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/Makefile b/tf_fuzz/Makefile
new file mode 100644
index 0000000..0e98dc6
--- /dev/null
+++ b/tf_fuzz/Makefile
@@ -0,0 +1,231 @@
+# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+.PHONY: default
+default: tfz;
+
+edit:
+	$(EDITOR) template/template_line.hpp \
+	template/sst_template_line.hpp template/crypto_template_line.hpp \
+	template/secure_template_line.hpp calls/psa_call.hpp calls/sst_call.hpp \
+	calls/crypto_call.hpp calls/security_call.hpp assets/psa_asset.hpp \
+	assets/sst_asset.hpp assets/crypto_asset.hpp utility/data_blocks.hpp \
+	utility/variables.hpp utility/gibberish.hpp utility/randomization.hpp \
+	utility/find_or_create_asset.hpp utility/string_ops.hpp \
+	utility/compute.hpp boilerplate/boilerplate.hpp \
+	utility/find_or_create_asset.hpp class_forwards.hpp tf_fuzz.hpp \
+	parser/tf_fuzz_grammar.l parser/tf_fuzz_grammar.y \
+	template/template_line.cpp \
+	template/sst_template_line.cpp template/crypto_template_line.cpp \
+	template/secure_template_line.cpp calls/psa_call.cpp calls/sst_call.cpp \
+	calls/crypto_call.cpp calls/security_call.cpp assets/psa_asset.cpp \
+	assets/sst_asset.cpp assets/crypto_asset.cpp utility/data_blocks.cpp \
+	utility/gibberish.cpp utility/randomization.cpp utility/string_ops.cpp \
+	utility/compute.cpp \
+	boilerplate/boilerplate.cpp tf_fuzz.cpp \
+	tests/example_template tests/sstSets tests/sstReads \
+	lib/tfm_boilerplate.txt boilerplate/boilerplate.hpp \
+	Makefile README assets/README \
+	boilerplate/README calls/README demo/README lib/README parser/README \
+	template/README tests/README regression/README utility/README \
+	visualStudio/README &
+
+edit3:
+	$(EDITOR) template/template_line.hpp \
+	template/sst_template_line.hpp template/crypto_template_line.hpp \
+	template/secure_template_line.hpp calls/psa_call.hpp calls/sst_call.hpp \
+	calls/crypto_call.hpp calls/security_call.hpp assets/psa_asset.hpp \
+	assets/sst_asset.hpp assets/crypto_asset.hpp  utility/data_blocks.hpp \
+	utility/variables.hpp utility/gibberish.hpp utility/randomization.hpp \
+	utility/find_or_create_asset.hpp utility/string_ops.hpp \
+	utility/compute.hpp boilerplate/boilerplate.hpp \
+	utility/find_or_create_asset.hpp class_forwards.hpp tf_fuzz.hpp &
+	$(EDITOR) parser/tf_fuzz_grammar.l parser/tf_fuzz_grammar.y \
+	template/template_line.cpp \
+	template/sst_template_line.cpp template/crypto_template_line.cpp \
+	template/secure_template_line.cpp calls/psa_call.cpp calls/sst_call.cpp \
+	calls/crypto_call.cpp calls/security_call.cpp assets/psa_asset.cpp \
+	assets/sst_asset.cpp assets/crypto_asset.cpp utility/data_blocks.cpp \
+	utility/variables.cpp utility/gibberish.cpp utility/randomization.cpp \
+	utility/string_ops.cpp utility/compute.cpp boilerplate/boilerplate.cpp \
+	tf_fuzz.cpp &
+	$(EDITOR) tests/example_template Makefile tests/sstSets tests/sstReads \
+	lib/tfm_boilerplate.txt boilerplate/boilerplate.hpp &
+
+includes = -I . -I ./parser -I ./template -I ./assets -I ./calls -I ./boilerplate -I ./utility
+
+parser/tf_fuzz_grammar.tab.hpp:  parser/tf_fuzz_grammar.y class_forwards.hpp \
+boilerplate/boilerplate.hpp utility/gibberish.hpp utility/string_ops.hpp \
+tf_fuzz.hpp utility/data_blocks.hpp utility/variables.hpp \
+utility/find_or_create_asset.hpp assets/psa_asset.hpp \
+assets/sst_asset.hpp assets/crypto_asset.hpp calls/psa_call.hpp \
+template/template_line.hpp Makefile
+	rm -f parser/tf_fuzz_grammar.tab.hpp parser/tf_fuzz_grammar.tab.cpp \
+	parser/tf_fuzz_grammar.tab.o
+	bison --verbose -d parser/tf_fuzz_grammar.y -o \
+	parser/tf_fuzz_grammar.tab.cpp
+
+parser/tf_fuzz_grammar.tab.cpp:  parser/tf_fuzz_grammar.y class_forwards.hpp \
+boilerplate/boilerplate.hpp utility/gibberish.hpp utility/string_ops.hpp \
+tf_fuzz.hpp utility/data_blocks.hpp utility/variables.hpp \
+utility/find_or_create_asset.hpp assets/psa_asset.hpp \
+assets/sst_asset.hpp assets/crypto_asset.hpp calls/psa_call.hpp \
+template/template_line.hpp Makefile
+	rm -f parser/tf_fuzz_grammar.tab.hpp parser/tf_fuzz_grammar.tab.cpp \
+	parser/tf_fuzz_grammar.tab.o
+	bison --verbose -d parser/tf_fuzz_grammar.y -o \
+	parser/tf_fuzz_grammar.tab.cpp
+
+parser/tf_fuzz_grammar.lex.c:  parser/tf_fuzz_grammar.l \
+parser/tf_fuzz_grammar.tab.hpp Makefile
+	lex --outfile=parser/tf_fuzz_grammar.lex.c parser/tf_fuzz_grammar.l
+parser/tf_fuzz_grammar.lex.o:  parser/tf_fuzz_grammar.lex.c Makefile
+	g++ -std=gnu++11 -O0 -g -c -I /usr/include $(includes) -o parser/tf_fuzz_grammar.lex.o \
+	parser/tf_fuzz_grammar.lex.c
+
+parser/tf_fuzz_grammar.tab.o:  parser/tf_fuzz_grammar.lex.o \
+parser/tf_fuzz_grammar.tab.cpp parser/tf_fuzz_grammar.tab.hpp Makefile
+	g++ -Wall -std=c++11 -O0 -g -c -I /usr/include $(includes) -o \
+	parser/tf_fuzz_grammar.tab.o parser/tf_fuzz_grammar.tab.cpp
+
+utility/data_blocks.o:  utility/data_blocks.hpp utility/data_blocks.cpp  Makefile
+	g++ -Wall -std=c++11 -O0 -g -c $(includes) -o utility/data_blocks.o \
+	utility/data_blocks.cpp
+
+utility/variables.o:  utility/find_or_create_asset.hpp \
+utility/variables.hpp utility/variables.cpp  Makefile
+	g++ -Wall -std=c++11 -O0 -g -c $(includes) -o utility/variables.o \
+	utility/variables.cpp
+
+template/template_line.o:  utility/randomization.hpp template/template_line.cpp \
+class_forwards.hpp boilerplate/boilerplate.hpp tf_fuzz.hpp calls/psa_call.hpp \
+assets/psa_asset.hpp utility/data_blocks.hpp template/template_line.hpp \
+assets/sst_asset.hpp assets/crypto_asset.hpp  Makefile
+	g++ -Wall -std=c++11 -O0 -g -c $(includes) -o template/template_line.o \
+	template/template_line.cpp
+
+template/sst_template_line.o:  template/sst_template_line.cpp class_forwards.hpp \
+boilerplate/boilerplate.hpp tf_fuzz.hpp calls/psa_call.hpp assets/psa_asset.hpp \
+utility/data_blocks.hpp template/template_line.hpp template/sst_template_line.hpp \
+assets/sst_asset.hpp assets/crypto_asset.hpp Makefile
+	g++ -Wall -std=c++11 -O0 -g -c $(includes) -o template/sst_template_line.o \
+	template/sst_template_line.cpp
+
+template/crypto_template_line.o:  template/crypto_template_line.cpp \
+class_forwards.hpp boilerplate/boilerplate.hpp tf_fuzz.hpp calls/psa_call.hpp \
+assets/psa_asset.hpp utility/data_blocks.hpp template/template_line.hpp \
+assets/sst_asset.hpp assets/crypto_asset.hpp template/crypto_template_line.hpp Makefile
+	g++ -Wall -std=c++11 -O0 -g -c $(includes) -o template/crypto_template_line.o \
+	template/crypto_template_line.cpp
+
+template/secure_template_line.o:  utility/randomization.hpp class_forwards.hpp \
+boilerplate/boilerplate.hpp tf_fuzz.hpp calls/psa_call.hpp \
+assets/psa_asset.hpp utility/data_blocks.hpp template/secure_template_line.hpp \
+assets/sst_asset.hpp assets/crypto_asset.hpp  Makefile
+	g++ -Wall -std=c++11 -O0 -g -c $(includes) -o template/secure_template_line.o \
+	template/secure_template_line.cpp
+
+assets/psa_asset.o:  assets/psa_asset.cpp class_forwards.hpp \
+boilerplate/boilerplate.hpp tf_fuzz.hpp utility/data_blocks.hpp calls/psa_call.hpp \
+assets/psa_asset.hpp template/template_line.hpp Makefile
+	g++ -Wall -std=c++11 -O0 -g -c $(includes) -o assets/psa_asset.o \
+	assets/psa_asset.cpp
+
+assets/sst_asset.o:  assets/sst_asset.cpp class_forwards.hpp \
+boilerplate/boilerplate.hpp utility/data_blocks.hpp tf_fuzz.hpp calls/psa_call.hpp \
+assets/psa_asset.hpp template/template_line.hpp assets/sst_asset.hpp  Makefile
+	g++ -Wall -std=c++11 -O0 -g -c $(includes) -o assets/sst_asset.o \
+	assets/sst_asset.cpp
+
+assets/crypto_asset.o:  utility/randomization.hpp assets/crypto_asset.cpp \
+class_forwards.hpp boilerplate/boilerplate.hpp tf_fuzz.hpp utility/data_blocks.hpp \
+calls/psa_call.hpp assets/psa_asset.hpp assets/crypto_asset.hpp Makefile
+	g++ -Wall -std=c++11 -O0 -g -c $(includes) -o assets/crypto_asset.o \
+	assets/crypto_asset.cpp
+
+calls/psa_call.o:  calls/psa_call.cpp class_forwards.hpp \
+boilerplate/boilerplate.hpp utility/data_blocks.hpp utility/variables.hpp tf_fuzz.hpp \
+calls/psa_call.hpp Makefile
+	g++ -Wall -std=c++11 -O0 -g -c $(includes) -o calls/psa_call.o calls/psa_call.cpp
+
+calls/sst_call.o:  calls/sst_call.cpp class_forwards.hpp \
+boilerplate/boilerplate.hpp tf_fuzz.hpp calls/psa_call.hpp assets/psa_asset.hpp \
+template/template_line.hpp utility/data_blocks.hpp utility/variables.hpp \
+calls/sst_call.hpp assets/sst_asset.hpp assets/crypto_asset.hpp utility/string_ops.hpp \
+Makefile
+	g++ -Wall -std=c++11 -O0 -g -c $(includes) -o calls/sst_call.o \
+	calls/sst_call.cpp
+
+calls/crypto_call.o:  utility/randomization.hpp calls/crypto_call.cpp \
+class_forwards.hpp boilerplate/boilerplate.hpp utility/string_ops.hpp \
+tf_fuzz.hpp calls/psa_call.hpp utility/data_blocks.hpp utility/variables.hpp \
+assets/psa_asset.hpp template/template_line.hpp \
+calls/crypto_call.hpp assets/sst_asset.hpp assets/crypto_asset.hpp Makefile
+	g++ -Wall -std=c++11 -O0 -g -c $(includes) -o calls/crypto_call.o \
+	calls/crypto_call.cpp
+
+calls/security_call.o:  utility/randomization.hpp calls/security_call.hpp \
+calls/security_call.cpp class_forwards.hpp boilerplate/boilerplate.hpp \
+utility/string_ops.hpp utility/data_blocks.hpp utility/variables.hpp tf_fuzz.hpp \
+calls/psa_call.hpp assets/psa_asset.hpp template/template_line.hpp \
+calls/security_call.hpp assets/sst_asset.hpp \
+Makefile
+	g++ -Wall -std=c++11 -O0 -g -c $(includes) -o calls/security_call.o \
+	calls/security_call.cpp
+
+boilerplate/boilerplate.o:  boilerplate/boilerplate.cpp class_forwards.hpp \
+boilerplate/boilerplate.hpp tf_fuzz.hpp calls/psa_call.hpp assets/psa_asset.hpp \
+template/template_line.hpp Makefile
+	g++ -Wall -std=c++11 -O0 -g -c $(includes) -o boilerplate/boilerplate.o \
+	boilerplate/boilerplate.cpp
+
+utility/gibberish.o:  utility/gibberish.cpp class_forwards.hpp \
+utility/gibberish.hpp Makefile
+	g++ -Wall -std=c++11 -O0 -g -c $(includes) -o utility/gibberish.o \
+	utility/gibberish.cpp
+
+utility/string_ops.o:  utility/string_ops.cpp utility/string_ops.hpp Makefile
+	g++ -Wall -std=c++11 -O0 -g -c $(includes) -o utility/string_ops.o \
+	utility/string_ops.cpp
+
+utility/randomization.o:  utility/randomization.cpp utility/randomization.hpp \
+Makefile
+	g++ -Wall -std=c++11 -O0 -g -c $(includes) -o utility/randomization.o \
+	utility/randomization.cpp
+
+utility/compute.o:  utility/compute.cpp utility/compute.hpp Makefile
+	g++ -Wall -std=c++11 -O0 -g -c $(includes) -o utility/compute.o \
+	utility/compute.cpp
+
+tf_fuzz.o:  tf_fuzz.cpp class_forwards.hpp boilerplate/boilerplate.hpp tf_fuzz.hpp \
+calls/psa_call.hpp assets/psa_asset.hpp utility/data_blocks.hpp utility/variables.hpp \
+template/template_line.hpp parser/tf_fuzz_grammar.tab.hpp Makefile
+	g++ -Wall -std=c++11 -O0 -g -c $(includes) -o tf_fuzz.o tf_fuzz.cpp
+
+tfz:  parser/tf_fuzz_grammar.lex.o parser/tf_fuzz_grammar.tab.o \
+template/secure_template_line.o template/template_line.o \
+template/sst_template_line.o template/crypto_template_line.o utility/data_blocks.o \
+utility/variables.o assets/psa_asset.o assets/sst_asset.o assets/crypto_asset.o \
+utility/gibberish.o utility/string_ops.o calls/psa_call.o calls/sst_call.o \
+calls/crypto_call.o utility/randomization.o utility/compute.o boilerplate/boilerplate.o \
+calls/security_call.o tf_fuzz.o \
+Makefile
+	g++ -Wall -std=c++11 -O0 -g -o tfz parser/tf_fuzz_grammar.lex.o \
+	parser/tf_fuzz_grammar.tab.o template/secure_template_line.o \
+	template/template_line.o template/sst_template_line.o utility/data_blocks.o \
+	utility/variables.o template/crypto_template_line.o assets/psa_asset.o \
+	assets/sst_asset.o assets/crypto_asset.o utility/gibberish.o \
+	utility/string_ops.o utility/randomization.o utility/compute.o \
+	calls/psa_call.o calls/sst_call.o calls/crypto_call.o calls/security_call.o \
+	boilerplate/boilerplate.o tf_fuzz.o
+
+clean:
+	rm -f ./*.o parser/*.o assets/*.o calls/*.o template/*.o utility/*.o \
+	boilerplate/*.o utility/gibberish.o tfz tfz.exe \
+	parser/tf_fuzz_grammar.lex.* parser/tf_fuzz_grammar.tab.* \
+	parser/tf_fuzz_grammar.output
+	rm -f `find regression -name "stdout_stderr"`
+	rm -f `find regression -name "test.c"`
+	rm -f demo/tossThis*
diff --git a/tf_fuzz/README b/tf_fuzz/README
new file mode 100644
index 0000000..32754c2
--- /dev/null
+++ b/tf_fuzz/README
@@ -0,0 +1,154 @@
+.../tf_fuzz directory contents:
+
+assets       calls               demo      parser    tests        regression
+backupStuff  class_forwards.hpp  lib       README    tf_fuzz.cpp  utility
+boilerplate  commands            Makefile  template  tf_fuzz.hpp  visualStudio
+
+TF-Fuzz root directory.
+
+--------------------------------------------------------------------------------
+
+TF-Fuzz is a TF-M fuzzing tool, at the PSA-call level.  At the time of writing
+this at least, presentations available at:
+    https://www.trustedfirmware.org/docs/TF-M_Fuzzing_Tool_TFOrg.pdf
+    https://zoom.us/rec/share/1dxZcZit111IadadyFqFU7IoP5X5aaa8gXUdr_UInxmMbyLzEqEmXQdx79-IWQ9p
+(These presentation materials may not be viewable by all parties.)
+
+--------------------------------------------------------------------------------
+
+To build TF-Fuzz, simply type "make" in this directory.  Executable, called
+"tfz," is placed in this directory.
+
+To run tfz, two environment variables must first be assigned.  In bash syntax:
+export TF_FUZZ_LIB_DIR=<path to this TF-M installation>/tools/tf_fuzz/lib
+export TF_FUZZ_BPLATE=tfm_boilerplate.txt
+
+Examples of usage can be found in the demo directory.
+
+--------------------------------------------------------------------------------
+
+To generate a testsuite for TF-M from a set of template files, use
+generate_test_suite.sh.
+
+.. code-block:: bash
+
+    Usage: generate_test_suite.sh <template_dir> <suites_dir>
+
+    Where:
+        template_dir: The directory containing template files for the
+                    fuzzing tool
+        suites_dir: The suites directory in the TF-M working copy.
+                    i.e.: $TF-M_ROOT/test/suites
+    Example:
+        cd tools/tf_fuzz
+        ./generate_test_suite.sh $TF-M_ROOT/tools/tf_fuzz/tests/  $TF-M_ROOT/../tf-m-tests/test/suites/
+
+
+After the test suite is generated, the new test suite needs to be added to the
+TF-M build by providing the following options to the CMake generate command
+(The path needs to be aligned with the test suite dir provided for the shell
+script above):
+
+.. code-block:: bash
+
+    -DTFM_FUZZER_TOOL_TESTS=1
+    -DTFM_FUZZER_TOOL_TESTS_CMAKE_INC_PATH=$TF-M_ROOT/test/suites/tf_fuzz
+
+--------------------------------------------------------------------------------
+
+To help understand the code, below is a C++-class hierarchy used in this code
+base.  They are explained further in the READMEs in their respective direc-
+tories, so the file names where the classes are defined is listed below (this,
+very roughly in order of functional interactions, of chronological usage during
+execution, and of most-to-least importance):
+
+    template_line                        ./template/template_line.hpp
+        sst_template_line                ./template/template_line.hpp
+            read_sst_template_line       ./template/sst_template_line.hpp
+            remove_sst_template_line     ./template/sst_template_line.hpp
+            set_sst_template_line        ./template/sst_template_line.hpp
+        policy_template_line             ./template/template_line.hpp
+            read_policy_template_line    ./template/crypto_template_line.hpp
+            set_policy_template_line     ./template/crypto_template_line.hpp
+        key_template_line                ./template/template_line.hpp
+            read_key_template_line       ./template/crypto_template_line.hpp
+            remove_key_template_line     ./template/crypto_template_line.hpp
+            set_key_template_line        ./template/crypto_template_line.hpp
+        security_template_line           ./template/template_line.hpp
+            security_hash_template_line  ./template/secure_template_line.hpp
+
+    psa_call                             ./calls/psa_call.hpp
+        crypto_call                      ./calls/psa_call.hpp
+            policy_call                  ./calls/crypto_call.hpp
+                policy_get_call          ./calls/crypto_call.hpp
+                policy_set_call          ./calls/crypto_call.hpp
+            key_call                     ./calls/crypto_call.hpp
+                get_key_info_call        ./calls/crypto_call.hpp
+                set_key_call             ./calls/crypto_call.hpp
+                destroy_key_call         ./calls/crypto_call.hpp
+        sst_call                         ./calls/psa_call.hpp
+            sst_remove_call              ./calls/sst_call.hpp
+            sst_get_call                 ./calls/sst_call.hpp
+            sst_set_call                 ./calls/sst_call.hpp
+        security_call                    ./calls/psa_call.hpp
+            hash_call                    ./calls/security_call.hpp
+
+    boilerplate                          ./boilerplate/boilerplate.hpp
+
+    psa_asset                            ./assets/psa_asset.hpp
+        crypto_asset                     ./assets/crypto_asset.hpp
+            policy_asset                 ./assets/crypto_asset.hpp
+            key_asset                    ./assets/crypto_asset.hpp
+        sst_asset                        ./assets/sst_asset.hpp
+
+    tf_fuzz_info                         ./tf_fuzz.hpp
+
+    crc32                                ./utility/compute.hpp
+
+    gibberish                            ./utility/gibberish.hpp
+
+    expect_info                          ./utility/data_blocks.hpp
+    set_data_info                        ./utility/data_blocks.hpp
+    asset_name_id_info                   ./utility/data_blocks.hpp
+
+--------------------------------------------------------------------------------
+
+There are currently two especially annoying warts on the design of TF-Fuzz:
+*   Need better management of variables in the generated code.  Currently,
+    for example, upon "read"ing a value from a PSA asset more than once, it
+    creates a same-named (i.e., duplicate) variable for each such time, which
+    is obviously not right.
+*   Upon adding the ability to do "do any N of these PSA calls at random,"
+    in hindsight, a fundamental flaw was uncovered in the top-level flow of
+    how TF-Fuzz generates the code.  High-level summary:
+  *   It should have completely distinct Parse, Simulate, then Code-generation
+      stages.
+  *   Currently, the Parse and Simulate stages aren't really completely
+      distinct, so there's a bunch of complicated Boolean flags traffic-
+      copping between what in hindsight should be completely-separate Parse
+      vs. Code-generation functionality.
+    The function, interpret_template_line(), currently in
+    .../tf_fuzz/parser/tf_fuzz_grammar.y (which may be moved to the its own file
+    with randomize_template_lines()), has the lion's share of such Booleans,
+    such as fill_in_template, create_call_bool, and create_asset_bool.
+    The way it *should* work is:
+  *   The parser in .../tf_fuzz_grammar.y should generate an STL vector (or
+      list) of psa_call-subclass "tracker" objects.  It should not generate
+      PSA-asset tracker objects (subclasses of psa_asset).
+  *   There should then be an organized Simulate stage, that sequences through
+      the psa_call-subclass list, creating and accumulating/maintaining current
+      state in psa_asset-subclass objects, using that current state to
+      determine expected results of each PSA call, which get annotated back
+      into the psa_call-tracker objects.
+  *   Finally, there already is, and should continue to be, a Code-generation
+      phase that writes out the code, based upon text substitutions of
+      "boilerplate" code snippets.
+  *   Currently, (hindsight obvious) the Parse and Simulate phases got somewhat
+      muddled together.  This shouldn't be super-hard to fix.
+    That final Code-generation phase, conceptually at least, could be replaced
+    instead with simply executing those commands directly, for targets that
+    sufficient space to run TF-Fuzz in real-time.
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/assets/README b/tf_fuzz/assets/README
new file mode 100644
index 0000000..870416e
--- /dev/null
+++ b/tf_fuzz/assets/README
@@ -0,0 +1,10 @@
+This directory contains C++ header and program files for classes of objects that
+track PSA assets, notably during the Simulate phase.
+
+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/asset_dir.html
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/assets/crypto_asset.cpp b/tf_fuzz/assets/crypto_asset.cpp
new file mode 100644
index 0000000..7918a79
--- /dev/null
+++ b/tf_fuzz/assets/crypto_asset.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "class_forwards.hpp"
+
+#include "boilerplate.hpp"
+#include "randomization.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"
+
+
+
+/**********************************************************************************
+   Methods of class crypto_asset follow:
+**********************************************************************************/
+
+crypto_asset::crypto_asset (void)  // (default constructor)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+
+crypto_asset::~crypto_asset (void)  // (destructor)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+/**********************************************************************************
+   End of methods of class crypto_asset.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class policy_asset follow:
+**********************************************************************************/
+
+policy_asset::policy_asset (void)  // (default constructor)
+{
+    // Randomize key-policy usage and algorithm:
+    policy_usage = rand_key_usage();
+    policy_algorithm = rand_key_algorithm();
+    // keys:  Should automatically come up as empby.
+}
+
+
+policy_asset::~policy_asset (void)  // (destructor)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+/**********************************************************************************
+   End of methods of class policy_asset.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class key_asset follow:
+**********************************************************************************/
+
+bool key_asset::set_key_id (int id_n)
+{
+    key_id = id_n;
+    return true;
+}
+
+
+key_asset::key_asset (void)
+{
+    // Note:  Similar random initialization for asset and template
+    // Randomize handle:
+    // TODO:  Key handles appear to be a lot more complex a question than the below
+    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;
+    // Randomize key type:
+    key_type = rand_key_type();
+    // Randomize lifetime:
+    lifetime_str = ((rand() % 2) == 1)?
+                       "PSA_KEY_LIFETIME_VOLATILE" : "PSA_KEY_LIFETIME_PERSISTENT";
+}
+
+
+key_asset::~key_asset (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+/**********************************************************************************
+   End of methods of class key_asset.
+**********************************************************************************/
diff --git a/tf_fuzz/assets/crypto_asset.hpp b/tf_fuzz/assets/crypto_asset.hpp
new file mode 100644
index 0000000..bcee450
--- /dev/null
+++ b/tf_fuzz/assets/crypto_asset.hpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef CRYPTO_ASSET_HPP
+#define CRYPTO_ASSET_HPP
+
+#include <string>
+#include <vector>
+#include <cstddef>
+#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"
+*/
+
+
+using namespace std;
+
+class crypto_asset : public psa_asset
+{
+public:
+    // Data members:
+        key_policy_info policy;
+    // Methods:
+        crypto_asset (void);  // (constructor)
+        ~crypto_asset (void);
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+class policy_asset : public crypto_asset
+{
+public:
+    // Data members:
+        string policy_usage;  // for now just strings;  maybe future tap TF-M(?) value list
+        string key_type;  // DES, AES, RAW, vendor, none, etc.
+        string policy_algorithm;
+        vector<key_asset*> keys;  // keys that use this policy
+    // Methods:
+        policy_asset (void);  // (constructor)
+        ~policy_asset (void);
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+class key_asset : public crypto_asset
+{
+public:
+    // Data members:
+        vector<policy_asset*>::iterator the_policy_asset;
+            /* The policy for this key.  Note that psa_make_key() lets us create
+             a key without associating a policy with it.  In that case, this will
+             be null, and the attributes below apply.  Later, psa_set_key_policy
+             lets us associate a policy with a key, at which point this becomes
+             non-null and the following attributes no longer apply. */
+        string key_type;  // DES, AES, RAW, vendor, none, etc.
+        string usage;  // for now just strings;  maybe future tap TF-M(?) value list
+        string alg;  // these only apply if the string was created without a policy
+        string lifetime_str;  // similarly, the text representation of the key's lifetime
+    // Methods:
+        bool set_key_id (int id_n);  // checks key-ID value, returns true==success
+        key_asset (void);  // (constructor)
+        ~key_asset (void);
+
+protected:
+    // Data members:
+        uint64_t key_id;
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+#endif  // CRYPTO_ASSET_HPP
diff --git a/tf_fuzz/assets/crypto_asset.o b/tf_fuzz/assets/crypto_asset.o
new file mode 100644
index 0000000..accb11f
--- /dev/null
+++ b/tf_fuzz/assets/crypto_asset.o
Binary files differ
diff --git a/tf_fuzz/assets/psa_asset.cpp b/tf_fuzz/assets/psa_asset.cpp
new file mode 100644
index 0000000..2c230e7
--- /dev/null
+++ b/tf_fuzz/assets/psa_asset.cpp
@@ -0,0 +1,55 @@
+/*
+ * 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"
+
+
+/**********************************************************************************
+   Methods of class psa_asset follow:
+**********************************************************************************/
+
+void psa_asset::set_name (string set_val)
+{
+    asset_info.name_specified = true;
+    asset_name.assign (set_val);
+}
+
+string psa_asset::get_name (void)
+{
+    return asset_name;
+}
+
+bool psa_asset::simulate (void) {
+    return false;
+        // by default, assume that nothing changed; derived classes may override.
+}
+
+psa_asset::psa_asset (void)  // (default constructor)
+{
+    asset_info.asset_ser_no = unique_id_counter++;
+}
+
+
+psa_asset::~psa_asset (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+/**********************************************************************************
+   End of methods of class psa_asset.
+**********************************************************************************/
diff --git a/tf_fuzz/assets/psa_asset.hpp b/tf_fuzz/assets/psa_asset.hpp
new file mode 100644
index 0000000..9eb4d3f
--- /dev/null
+++ b/tf_fuzz/assets/psa_asset.hpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PSA_ASSET_HPP
+#define PSA_ASSET_HPP
+
+#include <string>
+#include <vector>
+#include <cstdint>
+
+/* This project's header files #including other project headers quickly becomes
+   unrealistically complicated.  The only solution is for each .cpp to include
+   the headers it needs. */
+
+using namespace std;
+
+class psa_asset
+{
+public:
+    /* Data members -- not all PSA assets have all of these, but they need to be
+       accessible polymorphically via a psa_asset iterator: */
+        set_data_info set_data;
+            /* For a PSA-asset tracker, this is really more about an asset's
+               on-going, real-time asset data value than about *setting* its data
+               value.  On a template_line or a psa_call, it's about setting its
+               value at one particular time. */
+        expect_info exp_data;
+            /* For now at least, this is here only for its n_exp_vars member, to
+               keep track of how many expected-data variables in the test. */
+        asset_name_id_info asset_info;  // everything about the asset(s) for this line
+        key_policy_info policy;  // (specific to crypto, but have to put this here)
+        vector<int> template_ref;
+            // list of template line #s that reference this asset
+        vector<psa_call> call_ref;  // list of PSA calls that reference this asset
+        string handle_str;  // the text name of the key's "handle"
+        bool asset_name_specified;
+            /* true if the template specified the asset_name, as opposed to us
+               having inferred it. */
+    // Methods:
+        void set_name (string set_val);
+        string get_name (void);
+        virtual bool simulate (void);
+            /* simulate() tells this asset to react to its current state information.
+               Initially, this won't really do much, but will allow assets to react
+               to each other, if that is relevant.  It returns true if anything
+               in the state of the asset changed, in which case all assets' simulate()
+               methods will be invoked again to react again.  That will repeat until
+               all assets read a quiescent state. */
+        psa_asset();  // (constructor)
+        ~psa_asset();
+
+protected:
+    // Data members:
+        // These are initially copied over from the call (or possibly template line):
+        string data;  // String describing current data value.
+        string asset_name;  // human-meaningful name
+        static long unique_id_counter;  // counts off unique IDs for assets
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+#endif  // PSA_ASSET_HPP
diff --git a/tf_fuzz/assets/psa_asset.o b/tf_fuzz/assets/psa_asset.o
new file mode 100644
index 0000000..994bdd7
--- /dev/null
+++ b/tf_fuzz/assets/psa_asset.o
Binary files differ
diff --git a/tf_fuzz/assets/sst_asset.cpp b/tf_fuzz/assets/sst_asset.cpp
new file mode 100644
index 0000000..ac4de6f
--- /dev/null
+++ b/tf_fuzz/assets/sst_asset.cpp
@@ -0,0 +1,50 @@
+/*
+ * 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_asset.hpp"
+
+
+
+/**********************************************************************************
+   Methods of class sst_asset follow:
+**********************************************************************************/
+
+bool sst_asset::set_uid (uint64_t uid)
+{
+    /* TODO:  What are the limits upon UIDs?  I don't necessarily not want to be
+              able to set an illegal value, but if it is illegal, I might want to
+              set some flag appropriately to generate expected results. */
+    asset_info.set_id_n (uid);
+    return true;
+}
+
+sst_asset::sst_asset (void)  // (default constructor)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+
+sst_asset::~sst_asset (void)  // (destructor)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+/**********************************************************************************
+   End of methods of class sst_asset.
+**********************************************************************************/
diff --git a/tf_fuzz/assets/sst_asset.hpp b/tf_fuzz/assets/sst_asset.hpp
new file mode 100644
index 0000000..0fbd5b8
--- /dev/null
+++ b/tf_fuzz/assets/sst_asset.hpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef SST_ASSET_HPP
+#define SST_ASSET_HPP
+
+#include <string>
+
+/* This project's header files #including other project headers quickly becomes
+   unrealistically complicated.  The only solution is for each .cpp to include
+   the headers it needs.
+#include "psa_asset.hpp"
+*/
+
+
+using namespace std;
+
+class sst_asset : public psa_asset
+{
+public:  // (low value in hiding these behind setters and getters)
+    // Data members:
+    // Methods:
+        bool set_uid (uint64_t uid);  // checks input UID value, returns true==success
+        void set_literal_data (string literal_data);
+           // if literal data, this sets both "data" string and "data_length"
+        sst_asset (void);  // (constructor)
+        ~sst_asset (void);
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+#endif  // SST_ASSET_HPP
diff --git a/tf_fuzz/assets/sst_asset.o b/tf_fuzz/assets/sst_asset.o
new file mode 100644
index 0000000..2e5a2ef
--- /dev/null
+++ b/tf_fuzz/assets/sst_asset.o
Binary files differ
diff --git a/tf_fuzz/boilerplate/README b/tf_fuzz/boilerplate/README
new file mode 100644
index 0000000..60c78fa
--- /dev/null
+++ b/tf_fuzz/boilerplate/README
@@ -0,0 +1,10 @@
+These are the C++ code to work with the customizable, "boilerplate" code
+snippets in the .../lib directory.  
+
+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/boilerplate_dir.html
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/boilerplate/boilerplate.cpp b/tf_fuzz/boilerplate/boilerplate.cpp
new file mode 100644
index 0000000..60deab7
--- /dev/null
+++ b/tf_fuzz/boilerplate/boilerplate.cpp
@@ -0,0 +1,101 @@
+/*
+ * 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"
+
+/**********************************************************************************
+   Methods of class boilerplate follow:
+**********************************************************************************/
+
+void env_var_usage (void)
+{
+    cerr << "Example, for typical TF-M usage, using bash syntax:" << endl
+         << "   export TF_FUZZ_LIB_DIR=<path to TF-M installation>/tools/tf_fuzz/lib"
+         << endl
+         << "   export TF_FUZZ_BPLATE=tfm_boilerplate.txt" << endl;
+}
+
+void boilerplate::stuff_boilerplate_strings (void)
+{
+    ifstream boilerplate_lib;
+    string file_name;  // boilerplate file name
+    string holder;
+        // temp string, e.g., holder for strings read from the boilerplate file
+
+    /* User must point the environment variable $TF_FUZZ_BPLATE to the boilerplate
+       file s/he wants to use, within a directory named by $TF_FUZZ_LIB_DIR. */
+    string bpStringL, bpStringF;
+    char *bpLibDir = getenv ("TF_FUZZ_LIB_DIR");
+    if (bpLibDir == NULL) {
+        cerr << "Error:  Please point environment variable $TF_FUZZ_LIB_DIR to "
+             << "TF-Fuzz's library directory." << endl;
+        env_var_usage();
+        exit (701);
+    }
+    bpStringL = bpLibDir;
+    char *bpFName = getenv ("TF_FUZZ_BPLATE");
+    if (bpFName == NULL) {
+        cerr << "Error:  Please set environment variable $TF_FUZZ_BPLATE to name the "
+             << "\"boilerplate\" text-library file." << endl;
+        env_var_usage();
+        exit (702);
+    }
+    bpStringF = bpFName;
+    file_name.assign (bpStringL + "/" + bpStringF);
+    boilerplate_lib.open (file_name);
+    if (!boilerplate_lib.is_open()) {
+        cerr << "\nError:  Unable to open boilerplate text-library file, at path "
+             << file_name << "." << endl;
+        env_var_usage();
+        exit(200);
+    }
+
+    // Read the strings into the boilerplate vector:
+    getline (boilerplate_lib, holder, '`');
+        /* This first one is "not real."  It's a README, in essence, explaining the
+           library-text file, so skip past it. */
+    for (int i = preamble_A;  i < n_boilerplate_texts;  i++) {
+        if (!getline (boilerplate_lib, holder, '`')) {
+            cerr << "\nError:  Unable to read from boilerplate text-library file, at path "
+                 << file_name << "." << endl;
+            cerr << "        Please make sure the file is not empty." << endl;
+            env_var_usage();
+            exit(851);
+        }
+        if (holder.length() < 5) {
+            cerr << "\nError:  Read from boilerplate text-library file, at path "
+                 << file_name << ", was too short." << endl;
+            cerr << "        Please make sure the file has not been damaged "
+                 << "from the TF-Fuzz distribution." << endl;
+            env_var_usage();
+            exit(852);
+        }
+        // Shave off the three-character tag + \n from the front of the string:
+        holder.erase(0, 4);
+        bplate_string.push_back(holder);
+    }
+    boilerplate_lib.close();
+}
+
+boilerplate::boilerplate (void) {
+    stuff_boilerplate_strings();
+}
+
+/**********************************************************************************
+   End of methods of class boilerplate.
+**********************************************************************************/
diff --git a/tf_fuzz/boilerplate/boilerplate.hpp b/tf_fuzz/boilerplate/boilerplate.hpp
new file mode 100644
index 0000000..4bbf651
--- /dev/null
+++ b/tf_fuzz/boilerplate/boilerplate.hpp
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/* boilerplate.*pp contains class(es) to read and store customizable code
+   fragments used in realizing the pieces of a test.  It's critical that
+   these be customizable in external library files, so that TF-Fuzz can
+   exercise TF-A as well as TF-M.  Each TF-x has its own library of text
+   pieces, which are read into these data structures upon program initial-
+   ization. */
+
+#ifndef BOILERPLATE_HPP
+#define BOILERPLATE_HPP
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+
+
+using namespace std;
+
+// Constant mnemonics for entries in array of boilerplate texts:
+const int
+    // Stuff around the test itself:
+        preamble_A = 0,  // setup stuff before PSA calls begin
+            /* Strings to be substituted from template:
+            $purpose:  The purpose of the test */
+        hashing_code = 1,  // code to perform a simple hash of asset data
+            /* Strings to be substituted from template:  (none) */
+        preamble_B = 2,  // setup stuff before PSA calls begin
+            /* Strings to be substituted from template:
+            $purpose:  The purpose of the test */
+        preamble_C = 3,  // setup stuff before PSA calls begin
+            /* Strings to be substituted from template:
+            $purpose:  The purpose of the test */
+        declare_int = 4,  // declaration for an int
+            /* Strings to be substituted from template:
+            $var:  The integer thing to declare
+            $init:  Its initialization */
+        declare_string = 5,  // declaration for a string
+            /* Strings to be substituted from template:
+            $var:  The string variable to declare
+            $init:  Its initialization */
+        declare_big_string = 6,  // declaration for a string, sized large
+            /* Strings to be substituted from template:
+            $var:  The string variable to declare
+            $init:  Its initialization */
+        declare_size_t = 7,  // declaration for a size_t
+            /* Strings to be substituted from template:
+            $var:  The integer thing to declare
+            $init:  Its initialization */
+        declare_policy = 8,  // declaration for a policy (key attributes)
+            /* Strings to be substituted from template:
+            $var:  The variable to declare */
+        declare_policy_algorithm = 9,  // declaration for a
+            /* Strings to be substituted from template:
+            $var:  The variable to declare */
+        declare_policy_lifetime = 10,  // declaration for a
+            /* Strings to be substituted from template:
+            $var:  The variable to declare */
+        declare_policy_type = 11,  // declaration for a
+            /* Strings to be substituted from template:
+            $var:  The variable to declare */
+        declare_policy_usage = 12,  // declaration for a
+            /* Strings to be substituted from template:
+            $var:  The variable to declare */
+        declare_key = 13,  // declaration for a
+            /* Strings to be substituted from template:
+            $var:  The variable to declare */
+        declare_generic = 14,  // declaration for a some other type
+            /* Strings to be substituted from template:
+            $type:  The type to declare the variable to
+            $var:  The string variable to declare
+            $init:  Its initialization */
+        test_log = 15,  // print a message to the test log
+            /* Strings to be substituted from template:
+            $message:  What to print. */
+        teardown_sst = 16,  // call to delete SST resources after test completes
+            /* Strings to be substituted from template:
+              $uid:  (Exactly that) */
+        teardown_sst_check = 17,  // boilerplate code to check success of previous;
+            /* No strings to be substituted from template */
+        teardown_key = 18,  // call to delete crypto keys after test completes
+            /* Strings to be substituted from template:
+              $handle:  The handle to the key */
+        teardown_key_check = 19,  // boilerplate code to check success of previous;
+            /* No strings to be substituted from template */
+        closeout = 20,  // final code to close out the test.
+            // No strings to substitute.
+        sst_pass_string = 21,  // passing SST expected result
+        sst_fail_removed = 22,  // SST expected result from having deleted the asset
+    // SST calls:
+        set_sst_call = 23,  // boilerplate for setting up an SST asset;
+            /* Strings to be substituted from template:
+              $op:  (for comment) either "Creating" or "Resetting"
+              $description:  its "human name" if given, or "UID=..." if not
+              $data_source:  either first ~10 chars of data or file path
+              $uid:  (Exactly that)
+              $length:  Data length
+              $data:  Pointer to data (C string)
+              $flags:  SST-asset creation flags */
+        set_sst_check = 24,  // boilerplate code to check success of previous;
+            /* Strings to be substituted from template:
+              $expect:  Expected return status string */
+        get_sst_call = 25,  // boilerplate for retrieving data from an SST asset;
+            /* Strings to be substituted from template:
+              $uid:  (Exactly that)
+              $offset:  Start positon in the "file"  TO DO:  ADD OFFSET
+              $length:  Data length
+              $act_data:  Pointer to actual data (C string) */
+        get_sst_check = 26,  // boilerplate code to check call result only;
+            /* Strings to be substituted from template:
+              $expect:  Expected return status string */
+        get_sst_check_all = 27,  // boilerplate code to check call result and data;
+            /* Strings to be substituted from template:
+              $expect:  Expected return status
+              $exp_data:  Expected read data
+              $act_data:  Actual read data
+              $length:  Data length */
+        get_sst_hash = 28,  // boilerplate code to invoke hasher;
+            /* Strings to be substituted from template:
+              $act_data_var:  Actual read data, to be hashed
+              $hash_var:  Hash-result variable */
+        remove_sst = 29,  // boilerplate for removing an SST asset;
+            /* Strings to be substituted from template:
+              $uid:  (Exactly that) */
+        remove_sst_check = 30,  // boilerplate code to check success of previous;
+            /* Strings to be substituted from template:
+              $expect:  Expected return status */
+    // Crypto-key-policy calls:
+        init_policy = 31,  // initialize a policy (key attributes);
+            /* Strings to be substituted from template:
+              $policy:  The name of the policy */
+        reset_policy = 32,  // reset a policy (key attributes);
+            /* Strings to be substituted from template:
+              $policy:  The name of the policy */
+        add_policy_usage = 33,  // add a usage flag to a policy;
+            /* Strings to be substituted from template:
+              $policy:  The name of the policy
+              $flag:  usage-flag name */
+        set_policy_lifetime = 34,
+            /* Strings to be substituted from template:
+              $policy:  The name of the policy
+              $life:  Lifetime -- volatile or persistent */
+        set_policy_size = 35,
+            /* Strings to be substituted from template:
+              $policy:  The name of the policy
+              $size:  The key size, in bits */
+        set_policy_type = 36,
+            /* Strings to be substituted from template:
+              $policy:  The name of the policy
+              $type:  The key type -- RSA pair, AES, etc. */
+        set_policy_algorithm = 37,
+            /* Strings to be substituted from template:
+              $policy:  The name of the policy
+              $algorithm:  The algorithm -- AEAD, sign, hash mask, etc. */
+        set_policy_usage = 38,
+            /* Strings to be substituted from template:
+              $policy:  The name of the policy
+              $usage:  The usage -- encrypt, decrypt, export, copy, etc. */
+        get_policy_lifetime = 39,
+            /* Strings to be substituted from template:
+              $policy:  The name of the policy
+              $life:  Lifetime -- volatile or persistent */
+        get_policy_lifetime_print = 40,
+            /* Strings to be substituted from template:
+              $policy:  The name of the policy
+              $life:  Lifetime -- volatile or persistent */
+        get_policy_size = 41,
+            /* Strings to be substituted from template:
+              $policy:  The name of the policy
+              $size:  The key size, in bits */
+        get_policy_type = 42,
+            /* Strings to be substituted from template:
+              $policy:  The name of the policy
+              $type:  The key type -- RSA pair, AES, etc. */
+        get_policy_type_print = 43,
+            /* Strings to be substituted from template:
+              $policy:  The name of the policy
+              $type:  The key type -- RSA pair, AES, etc. */
+        get_policy_algorithm = 44,
+            /* Strings to be substituted from template:
+              $policy:  The name of the policy
+              $algorithm:  The algorithm -- AEAD, sign, hash mask, etc. */
+        get_policy_algorithm_print = 45,
+            /* Strings to be substituted from template:
+              $policy:  The name of the policy
+              $algorithm:  The algorithm -- AEAD, sign, hash mask, etc. */
+        get_policy_usage = 46,
+            /* Strings to be substituted from template:
+              $policy:  The name of the policy
+              $usage:  The usage -- encrypt, decrypt, export, copy, etc. */
+        print_policy_usage = 47,
+            /* Strings to be substituted from template:
+              $policy:  The name of the policy
+              $usage:  The usage -- encrypt, decrypt, export, copy, etc. */
+        get_policy = 48,  // read the policy from a key;
+            /* Strings to be substituted from template:
+              $key:  The key whose policy we want to read
+              $policy:  The policy variable to read into */
+        get_policy_check = 49,  // success check fpr previous;
+            /* Strings to be substituted from template:
+              $expect:  Expected return status */
+    // Crypto-key-related calls:
+        generate_key = 50,  // generate key from scratch;
+            /* Strings to be substituted from template:
+              $key:  The key to generate
+              $policy:  The name of the policy */
+        generate_key_check = 51,  // success check for previous;
+            /* Strings to be substituted from template:
+              $expect:  Expected return status */
+        create_key = 52,  // Create key from policy and key data;
+            /* Strings to be substituted from template:
+              $policy:  The name of the policy
+              $data:  The key data
+              $length:  The key-data length -- sizeof() */
+        create_key_check = 53,  // success check for previous;
+            /* Strings to be substituted from template:
+              $expect:  Expected return status */
+        copy_key = 54,  // Copy key data from one key to another; different policy;
+            /* Strings to be substituted from template:
+              $master:  The source key-handle variable
+              $policy:  The name of the policy
+              $copy:  The copy key-handle variable */
+        copy_key_check = 55,  // success check for previous;
+            /* Strings to be substituted from template:
+              $expect:  Expected return status */
+        compare_data = 56,  // compare data blocks, such as key data
+            /* Strings to be substituted from template:
+              $exp_data:  Expected read data
+              $act_data:  Actual read data
+              $length:  Data length */
+        read_key_data = 57,  // read key data;
+            /* Strings to be substituted from template:
+              $key:  The key to read
+              $data:  Where to put the data
+              $length:  Length of the data buffer
+              $act_size:  The actual size of the key data retrieved */
+        read_key_data_check = 58,  // success check for previous;
+            /* Strings to be substituted from template:
+              $expect:  Expected return status */
+        remove_key = 59,  // boilerplate for creating a key;
+            /* Strings to be substituted from template:
+              $handle:  The handle to the key */
+        remove_key_check = 60,  // boilerplate code to check success of previous;
+            /* Strings to be substituted from template:
+              $expect:  Expected return status */
+    // Just an anchor at the end, for sizing the string array (if needed):
+        n_boilerplate_texts = 61;
+
+
+class boilerplate
+{
+public:  // (More pain than it's worth to create getters and setters)
+    // Data members:
+    vector<string> bplate_string;
+    string cpp_string;  // used to stuff bplate_string
+    // Methods:
+    void stuff_boilerplate_strings (void);
+    boilerplate (void);
+};
+
+
+#endif  // #ifndef BOILERPLATE_HPP
diff --git a/tf_fuzz/boilerplate/boilerplate.o b/tf_fuzz/boilerplate/boilerplate.o
new file mode 100644
index 0000000..7de9b1b
--- /dev/null
+++ b/tf_fuzz/boilerplate/boilerplate.o
Binary files differ
diff --git a/tf_fuzz/calls/README b/tf_fuzz/calls/README
new file mode 100644
index 0000000..c57499e
--- /dev/null
+++ b/tf_fuzz/calls/README
@@ -0,0 +1,10 @@
+These classes define objects that describe everything needed to generate a PSA
+call.
+
+For more information, please browse to:
+
+    https://ci.trustedfirmware.org/job/tf-m-build-test-nightly/lastSuccessfulBuild/artifact/build-docs/tf-m_documents/install/doc/user_guide/html/docs/user_guides/tf_fuzz/calls_dir.html
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/calls/crypto_call.cpp b/tf_fuzz/calls/crypto_call.cpp
new file mode 100644
index 0000000..85d7ac0
--- /dev/null
+++ b/tf_fuzz/calls/crypto_call.cpp
@@ -0,0 +1,1385 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <cstdlib>
+
+#include "class_forwards.hpp"
+
+#include "boilerplate.hpp"
+#include "variables.hpp"
+#include "gibberish.hpp"
+#include "compute.hpp"
+#include "randomization.hpp"
+#include "string_ops.hpp"
+#include "data_blocks.hpp"
+#include "psa_asset.hpp"
+#include "find_or_create_asset.hpp"
+#include "template_line.hpp"
+#include "tf_fuzz.hpp"
+#include "crypto_asset.hpp"
+#include "psa_call.hpp"
+#include "crypto_call.hpp"
+#include "sst_asset.hpp"
+
+
+/**********************************************************************************
+   Methods of class policy_call follow:
+**********************************************************************************/
+
+/* Most of the policy classes, in their fill_in_prep_code() method, need to ensure
+   that, at a minimum, the policy variable (psa_key_attributes_t) exists, so, just
+   to cut down code duplication: */
+void policy_call::policy_fill_in_prep_code (void)
+{
+    vector<variable_info>::iterator policy_variable;
+
+    policy_variable = test_state->find_var (asset_info.get_name());
+    if (policy_variable == test_state->variable.end()) {
+        // No such variable exists, so:
+        test_state->make_var (asset_info.get_name());
+        policy_variable = test_state->find_var (asset_info.get_name());
+        prep_code.assign (test_state->bplate->bplate_string[declare_policy]);
+        find_replace_1st ("$var", asset_info.get_name(), prep_code);
+    }
+}
+
+
+policy_call::policy_call (tf_fuzz_info *test_state,    // (constructor)
+                          long &call_ser_no,
+                          asset_search how_asset_found)
+                             : crypto_call(test_state, call_ser_no, how_asset_found)
+{
+    // Note:  Key attributes are set in the key_policy_info constructor.
+}
+policy_call::~policy_call (void)
+{
+    // Nothing further to delete.
+    return;  // just to have something to pin a breakpoint onto
+}
+
+vector<psa_asset*>::iterator policy_call::resolve_asset (bool create_asset_bool,
+                                                         psa_asset_usage where) {
+    vector<psa_asset*>::iterator found_asset;
+    vector<psa_asset*> *asset_vector;
+    int asset_pick;
+
+    if (random_asset != psa_asset_usage::all) {
+        // != psa_asset_usage::all means to choose some known asset at random:
+        if (random_asset == psa_asset_usage::active) {
+            asset_vector = &(test_state->active_policy_asset);
+            asset_info.how_asset_found = asset_search::found_active;
+        } else if (random_asset == psa_asset_usage::deleted) {
+            asset_vector = &(test_state->deleted_policy_asset);
+            asset_info.how_asset_found = asset_search::found_deleted;
+        } else {
+            // "invalid" assets are not currently used.
+            cerr << "\nError:  Tool-internal:  Please report error 1102 to " << endl
+                 << "TF-Fuzz developers."
+                 << endl;
+            exit(1102);
+        }
+        if (asset_vector->size() > 0) {
+            /* Pick an active or deleted asset at random: */
+            asset_pick = rand() % asset_vector->size();
+            found_asset = asset_vector->begin() + asset_pick;
+            /* Copy asset information into template tracker: */
+            asset_info.id_n = (*found_asset)->asset_info.id_n;
+            asset_info.asset_ser_no
+                    = (*found_asset)->asset_info.asset_ser_no;
+        } else {
+            if (random_asset == psa_asset_usage::active) {
+                cerr << "\nError:  A policy call asks for a "
+                     << "randomly chosen active asset, when none " << endl
+                     << "is currently defined." << endl;
+                exit(1010);
+            } else if (random_asset == psa_asset_usage::deleted) {
+                cerr << "\nError:  A policy call asks for a "
+                     << "randomly chosen deleted asset, when none " << endl
+                     << "is currently defined." << endl;
+                exit(1011);
+            }  // "invalid" assets are not currently used.
+        }
+    } else {
+        // Find the asset by name:
+        asset_info.how_asset_found = test_state->find_or_create_policy_asset (
+                            psa_asset_search::name, where,
+                            asset_info.get_name(), 0, asset_info.asset_ser_no,
+                            create_asset_bool, found_asset );
+        if (   asset_info.how_asset_found == asset_search::unsuccessful
+            || asset_info.how_asset_found == asset_search::something_wrong ) {
+            cerr << "\nError:  Tool-internal:  Please report error 108 to " << endl
+                 << "TF-Fuzz developers."
+                 << endl;
+            exit(108);
+        }
+    }
+    return found_asset;
+}
+
+/**********************************************************************************
+   End of methods of class policy_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class key_call follow:
+**********************************************************************************/
+
+key_call::key_call (tf_fuzz_info *test_state,    // (constructor)
+                          long &call_ser_no,
+                          asset_search how_asset_found)
+                             : crypto_call(test_state, call_ser_no, how_asset_found)
+{
+    asset_info.the_asset = nullptr;
+}
+key_call::~key_call (void)
+{
+    // Nothing further to delete.
+    return;  // just to have something to pin a breakpoint onto
+}
+
+vector<psa_asset*>::iterator key_call::resolve_asset (bool create_asset_bool,
+                                                      psa_asset_usage where) {
+    vector<psa_asset*>::iterator found_asset;
+    vector<psa_asset*> *asset_vector;
+    int asset_pick;
+
+    if (random_asset != psa_asset_usage::all) {
+        // != psa_asset_usage::all means to choose some known asset at random:
+        if (random_asset == psa_asset_usage::active) {
+            asset_vector = &(test_state->active_key_asset);
+            asset_info.how_asset_found = asset_search::found_active;
+        } else if (random_asset == psa_asset_usage::deleted) {
+            asset_vector = &(test_state->deleted_key_asset);
+            asset_info.how_asset_found = asset_search::found_deleted;
+        } else {
+            // "invalid" assets are not currently used.
+            cerr << "\nError:  Tool-internal:  Please report error 1103 to " << endl
+                 << "TF-Fuzz developers."
+                 << endl;
+            exit(1103);
+        }
+        if (asset_vector->size() > 0) {
+            /* Pick an active or deleted asset at random: */
+            asset_pick = rand() % asset_vector->size();
+            found_asset = asset_vector->begin() + asset_pick;
+            /* Copy asset information into template tracker: */
+            asset_info.id_n = (*found_asset)->asset_info.id_n;
+            asset_info.asset_ser_no
+                    = (*found_asset)->asset_info.asset_ser_no;
+        } else {
+            if (random_asset == psa_asset_usage::active) {
+                cerr << "\nError:  A key call asks for a "
+                     << "randomly chosen active asset, when none " << endl
+                     << "is currently defined." << endl;
+                exit(1012);
+            } else if (random_asset == psa_asset_usage::deleted) {
+                cerr << "\nError:  A key call asks for a "
+                     << "randomly chosen deleted asset, when none " << endl
+                     << "is currently defined." << endl;
+                exit(1013);
+            }  // "invalid" assets are not currently used.
+        }
+    } else {
+        // Find the asset by name:
+        asset_info.how_asset_found = test_state->find_or_create_key_asset (
+                            psa_asset_search::name, where,
+                            asset_info.get_name(), 0, asset_info.asset_ser_no,
+                            create_asset_bool, found_asset );
+        if (   asset_info.how_asset_found == asset_search::unsuccessful
+            || asset_info.how_asset_found == asset_search::something_wrong ) {
+            cerr << "\nError:  Tool-internal:  Please report error 108 to " << endl
+                 << "TF-Fuzz developers."
+                 << endl;
+            exit(108);
+        }
+    }
+    return found_asset;
+}
+
+/**********************************************************************************
+   End of methods of class key_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class init_policy_call follow:
+**********************************************************************************/
+
+init_policy_call::init_policy_call (tf_fuzz_info *test_state,    // (constructor)
+                                    long &call_ser_no,
+                                    asset_search how_asset_found)
+                                        : policy_call(test_state, call_ser_no,
+                                                   how_asset_found)
+{
+    // Copy the boilerplate text into local buffers:
+    prep_code.assign ("");
+    call_code.assign (test_state->bplate->bplate_string[init_policy]);
+    call_description = "initialize-policy call";
+}
+init_policy_call::~init_policy_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool init_policy_call::copy_call_to_asset (void)
+{
+    return copy_call_to_asset_t<policy_asset*> (this, yes_create_asset);
+}
+
+void init_policy_call::fill_in_prep_code (void)
+{
+    policy_fill_in_prep_code();
+}
+
+void init_policy_call::fill_in_command (void)
+{
+    // (call_code already loaded by constructor)
+    find_replace_all ("$policy", asset_info.get_name(), call_code);
+    // Calculate the expected results:
+    calc_result_code();
+}
+
+/**********************************************************************************
+   End of methods of class init_policy_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class reset_policy_call follow:
+**********************************************************************************/
+
+reset_policy_call::reset_policy_call (tf_fuzz_info *test_state,    // (constructor)
+                                    long &call_ser_no,
+                                    asset_search how_asset_found)
+                                        : policy_call(test_state, call_ser_no,
+                                                   how_asset_found)
+{
+    // Copy the boilerplate text into local buffers:
+    prep_code.assign ("");
+    call_code.assign (test_state->bplate->bplate_string[reset_policy]);
+    call_description = "policy reset call";
+}
+reset_policy_call::~reset_policy_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool reset_policy_call::copy_call_to_asset (void)
+{
+    return copy_call_to_asset_t<policy_asset*> (this, yes_create_asset);
+}
+
+void reset_policy_call::fill_in_prep_code (void)
+{
+    policy_fill_in_prep_code();
+}
+
+void reset_policy_call::fill_in_command (void)
+{
+    // (call_code already loaded by constructor)
+    find_replace_all ("$policy", asset_info.get_name(), call_code);
+    // Calculate the expected results:
+    calc_result_code();
+}
+
+/**********************************************************************************
+   End of methods of class reset_policy_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class add_policy_usage_call follow:
+**********************************************************************************/
+
+add_policy_usage_call::add_policy_usage_call (tf_fuzz_info *test_state,    // (constructor)
+                                    long &call_ser_no,
+                                    asset_search how_asset_found)
+                                        : policy_call(test_state, call_ser_no,
+                                                   how_asset_found)
+{
+    // Copy the boilerplate text into local buffers:
+    prep_code.assign ("");
+    call_code.assign (test_state->bplate->bplate_string[add_policy_usage]);
+    call_description = "policy add-usage call";
+}
+add_policy_usage_call::~add_policy_usage_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool add_policy_usage_call::copy_call_to_asset (void)
+{
+    return copy_call_to_asset_t<policy_asset*> (this, yes_create_asset);
+}
+
+void add_policy_usage_call::fill_in_prep_code (void)
+{
+    policy_fill_in_prep_code();
+    /* TODO:  The variable this creates should have been declared already.  Should
+              this instead produce an error if it doesn't exist? */
+}
+
+void add_policy_usage_call::fill_in_command (void)
+{
+    // (call_code already loaded by constructor)
+    find_replace_all ("$policy", asset_info.get_name(), call_code);
+    find_replace_1st ("$flag", policy.usage_string, call_code);
+    // Calculate the expected results:
+    calc_result_code();
+}
+
+/**********************************************************************************
+   End of methods of class add_policy_usage_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class set_policy_lifetime_call follow:
+**********************************************************************************/
+
+set_policy_lifetime_call::set_policy_lifetime_call (tf_fuzz_info *test_state,
+                                    long &call_ser_no,    // (constructor)
+                                    asset_search how_asset_found)
+                                        : policy_call(test_state, call_ser_no,
+                                                   how_asset_found)
+{
+    // Copy the boilerplate text into local buffers:
+    prep_code.assign ("");
+    call_code.assign (test_state->bplate->bplate_string[set_policy_lifetime]);
+    call_description = "policy lifetime-set call";
+}
+set_policy_lifetime_call::~set_policy_lifetime_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool set_policy_lifetime_call::copy_call_to_asset (void)
+{
+    return copy_call_to_asset_t<policy_asset*> (this, yes_create_asset);
+}
+
+void set_policy_lifetime_call::fill_in_prep_code (void)
+{
+    policy_fill_in_prep_code();
+}
+
+void set_policy_lifetime_call::fill_in_command (void)
+{
+    // (call_code already loaded by constructor)
+    find_replace_all ("$policy", asset_info.get_name(), call_code);
+    find_replace_1st ("$life",
+                      policy.persistent?   "PSA_KEY_LIFETIME_PERSISTENT"
+                                         : "PSA_KEY_LIFETIME_VOLATILE",
+                      call_code);
+    // Calculate the expected results:
+    calc_result_code();
+}
+
+/**********************************************************************************
+   End of methods of class set_policy_lifetime_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class set_policy_size_call follow:
+**********************************************************************************/
+
+set_policy_size_call::set_policy_size_call (tf_fuzz_info *test_state,    // (constructor)
+                                    long &call_ser_no,
+                                    asset_search how_asset_found)
+                                        : policy_call(test_state, call_ser_no,
+                                                   how_asset_found)
+{
+    // Copy the boilerplate text into local buffers:
+    prep_code.assign ("");
+    call_code.assign (test_state->bplate->bplate_string[set_policy_size]);
+    call_description = "policy size-set call";
+}
+set_policy_size_call::~set_policy_size_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool set_policy_size_call::copy_call_to_asset (void)
+{
+    return copy_call_to_asset_t<policy_asset*> (this, yes_create_asset);
+}
+
+void set_policy_size_call::fill_in_prep_code (void)
+{
+    policy_fill_in_prep_code();
+}
+
+void set_policy_size_call::fill_in_command (void)
+{
+    // (call_code already loaded by constructor)
+    find_replace_all ("$policy", asset_info.get_name(), call_code);
+    find_replace_1st ("$size", to_string (policy.n_bits), call_code);
+    // Calculate the expected results:
+    calc_result_code();
+}
+
+/**********************************************************************************
+   End of methods of class set_policy_size_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class set_policy_type_call follow:
+**********************************************************************************/
+
+set_policy_type_call::set_policy_type_call (tf_fuzz_info *test_state,    // (constructor)
+                                    long &call_ser_no,
+                                    asset_search how_asset_found)
+                                        : policy_call(test_state, call_ser_no,
+                                                   how_asset_found)
+{
+    // Copy the boilerplate text into local buffers:
+    prep_code.assign ("");
+    call_code.assign (test_state->bplate->bplate_string[set_policy_type]);
+    call_description = "policy type-set call";
+}
+set_policy_type_call::~set_policy_type_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool set_policy_type_call::copy_call_to_asset (void)
+{
+    return copy_call_to_asset_t<policy_asset*> (this, yes_create_asset);
+}
+
+void set_policy_type_call::fill_in_prep_code (void)
+{
+    policy_fill_in_prep_code();
+}
+
+void set_policy_type_call::fill_in_command (void)
+{
+    // (call_code already loaded by constructor)
+    find_replace_all ("$policy", asset_info.get_name(), call_code);
+    find_replace_1st ("$type", policy.key_type, call_code);
+    // Calculate the expected results:
+    calc_result_code();
+}
+
+/**********************************************************************************
+   End of methods of class set_policy_type_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class set_policy_algorithm_call follow:
+**********************************************************************************/
+
+set_policy_algorithm_call::set_policy_algorithm_call (tf_fuzz_info *test_state,
+                                    long &call_ser_no,    // (constructor)
+                                    asset_search how_asset_found)
+                                        : policy_call(test_state, call_ser_no,
+                                                   how_asset_found)
+{
+    // Copy the boilerplate text into local buffers:
+    prep_code.assign ("");
+    call_code.assign (test_state->bplate->bplate_string[set_policy_algorithm]);
+    call_description = "policy algorithm-set call";
+}
+set_policy_algorithm_call::~set_policy_algorithm_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool set_policy_algorithm_call::copy_call_to_asset (void)
+{
+    return copy_call_to_asset_t<policy_asset*> (this, yes_create_asset);
+}
+
+void set_policy_algorithm_call::fill_in_prep_code (void)
+{
+    policy_fill_in_prep_code();
+}
+
+void set_policy_algorithm_call::fill_in_command (void)
+{
+    // (call_code already loaded by constructor)
+    find_replace_all ("$policy", asset_info.get_name(), call_code);
+    find_replace_1st ("$algorithm", policy.key_algorithm, call_code);
+    // Calculate the expected results:
+    calc_result_code();
+}
+
+/**********************************************************************************
+   End of methods of class set_policy_algorithm_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class set_policy_usage_call follow:
+**********************************************************************************/
+
+set_policy_usage_call::set_policy_usage_call (tf_fuzz_info *test_state,    // (constructor)
+                                    long &call_ser_no,
+                                    asset_search how_asset_found)
+                                        : policy_call(test_state, call_ser_no,
+                                                   how_asset_found)
+{
+    // Copy the boilerplate text into local buffers:
+    prep_code.assign ("");
+    call_code.assign (test_state->bplate->bplate_string[set_policy_usage]);
+    call_description = "policy usage-set call";
+}
+set_policy_usage_call::~set_policy_usage_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool set_policy_usage_call::copy_call_to_asset (void)
+{
+    return copy_call_to_asset_t<policy_asset*> (this, yes_create_asset);
+}
+
+void set_policy_usage_call::fill_in_prep_code (void)
+{
+    policy_fill_in_prep_code();
+}
+
+void set_policy_usage_call::fill_in_command (void)
+{
+    find_replace_1st ("$policy", asset_info.get_name(), call_code);
+    find_replace_1st ("$usage", "0", call_code);
+    // Calculate the expected results:
+    calc_result_code();
+}
+
+/**********************************************************************************
+   End of methods of class set_policy_usage_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class get_policy_lifetime_call follow:
+**********************************************************************************/
+
+get_policy_lifetime_call::get_policy_lifetime_call (tf_fuzz_info *test_state,
+                                    long &call_ser_no,    // (constructor)
+                                    asset_search how_asset_found)
+                                        : policy_call(test_state, call_ser_no,
+                                                   how_asset_found)
+{
+    // Copy the boilerplate text into local buffers:
+    prep_code.assign ("");
+    call_code.assign (test_state->bplate->bplate_string[get_policy_lifetime]);
+    call_description = "policy lifetime-get call";
+}
+get_policy_lifetime_call::~get_policy_lifetime_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool get_policy_lifetime_call::copy_call_to_asset (void)
+{
+    return copy_call_to_asset_t<policy_asset*> (this, dont_create_asset);
+}
+
+void get_policy_lifetime_call::fill_in_prep_code (void)
+{
+    string var_name = asset_info.get_name() + "_life";
+    vector<variable_info>::iterator assign_variable;
+
+    policy_fill_in_prep_code();  // make sure the policy variable itself is defined
+    assign_variable = test_state->find_var (var_name);
+    if (assign_variable == test_state->variable.end()) {
+        // No such variable exists, so:
+        test_state->make_var (var_name);
+        prep_code.append (test_state->bplate->bplate_string[declare_policy_lifetime]);
+        find_replace_all ("$var", var_name, prep_code);
+    }
+}
+
+void get_policy_lifetime_call::fill_in_command (void)
+{
+    // (call_code already loaded by constructor)
+    find_replace_all ("$policy", asset_info.get_name(), call_code);
+    find_replace_1st ("$life", asset_info.get_name() + "_life", call_code);
+    // Calculate the expected results:
+    calc_result_code();
+}
+
+/**********************************************************************************
+   End of methods of class get_policy_lifetime_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class get_policy_size_call follow:
+**********************************************************************************/
+
+get_policy_size_call::get_policy_size_call (tf_fuzz_info *test_state,
+                                    long &call_ser_no,    // (constructor)
+                                    asset_search how_asset_found)
+                                        : policy_call(test_state, call_ser_no,
+                                                   how_asset_found)
+{
+    // Copy the boilerplate text into local buffers:
+    prep_code.assign ("");
+    call_code.assign (test_state->bplate->bplate_string[get_policy_size]);
+    call_description = "policy size-get call";
+}
+get_policy_size_call::~get_policy_size_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool get_policy_size_call::copy_call_to_asset (void)
+{
+    return copy_call_to_asset_t<policy_asset*> (this, dont_create_asset);
+}
+
+void get_policy_size_call::fill_in_prep_code (void)
+{
+    string var_name = asset_info.get_name() + "_size";
+    vector<variable_info>::iterator assign_variable;
+
+    policy_fill_in_prep_code();  // make sure the policy variable itself is defined
+    assign_variable = test_state->find_var (var_name);
+    if (assign_variable == test_state->variable.end()) {
+        // No such variable exists, so:
+        test_state->make_var (var_name);
+        prep_code.append (test_state->bplate->bplate_string[declare_size_t]);
+        find_replace_all ("$var", var_name, prep_code);
+        find_replace_1st ("$init", to_string(exp_data.data.length()), prep_code);
+    }
+}
+
+void get_policy_size_call::fill_in_command (void)
+{
+    // (call_code already loaded by constructor)
+    find_replace_all ("$policy", asset_info.get_name(), call_code);
+    find_replace_1st ("$size", asset_info.get_name() + "_size", call_code);
+    // Calculate the expected results:
+    calc_result_code();
+}
+
+/**********************************************************************************
+   End of methods of class get_policy_size_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class get_policy_type_call follow:
+**********************************************************************************/
+
+get_policy_type_call::get_policy_type_call (tf_fuzz_info *test_state,
+                                    long &call_ser_no,    // (constructor)
+                                    asset_search how_asset_found)
+                                        : policy_call(test_state, call_ser_no,
+                                                   how_asset_found)
+{
+    // Copy the boilerplate text into local buffers:
+    prep_code.assign ("");
+    call_code.assign (test_state->bplate->bplate_string[get_policy_type]);
+    call_description = "policy type-get call";
+}
+get_policy_type_call::~get_policy_type_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool get_policy_type_call::copy_call_to_asset (void)
+{
+    return copy_call_to_asset_t<policy_asset*> (this, dont_create_asset);
+}
+
+void get_policy_type_call::fill_in_prep_code (void)
+{
+    string var_name = asset_info.get_name() + "_type";
+    vector<variable_info>::iterator assign_variable;
+
+    policy_fill_in_prep_code();  // make sure the policy variable itself is defined
+    assign_variable = test_state->find_var (var_name);
+    if (assign_variable == test_state->variable.end()) {
+        // No such variable exists, so:
+        test_state->make_var (var_name);
+        prep_code.append (test_state->bplate->bplate_string[declare_policy_type]);
+        find_replace_all ("$var", var_name, prep_code);
+    }
+}
+
+void get_policy_type_call::fill_in_command (void)
+{
+    // (call_code already loaded by constructor)
+    find_replace_all ("$policy", asset_info.get_name(), call_code);
+    find_replace_1st ("$type", asset_info.get_name() + "_type", call_code);
+    // Calculate the expected results:
+    calc_result_code();
+}
+
+/**********************************************************************************
+   End of methods of class get_policy_type_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class get_policy_algorithm_call follow:
+**********************************************************************************/
+
+get_policy_algorithm_call::get_policy_algorithm_call (tf_fuzz_info *test_state,
+                                    long &call_ser_no,    // (constructor)
+                                    asset_search how_asset_found)
+                                        : policy_call(test_state, call_ser_no,
+                                                   how_asset_found)
+{
+    // Copy the boilerplate text into local buffers:
+    prep_code.assign ("");
+    call_code.assign (test_state->bplate->bplate_string[get_policy_algorithm]);
+    call_description = "policy algorithm-get call";
+}
+get_policy_algorithm_call::~get_policy_algorithm_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool get_policy_algorithm_call::copy_call_to_asset (void)
+{
+    return copy_call_to_asset_t<policy_asset*> (this, dont_create_asset);
+}
+
+void get_policy_algorithm_call::fill_in_prep_code (void)
+{
+    string var_name = asset_info.get_name() + "_algo";
+    vector<variable_info>::iterator assign_variable;
+
+    policy_fill_in_prep_code();  // make sure the policy variable itself is defined
+    assign_variable = test_state->find_var (var_name);
+    if (assign_variable == test_state->variable.end()) {
+        // No such variable exists, so:
+        test_state->make_var (var_name);
+        prep_code.append (test_state->bplate->bplate_string[declare_policy_algorithm]);
+        find_replace_all ("$var", var_name, prep_code);
+    }
+}
+
+void get_policy_algorithm_call::fill_in_command (void)
+{
+    // (call_code already loaded by constructor)
+    find_replace_all ("$policy", asset_info.get_name(), call_code);
+    find_replace_1st ("$algorithm", asset_info.get_name() + "_algo", call_code);
+    // Calculate the expected results:
+    calc_result_code();
+}
+
+/**********************************************************************************
+   End of methods of class get_policy_algorithm_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class get_policy_usage_call follow:
+**********************************************************************************/
+
+get_policy_usage_call::get_policy_usage_call (tf_fuzz_info *test_state,
+                                    long &call_ser_no,    // (constructor)
+                                    asset_search how_asset_found)
+                                        : policy_call(test_state, call_ser_no,
+                                                   how_asset_found)
+{
+    // Copy the boilerplate text into local buffers:
+    prep_code.assign ("");
+    call_code.assign (test_state->bplate->bplate_string[get_policy_usage]);
+    call_description = "policy usage-get call";
+}
+get_policy_usage_call::~get_policy_usage_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool get_policy_usage_call::copy_call_to_asset (void)
+{
+    return copy_call_to_asset_t<policy_asset*> (this, dont_create_asset);
+}
+
+void get_policy_usage_call::fill_in_prep_code (void)
+{
+    string var_name = asset_info.get_name() + "_usage";
+    vector<variable_info>::iterator assign_variable;
+
+    policy_fill_in_prep_code();  // make sure the policy variable itself is defined
+    assign_variable = test_state->find_var (var_name);
+    if (assign_variable == test_state->variable.end()) {
+        // No such variable exists, so:
+        test_state->make_var (var_name);
+        prep_code.append (test_state->bplate->bplate_string[declare_policy_usage]);
+        find_replace_all ("$var", var_name, prep_code);
+    }
+}
+
+void get_policy_usage_call::fill_in_command (void)
+{
+    // (call_code already loaded by constructor)
+    find_replace_all ("$policy", asset_info.get_name(), call_code);
+    find_replace_1st ("$usage", asset_info.get_name() + "_usage", call_code);
+    // Calculate the expected results:
+    calc_result_code();
+}
+
+/**********************************************************************************
+   End of methods of class get_policy_usage_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class print_policy_usage_call follow:
+**********************************************************************************/
+
+print_policy_usage_call::print_policy_usage_call (tf_fuzz_info *test_state,
+                                    long &call_ser_no,    // (constructor)
+                                    asset_search how_asset_found)
+                                        : policy_call(test_state, call_ser_no,
+                                                   how_asset_found)
+{
+    // Copy the boilerplate text into local buffers:
+    prep_code.assign ("");
+    call_code.assign (test_state->bplate->bplate_string[print_policy_usage]);
+    call_description = "policy usage-print call";
+}
+print_policy_usage_call::~print_policy_usage_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool print_policy_usage_call::copy_call_to_asset (void)
+{
+    return copy_call_to_asset_t<policy_asset*> (this, dont_create_asset);
+}
+
+void print_policy_usage_call::fill_in_prep_code (void)
+{
+    string var_name = asset_info.get_name() + "_usage";
+    vector<variable_info>::iterator assign_variable;
+
+    policy_fill_in_prep_code();  // make sure the policy variable itself is defined
+    // Make sure policy-usage variable is defined:
+    assign_variable = test_state->find_var (var_name);
+    if (assign_variable == test_state->variable.end()) {
+        // No such variable exists, so:
+        test_state->make_var (var_name);
+        prep_code.append (test_state->bplate->bplate_string[declare_policy_usage]);
+        find_replace_all ("$var", var_name, prep_code);
+    }
+}
+
+void print_policy_usage_call::fill_in_command (void)
+{
+    string var_name = asset_info.get_name() + "_usage";
+
+    // (call_code already loaded by constructor)
+    find_replace_all ("$policy", asset_info.get_name(), call_code);
+    find_replace_1st ("$usage_string", policy.usage_string, call_code);
+    find_replace_1st ("$usage", var_name, call_code);
+    find_replace_1st ("$print_usage_true_string", policy.print_usage_true_string,
+                      call_code);
+    find_replace_1st ("$print_usage_false_string", policy.print_usage_false_string,
+                      call_code);
+    // Calculate the expected results:
+    calc_result_code();
+}
+
+/**********************************************************************************
+   End of methods of class print_policy_usage_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class get_key_policy_call follow:
+**********************************************************************************/
+
+get_key_policy_call::get_key_policy_call (tf_fuzz_info *test_state,    // (constructor)
+                                    long &call_ser_no,
+                                    asset_search how_asset_found)
+                                        : policy_call(test_state, call_ser_no,
+                                                   how_asset_found)
+{
+    // Copy the boilerplate text into local buffers:
+    prep_code.assign ("");
+    call_code.assign (test_state->bplate->bplate_string[get_policy]);
+    check_code.assign (test_state->bplate->bplate_string[get_policy_check]);
+    call_description = "policy get call";
+}
+get_key_policy_call::~get_key_policy_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool get_key_policy_call::copy_call_to_asset (void)
+{
+    return copy_call_to_asset_t<key_asset*> (this, dont_create_asset);
+}
+
+void get_key_policy_call::fill_in_prep_code (void)
+{
+    // No prep code required.
+    return;  // just to have something to pin a breakpoint onto
+}
+
+void get_key_policy_call::fill_in_command (void)
+{
+    // (call_code already loaded by constructor)
+    find_replace_all ("key", asset_info.get_name(), call_code);
+    find_replace_all ("$policy", policy.asset_2_name, call_code);
+    // Calculate the expected results:
+    calc_result_code();
+}
+
+/**********************************************************************************
+   End of methods of class get_key_policy_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class generate_key_call follow:
+**********************************************************************************/
+
+generate_key_call::generate_key_call (tf_fuzz_info *test_state,    // (constructor)
+                                    long &call_ser_no,
+                                    asset_search how_asset_found)
+                                        : key_call(test_state, call_ser_no,
+                                                   how_asset_found)
+{
+    // Copy the boilerplate text into local buffers:
+    prep_code.assign ("");
+    call_code.assign (test_state->bplate->bplate_string[generate_key]);
+    check_code.assign (test_state->bplate->bplate_string[generate_key_check]);
+    call_description = "key-generate call";
+}
+generate_key_call::~generate_key_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool generate_key_call::copy_call_to_asset (void)
+{
+    return copy_call_to_asset_t<key_asset*> (this, yes_create_asset);
+}
+
+void generate_key_call::fill_in_prep_code (void)
+{
+    string var_name = asset_info.get_name();
+    vector<variable_info>::iterator assign_variable;
+
+    // Make sure key variable is defined:
+    assign_variable = test_state->find_var (var_name);
+    if (assign_variable == test_state->variable.end()) {
+        // No such variable exists, so:
+        test_state->make_var (var_name);
+        prep_code.append (test_state->bplate->bplate_string[declare_key]);
+        find_replace_all ("$var", var_name, prep_code);
+    }
+}
+
+void generate_key_call::fill_in_command (void)
+{
+    // (call_code already loaded by constructor)
+    find_replace_all ("$policy", policy.asset_2_name, call_code);
+    find_replace_all ("$key", asset_info.get_name(), call_code);
+    // Calculate the expected results:
+    calc_result_code();
+}
+
+/**********************************************************************************
+   End of methods of class generate_key_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class create_key_call follow:
+**********************************************************************************/
+
+create_key_call::create_key_call (tf_fuzz_info *test_state,    // (constructor)
+                                    long &call_ser_no,
+                                    asset_search how_asset_found)
+                                        : key_call(test_state, call_ser_no,
+                                                   how_asset_found)
+{
+    // Copy the boilerplate text into local buffers:
+    prep_code.assign ("");
+    call_code.assign (test_state->bplate->bplate_string[create_key]);
+    check_code.assign (test_state->bplate->bplate_string[create_key_check]);
+    call_description = "key-create call";
+}
+create_key_call::~create_key_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool create_key_call::copy_call_to_asset (void)
+{
+    return copy_call_to_asset_t<key_asset*> (this, yes_create_asset);
+}
+
+void create_key_call::fill_in_prep_code (void)
+{
+    string var_name = asset_info.get_name();
+    vector<variable_info>::iterator assign_variable;
+    gibberish gib;
+    char gib_buff[500];
+    string t_string;
+
+    // Key variable:
+    assign_variable = test_state->find_var (var_name);
+    if (assign_variable == test_state->variable.end()) {
+        // No such variable exists, so:
+        test_state->make_var (var_name);
+        prep_code.append (test_state->bplate->bplate_string[declare_key]);
+        find_replace_all ("$var", var_name, prep_code);
+    }
+    // Key-data variable:
+    var_name = asset_info.get_name() + "_set_data";
+    assign_variable = test_state->find_var (var_name);
+    if (assign_variable == test_state->variable.end()) {
+        // No such variable exists, so:
+        test_state->make_var (var_name);
+        prep_code.append (test_state->bplate->bplate_string[declare_big_string]);
+        find_replace_all ("$var", var_name, prep_code);
+        int rand_data_length = 12 + (rand() % 100);
+        gib.sentence (gib_buff, gib_buff + rand_data_length - 1);
+        t_string = gib_buff;
+        find_replace_all ("$init", t_string, prep_code);
+    }
+}
+
+void create_key_call::fill_in_command (void)
+{
+    // (call_code already loaded by constructor)
+    find_replace_all ("$policy", policy.asset_2_name, call_code);
+    find_replace_all ("$data", asset_info.get_name() + "_set_data", call_code);
+    find_replace_all ("$length", to_string (policy.n_bits), call_code);
+    find_replace_all ("$key", asset_info.get_name(), call_code);
+    // Calculate the expected results:
+    calc_result_code();
+}
+
+/**********************************************************************************
+   End of methods of class create_key_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class copy_key_call follow:
+**********************************************************************************/
+
+copy_key_call::copy_key_call (tf_fuzz_info *test_state,    // (constructor)
+                                    long &call_ser_no,
+                                    asset_search how_asset_found)
+                                        : key_call(test_state, call_ser_no,
+                                                   how_asset_found)
+{
+    // Copy the boilerplate text into local buffers:
+    prep_code.assign ("");
+    call_code.assign (test_state->bplate->bplate_string[copy_key]);
+    check_code.assign (test_state->bplate->bplate_string[copy_key_check]);
+    call_description = "key-copy call";
+}
+copy_key_call::~copy_key_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool copy_key_call::copy_call_to_asset (void)
+{
+    return copy_call_to_asset_t<key_asset*> (this, yes_create_asset);
+}
+
+void copy_key_call::fill_in_prep_code (void)
+{
+    string var_name = asset_info.get_name();
+    vector<variable_info>::iterator assign_variable;
+
+    // Make sure key variable is defined:
+    assign_variable = test_state->find_var (var_name);
+    if (assign_variable == test_state->variable.end()) {
+        // No such variable exists, so:
+        test_state->make_var (var_name);
+        prep_code.append (test_state->bplate->bplate_string[declare_key]);
+        find_replace_all ("$var", var_name, prep_code);
+    }
+}
+
+void copy_key_call::fill_in_command (void)
+{
+    vector<psa_asset*>::iterator key_asset;
+    vector<psa_asset*> *asset_vector;
+    int asset_pick;
+
+    // Calculate the expected results:
+    asset_search find_result;
+    vector<psa_asset*>::iterator asset;
+    long dummy = 0L;
+    // See if the source key does not exist:
+
+    if (random_asset != psa_asset_usage::all) {
+        // != psa_asset_usage::all means to choose some known asset at random:
+        if (random_asset == psa_asset_usage::active) {
+            asset_vector = &(test_state->active_key_asset);
+            find_result = asset_info.how_asset_found = asset_search::found_active;
+                // if empty, we'll error out, below.
+        } else if (random_asset == psa_asset_usage::deleted) {
+            asset_vector = &(test_state->deleted_key_asset);
+            find_result = asset_info.how_asset_found = asset_search::found_deleted;
+        } else {
+            // "invalid" assets are not currently used.
+            cerr << "\nError:  Tool-internal:  Please report error 1103 to " << endl
+                 << "TF-Fuzz developers."
+                 << endl;
+            exit(1103);
+        }
+        if (asset_vector->size() > 0) {
+            /* Pick an active or deleted asset at random: */
+            asset_pick = rand() % asset_vector->size();
+            key_asset = asset_vector->begin() + asset_pick;
+            /* Copy asset information into template tracker: */
+            asset_info.id_n = (*key_asset)->asset_info.id_n;
+            asset_info.asset_ser_no
+                    = (*key_asset)->asset_info.asset_ser_no;
+        } else {
+            if (random_asset == psa_asset_usage::active) {
+                cerr << "\nError:  A key call asks for a "
+                     << "randomly chosen active asset, when none " << endl
+                     << "is currently defined." << endl;
+                exit(1012);
+            } else if (random_asset == psa_asset_usage::deleted) {
+                cerr << "\nError:  A key call asks for a "
+                     << "randomly chosen deleted asset, when none " << endl
+                     << "is currently defined." << endl;
+                exit(1013);
+            }  // "invalid" assets are not currently used.
+        }
+    } else {
+        find_result = test_state->
+            find_or_create_key_asset (psa_asset_search::name, psa_asset_usage::active,
+                                      policy.asset_3_name, (uint64_t) 0, dummy,
+                                      dont_create_asset, key_asset);
+    }
+    if (find_result != asset_search::found_active) {
+        exp_data.pf_specified = true;
+        exp_data.pf_result_string = "PSA_ERROR_INVALID_ARGUMENT";
+            // TODO:  Pull this in from boilerplate file
+    } else {
+        // See if the new policy does not exist:
+        find_result = test_state->
+            find_or_create_policy_asset (psa_asset_search::name, psa_asset_usage::active,
+                                         policy.asset_2_name, (uint64_t) 0, dummy,
+                                         dont_create_asset, asset);
+        if (find_result != asset_search::found_active) {
+            exp_data.pf_specified = true;
+            exp_data.pf_result_string = "PSA_ERROR_INVALID_ARGUMENT";
+                // TODO:  Pull this in from boilerplate file
+        } else if (!(*asset)->policy.copyable) {
+            // See if the source key does not support export:
+            // TODO:  Or wait, it's the original policy for the key, right?
+            exp_data.pf_specified = true;
+            exp_data.pf_result_string = "PSA_ERROR_NOT_PERMITTED";
+        }
+    }
+
+    // (call_code already loaded by constructor)
+    find_replace_all ("$master", (*key_asset)->asset_info.get_name(), call_code);
+    find_replace_all ("$policy", policy.asset_2_name, call_code);
+    find_replace_all ("$copy", asset_info.get_name(), call_code);
+    calc_result_code();
+}
+
+/**********************************************************************************
+   End of methods of class copy_key_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class read_key_data_call follow:
+**********************************************************************************/
+
+read_key_data_call::read_key_data_call (tf_fuzz_info *test_state,    // (constructor)
+                                    long &call_ser_no,
+                                    asset_search how_asset_found)
+                                        : key_call(test_state, call_ser_no,
+                                                   how_asset_found)
+{
+    // Copy the boilerplate text into local buffers:
+    prep_code.assign ("");
+    call_code.assign (test_state->bplate->bplate_string[read_key_data]);
+    check_code.assign (test_state->bplate->bplate_string[read_key_data_check]);
+    call_description = "key read-data call";
+}
+read_key_data_call::~read_key_data_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool read_key_data_call::copy_call_to_asset (void)
+{
+    return copy_call_to_asset_t<key_asset*> (this, dont_create_asset);
+}
+
+void read_key_data_call::fill_in_prep_code (void)
+{
+    string var_name, length_var_name, actual_length_var_name, var_name_suffix,
+           length_var_name_suffix, temp_string;
+    vector<variable_info>::iterator expect_variable;
+    vector<variable_info>::iterator assign_variable;
+
+    if (exp_data.data_var_specified) {
+        var_name.assign (exp_data.data_var + "_data");
+        length_var_name.assign (exp_data.data_var + "_length");
+        /* If actual-data variable doesn't already exist, create variable tracker,
+           and write declaration for it: */
+        expect_variable = test_state->find_var (exp_data.data_var);
+        if (expect_variable == test_state->variable.end()) {
+            // No such variable exists, so:
+            test_state->make_var (exp_data.data_var);
+            expect_variable = test_state->find_var (exp_data.data_var);
+            prep_code.append (test_state->bplate->bplate_string[declare_big_string]);
+            find_replace_1st ("$var", var_name, prep_code);
+            temp_string = (char *) expect_variable->value;
+            find_replace_1st ("$init", temp_string, prep_code);
+            // Input data length:
+            prep_code.append (test_state->bplate->bplate_string[declare_size_t]);
+            find_replace_1st ("$var", length_var_name, prep_code);
+            find_replace_1st ("$init", to_string(temp_string.length()), prep_code);
+            // TODO:  Is these lengths in bits or bytes?
+        }
+    }
+    // else we're not comparing to named variable, so compare to assigned data.
+    // Actual (output) data length:
+    if (assign_data_var_specified) {
+        var_name.assign (assign_data_var + "_data");
+        length_var_name.assign (assign_data_var + "_length");
+        actual_length_var_name.assign (assign_data_var + "_act_length");
+        /* If actual-data variable doesn't already exist, create variable tracker,
+           and write declaration for it: */
+        assign_variable = test_state->find_var (assign_data_var);
+        if (assign_variable == test_state->variable.end()) {
+            // No such variable exists, so:
+            test_state->make_var (assign_data_var);
+            assign_variable = test_state->find_var (assign_data_var);
+            prep_code.append (test_state->bplate->bplate_string[declare_big_string]);
+            find_replace_1st ("$var", var_name, prep_code);
+            temp_string = (char *) assign_variable->value;
+            find_replace_1st ("$init", temp_string, prep_code);
+            // Input data length:
+            prep_code.append (test_state->bplate->bplate_string[declare_size_t]);
+            find_replace_1st ("$var", length_var_name, prep_code);
+            find_replace_1st ("$init", to_string(temp_string.length()), prep_code);
+        }
+    } else {
+        // Key data not read into a named variable, so use default C variable:
+        var_name = asset_info.get_name() + "_act_data";
+        prep_code.append (test_state->bplate->bplate_string[declare_string]);
+        find_replace_1st ("$var", var_name, prep_code);
+        find_replace_1st ("$init", set_data.get(), prep_code);
+        actual_length_var_name.assign (asset_info.get_name() + "_act_length");
+        prep_code.append (test_state->bplate->bplate_string[declare_size_t]);
+        find_replace_1st ("$var", actual_length_var_name, prep_code);
+        find_replace_1st ("$init", to_string(set_data.get().length()), prep_code);
+    }
+    length_var_name_suffix = "_read_length";
+    var_name.assign (asset_info.get_name() + var_name_suffix);
+    length_var_name.assign (asset_info.get_name() + length_var_name_suffix);
+    prep_code.append (test_state->bplate->bplate_string[declare_size_t]);
+    find_replace_1st ("$var", length_var_name, prep_code);
+    find_replace_1st ("$init", to_string(set_data.get().length()), prep_code);
+}
+
+void read_key_data_call::fill_in_command (void)
+{
+    string var_name, length_var_name, exp_var_name, exp_length_var_name, 
+           actual_length_var_name, var_name_suffix, length_var_name_suffix, 
+           temp_string;
+
+    // Fill in the PSA command itself:
+    actual_length_var_name.assign (asset_info.get_name() + "_read_length");
+    if (assign_data_var_specified) {
+        var_name.assign (assign_data_var + "_data");
+        length_var_name.assign (assign_data_var + "_length");
+    } else {
+        var_name_suffix = "_act_data";
+        var_name.assign (asset_info.get_name() + var_name_suffix);
+        length_var_name_suffix = "_act_length";
+        length_var_name.assign (asset_info.get_name() + length_var_name_suffix);
+    }
+    find_replace_1st ("$data", var_name, call_code);
+    find_replace_1st ("$key", asset_info.get_name(), call_code);
+    string id_string = to_string((long) asset_info.id_n++);
+    find_replace_1st ("$length", length_var_name, call_code);
+    find_replace_1st ("$act_size", actual_length_var_name, call_code);
+
+    // Check data:
+    if (exp_data.data_var_specified) {
+        check_code.assign (test_state->bplate->bplate_string[compare_data]);
+        exp_var_name.assign (exp_data.data_var + "_data");
+        exp_length_var_name.assign (exp_data.data_var + "_length");
+        find_replace_1st ("$act_data", var_name, check_code);
+        find_replace_1st ("$exp_data", exp_var_name, check_code);
+        find_replace_1st ("$length", exp_length_var_name, check_code);
+    }
+
+    // See if the source key did not exist:
+    if (!policy.exportable) {
+        // See if the source key does not support export:
+        exp_data.pf_specified = true;
+        exp_data.pf_result_string = "PSA_ERROR_NOT_PERMITTED";
+    }
+    calc_result_code();
+}
+
+/**********************************************************************************
+   End of methods of class read_key_data_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class remove_key_call follow:
+**********************************************************************************/
+
+remove_key_call::remove_key_call (tf_fuzz_info *test_state,    // (constructor)
+                                    long &call_ser_no,
+                                    asset_search how_asset_found)
+                                        : key_call(test_state, call_ser_no,
+                                                   how_asset_found)
+{
+    // Copy the boilerplate text into local buffers:
+    prep_code.assign ("");
+    call_code.assign (test_state->bplate->bplate_string[remove_key]);
+    check_code.assign (test_state->bplate->bplate_string[remove_key_check]);
+    call_description = "key-remove call";
+}
+remove_key_call::~remove_key_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool remove_key_call::copy_call_to_asset (void)
+{
+    return copy_call_to_asset_t<key_asset*> (this, dont_create_asset);
+}
+
+void remove_key_call::fill_in_prep_code (void)
+{
+    // No prep code required.
+    return;  // just to have something to pin a breakpoint onto
+}
+
+void remove_key_call::fill_in_command (void)
+{
+    // (call_code already loaded by constructor)
+    find_replace_all ("$key", asset_info.get_name(), call_code);
+    // Calculate the expected results:
+    calc_result_code();
+}
+
+/**********************************************************************************
+   End of methods of class remove_key_call.
+**********************************************************************************/
+
diff --git a/tf_fuzz/calls/crypto_call.hpp b/tf_fuzz/calls/crypto_call.hpp
new file mode 100644
index 0000000..7fd58cc
--- /dev/null
+++ b/tf_fuzz/calls/crypto_call.hpp
@@ -0,0 +1,582 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef CRYPTO_CALL_HPP
+#define CRYPTO_CALL_HPP
+
+#include <string>
+#include <vector>
+
+/* This project's header files #including other project headers quickly becomes
+   unrealistically complicated.  The only solution is for each .cpp to include
+   the headers it needs.
+#include "psa_call.hpp"
+#include "crypto_asset.hpp"
+*/
+
+template<class T> bool copy_call_to_asset_t (psa_call *call, bool create_asset_bool)
+{
+    vector<psa_asset*>::iterator found_asset;
+
+    found_asset = call->resolve_asset (create_asset_bool, psa_asset_usage::all);
+    // Copy over everything relevant:
+    if (call->asset_info.how_asset_found != asset_search::not_found) {
+        call->asset_info.the_asset = reinterpret_cast<T>(*found_asset);
+            /* Note:  The vector is base-class, but the assets in this list
+                      themselves *really are* policy_asset-type objects. */
+        int i = call->asset_info.the_asset->set_data.n_set_vars;  // save this
+        call->asset_info.the_asset->exp_data.data = call->exp_data.data;
+        call->asset_info.the_asset->set_data = call->set_data;
+        call->asset_info.the_asset->set_data.n_set_vars = call->set_data.n_set_vars = ++i;
+        call->asset_info.the_asset->policy = call->policy;
+        call->asset_info.the_asset->handle_str = call->asset_info.get_name();
+        if (call->asset_info.how_asset_found == asset_search::created_new) {
+            call->asset_info.the_asset->asset_info.name_specified
+                = call->asset_info.name_specified;
+            call->asset_info.the_asset->asset_info.set_name (call->asset_info.get_name());
+            call->asset_info.the_asset->asset_info.asset_ser_no
+                = call->asset_info.asset_ser_no;
+            call->asset_info.the_asset->asset_info.id_n = call->asset_info.id_n;
+        }
+    }
+    return true;
+}
+
+
+using namespace std;
+
+class policy_call : public crypto_call
+{
+public:
+    // Data members:  // (low value in hiding these behind setters and getters)
+    // Methods:
+        vector<psa_asset*>::iterator resolve_asset (bool create_asset_bool,
+                                                    psa_asset_usage where);
+        void policy_fill_in_prep_code (void);
+        policy_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                    asset_search how_asset_found);  // (constructor)
+        ~policy_call (void);
+
+protected:
+    // Data members:
+    // Methods:
+//        void calc_result_code (void);  for *now* keep this in crypto_call::
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+class key_call : public crypto_call
+{
+public:
+    // Data members:  // (low value in hiding these behind setters and getters)
+    // Methods:
+        vector<psa_asset*>::iterator resolve_asset (bool create_asset_bool,
+                                                    psa_asset_usage where);
+        key_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                    asset_search how_asset_found);  // (constructor)
+        ~key_call (void);
+
+protected:
+    // Data members:
+    // Methods:
+//        void calc_result_code (void);  for *now* keep this in crypto_call::
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+/**********************************************************************************
+   Derived classes of class policy_call follow:
+**********************************************************************************/
+
+
+class init_policy_call : public policy_call
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_call_to_asset (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        init_policy_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                          asset_search how_asset_found);  // (constructor)
+        ~init_policy_call (void);
+
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+class reset_policy_call : public policy_call
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_call_to_asset (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        reset_policy_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                           asset_search how_asset_found);  // (constructor)
+        ~reset_policy_call (void);
+
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+class set_policy_usage_call : public policy_call
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_call_to_asset (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        set_policy_usage_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                               asset_search how_asset_found);  // (constructor)
+        ~set_policy_usage_call (void);
+
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+/* set_policy_usage_call(), above, gives a policy particular attribute, and resets
+   all others.  add_policy_usage_call(), below, ORs in an additional usage
+   attribute, to whatever is already in there. */
+
+class add_policy_usage_call : public policy_call
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_call_to_asset (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        add_policy_usage_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                               asset_search how_asset_found);  // (constructor)
+        ~add_policy_usage_call (void);
+
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+class set_policy_lifetime_call : public policy_call
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_call_to_asset (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        set_policy_lifetime_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                                  asset_search how_asset_found);  // (constructor)
+        ~set_policy_lifetime_call (void);
+
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+class set_policy_algorithm_call : public policy_call
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_call_to_asset (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        set_policy_algorithm_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                                   asset_search how_asset_found);  // (constructor)
+        ~set_policy_algorithm_call (void);
+
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+class set_policy_size_call : public policy_call
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_call_to_asset (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        set_policy_size_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                              asset_search how_asset_found);  // (constructor)
+        ~set_policy_size_call (void);
+
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+class set_policy_type_call : public policy_call
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_call_to_asset (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        set_policy_type_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                              asset_search how_asset_found);  // (constructor)
+        ~set_policy_type_call (void);
+
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+class get_policy_lifetime_call : public policy_call
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_call_to_asset (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        get_policy_lifetime_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                                  asset_search how_asset_found);  // (constructor)
+        ~get_policy_lifetime_call (void);
+
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+class get_policy_size_call : public policy_call
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_call_to_asset (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        get_policy_size_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                              asset_search how_asset_found);  // (constructor)
+        ~get_policy_size_call (void);
+
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+class get_policy_type_call : public policy_call
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_call_to_asset (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        get_policy_type_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                              asset_search how_asset_found);  // (constructor)
+        ~get_policy_type_call (void);
+
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+class get_policy_algorithm_call : public policy_call
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_call_to_asset (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        get_policy_algorithm_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                                   asset_search how_asset_found);  // (constructor)
+        ~get_policy_algorithm_call (void);
+
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+class get_policy_usage_call : public policy_call
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_call_to_asset (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        get_policy_usage_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                               asset_search how_asset_found);  // (constructor)
+        ~get_policy_usage_call (void);
+
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+/* This is not actually a PSA call;  it just emits code to print out, to the log,
+   information about the usage info retrieved in a get_policy_usage_call above. */
+class print_policy_usage_call : public policy_call
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_call_to_asset (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        print_policy_usage_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                               asset_search how_asset_found);  // (constructor)
+        ~print_policy_usage_call (void);
+
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+class get_key_policy_call : public policy_call
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_call_to_asset (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        get_key_policy_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                         asset_search how_asset_found);  // (constructor)
+        ~get_key_policy_call (void);
+
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+/**********************************************************************************
+   End of derived classes of class policy_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Derived classes of class key_call follow:
+**********************************************************************************/
+
+
+class generate_key_call : public key_call
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_call_to_asset (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        generate_key_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                         asset_search how_asset_found);  // (constructor)
+        ~generate_key_call (void);
+
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+class create_key_call : public key_call
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_call_to_asset (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        create_key_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                         asset_search how_asset_found);  // (constructor)
+        ~create_key_call (void);
+
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+class copy_key_call : public key_call
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_call_to_asset (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        copy_key_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                         asset_search how_asset_found);  // (constructor)
+        ~copy_key_call (void);
+
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+class read_key_data_call : public key_call
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_call_to_asset (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        read_key_data_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                            asset_search how_asset_found);  // (constructor)
+        ~read_key_data_call (void);
+
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+class remove_key_call : public key_call
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_call_to_asset (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        remove_key_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                         asset_search how_asset_found);  // (constructor)
+        ~remove_key_call (void);
+
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+/**********************************************************************************
+   End of derived classes of class key_call.
+**********************************************************************************/
+
+#endif  // CRYPTO_CALL_HPP
diff --git a/tf_fuzz/calls/crypto_call.o b/tf_fuzz/calls/crypto_call.o
new file mode 100644
index 0000000..d2840ff
--- /dev/null
+++ b/tf_fuzz/calls/crypto_call.o
Binary files differ
diff --git a/tf_fuzz/calls/psa_call.cpp b/tf_fuzz/calls/psa_call.cpp
new file mode 100644
index 0000000..46af409
--- /dev/null
+++ b/tf_fuzz/calls/psa_call.cpp
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "class_forwards.hpp"
+
+#include "boilerplate.hpp"
+#include "gibberish.hpp"
+#include "compute.hpp"
+#include "string_ops.hpp"
+#include "data_blocks.hpp"
+#include "psa_asset.hpp"
+#include "find_or_create_asset.hpp"
+#include "template_line.hpp"
+#include "tf_fuzz.hpp"
+#include "crypto_asset.hpp"
+#include "psa_call.hpp"
+
+
+
+/**********************************************************************************
+   Methods of class psa_call follow:
+**********************************************************************************/
+
+//**************** psa_call methods ****************
+
+psa_call::psa_call (tf_fuzz_info *test_state, long &call_ser_no,   // (constructor)
+                    asset_search how_asset_found)
+{
+    this->test_state = test_state;
+    this->asset_info.how_asset_found = how_asset_found;
+    set_data.string_specified = false;
+    set_data.set ("");  // actual data
+    assign_data_var.assign ("");  // name of variable assigned (dumped) to
+    assign_data_var_specified = false;
+    set_data.file_specified = false;
+    set_data.file_path.assign ("");
+    this->call_ser_no = call_ser_no = unique_id_counter++;
+    // These will be set in the lower-level constructors, but...
+    prep_code = call_code = check_code = "";
+    print_data = hash_data = false;
+    barrier = target_barrier = "";  // not (yet) any barrier for re-ordering calls
+    call_description = "";
+}
+
+psa_call::~psa_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+void psa_call::write_out_prep_code (ofstream &test_file)
+{
+    test_file << prep_code;
+}
+
+void psa_call::write_out_command (ofstream &test_file)
+{
+    test_file << call_code;
+}
+
+void psa_call::write_out_check_code (ofstream &test_file)
+{
+    if (!exp_data.pf_nothing) {
+        test_file << check_code;
+    } else {
+        test_file << "    /* (No checks for this PSA call.) */" << endl;
+    }
+}
+
+/**********************************************************************************
+   End of methods of class psa_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class sst_call follow:
+**********************************************************************************/
+
+/* calc_result_code() fills in the check_code string member with the correct
+   result code (e.g., "PSA_SUCCESS" or whatever).
+
+   This is a big part of where the target modeling -- error modeling -- occurs,
+   so lots of room for further refinement here. */
+void sst_call::calc_result_code (void)
+{
+    string formalized;  // "proper" result string
+
+    if (!exp_data.pf_nothing) {
+        if (exp_data.pf_pass) {
+            find_replace_all ("$expect",
+                              test_state->bplate->bplate_string[sst_pass_string],
+                              check_code);
+        } else if (exp_data.pf_fail) {
+            // Check for not-success:
+            find_replace_1st ("!=", "==",
+                              check_code);
+            find_replace_all ("$expect",
+                              test_state->bplate->bplate_string[sst_pass_string],
+                              check_code);
+            find_replace_1st ("expected ", "expected not ",
+                              check_code);
+        } else {
+            if (exp_data.pf_specified) {
+                formalized = formalize (exp_data.pf_result_string, "PSA_ERROR_");
+                find_replace_all ("$expect", formalized, check_code);
+            } else {
+                // Figure out what the message should read:
+                switch (asset_info.how_asset_found) {
+                    case asset_search::found_active:
+                    case asset_search::created_new:
+                        find_replace_all ("$expect",
+                                          test_state->bplate->
+                                              bplate_string[sst_pass_string],
+                                          check_code);
+                        break;
+                    case asset_search::found_deleted:
+                    case asset_search::not_found:
+                        find_replace_all ("$expect",
+                                          test_state->bplate->
+                                              bplate_string[sst_fail_removed],
+                                          check_code);
+                        break;
+                    default:
+                        find_replace_1st ("!=", "==",
+                                          check_code);  // like "fail", just make sure...
+                        find_replace_all ("$expect",
+                                          test_state->bplate->
+                                              bplate_string[sst_pass_string],
+                                          check_code);  // ... it's *not* PSA_SUCCESS
+                        break;
+                }
+            }
+        }
+    }
+}
+
+vector<psa_asset*>::iterator sst_call::resolve_asset (bool create_asset_bool,
+                                                      psa_asset_usage where) {
+    vector<psa_asset*>::iterator found_asset;
+    vector<psa_asset*> *asset_vector;
+    int asset_pick;
+
+    if (random_asset != psa_asset_usage::all) {
+        // != psa_asset_usage::all means to choose some known asset at random:
+        if (random_asset == psa_asset_usage::active) {
+            asset_vector = &(test_state->active_sst_asset);
+            asset_info.how_asset_found = asset_search::found_active;
+        } else if (random_asset == psa_asset_usage::deleted) {
+            asset_vector = &(test_state->deleted_sst_asset);
+            asset_info.how_asset_found = asset_search::found_deleted;
+        } else {
+            // "invalid" assets are not currently used.
+            cerr << "\nError:  Tool-internal:  Please report error 1101 to " << endl
+                 << "TF-Fuzz developers."
+                 << endl;
+            exit(1101);
+        }
+        if (asset_vector->size() > 0) {
+            /* Pick an active or deleted asset at random: */
+            asset_pick = rand() % asset_vector->size();
+            found_asset = asset_vector->begin() + asset_pick;
+            /* Copy asset information into template tracker: */
+            asset_info.id_n = (*found_asset)->asset_info.id_n;
+            asset_info.asset_ser_no
+                    = (*found_asset)->asset_info.asset_ser_no;
+        } else {
+            if (random_asset == psa_asset_usage::active) {
+                cerr << "\nError:  An sst call asks for a "
+                     << "randomly chosen active asset, when none " << endl
+                     << "is currently defined." << endl;
+                exit(1008);
+            } else if (random_asset == psa_asset_usage::deleted) {
+                cerr << "\nError:  An sst call asks for a "
+                     << "randomly chosen deleted asset, when none " << endl
+                     << "is currently defined." << endl;
+                exit(1009);
+            }  // "invalid" assets are not currently used.
+        }
+    } else {
+        // Find the asset by name:
+        asset_info.how_asset_found = test_state->find_or_create_sst_asset (
+                            psa_asset_search::name, where,
+                            asset_info.get_name(), 0, asset_info.asset_ser_no,
+                            create_asset_bool, found_asset );
+        if (   asset_info.how_asset_found == asset_search::unsuccessful
+            || asset_info.how_asset_found == asset_search::something_wrong ) {
+            cerr << "\nError:  Tool-internal:  Please report error 108 to " << endl
+                 << "TF-Fuzz developers."
+                 << endl;
+            exit(108);
+        }
+    }
+    return found_asset;
+}
+
+sst_call::sst_call (tf_fuzz_info *test_state, long &call_ser_no,   // (constructor)
+                    asset_search how_asset_found)
+                        : psa_call(test_state, call_ser_no, how_asset_found)
+{
+    asset_info.the_asset = nullptr;
+    return;  // just to have something to pin a breakpoint onto
+}
+sst_call::~sst_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+/**********************************************************************************
+   End of methods of class sst_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class crypto_call follow:
+**********************************************************************************/
+
+/* calc_result_code() fills in the check_code string member with the correct
+   result code (e.g., "PSA_SUCCESS" or whatever).  This "modeling" needs to be
+   improved and expanded upon *massively* more or less mirroring what is seen in
+   .../test/suites/crypto/crypto_tests_common.c in the psa_key_interface_test()
+   method, (starting around line 20ish). */
+void crypto_call::calc_result_code (void)
+{
+    string formalized;  // "proper" result string
+
+    if (!exp_data.pf_nothing) {
+        if (exp_data.pf_pass) {
+            find_replace_all ("$expect",
+                              test_state->bplate->bplate_string[sst_pass_string],
+                              check_code);
+        } else if (exp_data.pf_fail) {
+            // Check for not-success:
+            find_replace_1st ("!=", "==",
+                              check_code);
+            find_replace_all ("$expect",
+                              test_state->bplate->bplate_string[sst_pass_string],
+                              check_code);
+            find_replace_1st ("expected ", "expected not ",
+                              check_code);
+        } else {
+            if (exp_data.pf_specified) {
+                formalized = formalize (exp_data.pf_result_string, "PSA_ERROR_");
+                find_replace_all ("$expect", formalized, check_code);
+            } else {
+                // Figure out what the message should read:
+                switch (asset_info.how_asset_found) {
+                    case asset_search::found_active:
+                    case asset_search::created_new:
+                        find_replace_all ("$expect",
+                                          test_state->bplate->
+                                              bplate_string[sst_pass_string],
+                                          check_code);
+                        break;
+                    case asset_search::not_found:
+                    case asset_search::found_deleted:
+                        find_replace_all ("$expect", "PSA_ERROR_INVALID_HANDLE",
+                                          check_code);  // TODO:  take from boilerplate
+                        break;
+                    default:
+                        find_replace_1st ("!=", "==",
+                                          check_code);  // like "fail", just make sure...
+                        find_replace_all ("$expect",
+                                          test_state->bplate->
+                                              bplate_string[sst_pass_string],
+                                          check_code);  // ... it's *not* PSA_SUCCESS
+                        break;
+                }
+            }
+        }
+    }
+}
+
+
+bool crypto_call::copy_asset_to_call (void)
+{
+    if (asset_info.the_asset == nullptr) {
+        return false;
+    } else {
+        // Get updated asset info from the asset:
+        asset_info.asset_ser_no = asset_info.the_asset->asset_info.asset_ser_no;
+        asset_info.id_n = asset_info.the_asset->asset_info.id_n;
+        exp_data.n_exp_vars = asset_info.the_asset->exp_data.n_exp_vars;
+        exp_data.data = asset_info.the_asset->exp_data.data;
+        return true;
+    }
+}
+
+
+crypto_call::crypto_call (tf_fuzz_info *test_state, long &call_ser_no,  // (constructor)
+                          asset_search how_asset_found)
+                             : psa_call(test_state, call_ser_no, how_asset_found)
+{
+    // Nothing further to initialize.
+    return;  // just to have something to pin a breakpoint onto
+}
+crypto_call::~crypto_call (void)
+{
+    // Nothing further to delete.
+    return;  // just to have something to pin a breakpoint onto
+}
+
+/**********************************************************************************
+   End of methods of class crypto_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class security_call follow:
+**********************************************************************************/
+
+security_call::security_call (tf_fuzz_info *test_state, long &call_ser_no,  // (constructor)
+                          asset_search how_asset_found)
+                             : psa_call(test_state, call_ser_no, how_asset_found)
+{
+    // Nothing further to initialize.
+    return;  // just to have something to pin a breakpoint onto
+}
+security_call::~security_call (void)
+{
+    // Nothing further to delete.
+    return;  // just to have something to pin a breakpoint onto
+}
+
+// resolve_asset() doesn't do anything for security_calls, since there's no asset involved.
+vector<psa_asset*>::iterator security_call::resolve_asset (bool create_asset_bool,
+                                                           psa_asset_usage where)
+{
+    return test_state->active_sst_asset.end();  // (anything)
+}
+
+/* calc_result_code() fills in the check_code string member with the correct result
+   code (e.g., "PSA_SUCCESS" or whatever).
+
+   Since there are no actual PSA calls associated with security calls (so far at least),
+   this should never be invoked. */
+void security_call::calc_result_code (void)
+{
+    // Currently should not be invoked.
+    cerr << "\nError:  Internal:  Please report error #205 to TF-Fuzz developers." << endl;
+    exit (205);
+}
+
+/**********************************************************************************
+   End of methods of class security_call.
+**********************************************************************************/
+
+
diff --git a/tf_fuzz/calls/psa_call.hpp b/tf_fuzz/calls/psa_call.hpp
new file mode 100644
index 0000000..ed66245
--- /dev/null
+++ b/tf_fuzz/calls/psa_call.hpp
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PSA_CALL_HPP
+#define PSA_CALL_HPP
+
+#include <string>
+
+/* This project's header files #including other project headers quickly becomes
+   unrealistically complicated.  The only solution is for each .cpp to include
+   the headers it needs.
+#include "tf_fuzz.hpp"
+*/
+
+
+using namespace std;
+
+class psa_call
+{
+public:
+    /* Data members -- not all PSA calls have/need these, but they need to be acces-
+       sible polymorphically via a psa_call iterator: */
+        string call_description;  // description of the call, just for tracing
+        expect_info exp_data;  // everything about expected results
+        set_data_info set_data;  // everything about setting PSA-asset-data values
+        asset_name_id_info asset_info;  // everything about the asset(s) for this line
+        key_policy_info policy;  // (specific to crypto, but have to put this here)
+        string asset_2_name;  // if there's a 2nd asset, then this is its name
+        string asset_3_name;  // if there's a 3rd asset, then this is its name
+        psa_asset_usage random_asset;
+            /* if asked to use some random asset from active or deleted, this says
+               which.  psa_asset_usage::all if not using this feature. */
+        bool assign_data_var_specified;  // asset data to/from named variable
+        string assign_data_var;  // name of variable to dump (assign) data into
+        // Expected-result info:
+        bool print_data;  // true to print asset data to test log
+        bool hash_data;  // true to hash data for later comparison
+        string id_string;  // not all PSA calls involve an ID, but a diverse set do
+        long call_ser_no;  // unique serial# for this psa_call (see note in tf_fuzz.hpp)
+        tf_fuzz_info *test_state;  // the big blob with pointers to everything going on
+        string barrier;
+            /* "barrier" is used for template-line operations that resolve a series of
+               PSA calls.  In particular, with respect to the fact that TF-Fuzz strives
+               to randomize these multiple calls where possible, meaning interspersing
+               them among other, earlier commands.  However, for example, calls to set
+               the aspects of a policy can't be pushed too far back, such as in among
+               calls setting that same policy for a previous operation!  "barrier" is
+               either "", in which case this call does not care whether you place calls
+               before it, or it contains the name of an asset that, calls related to
+               which must be placed *after* this call. */
+        string target_barrier;
+            /* asset to tell the psa_call objects to set and search barrier to when
+               re-ordering PSA calls.  For key policies, this is not necessarily the
+               nominal asset of that call.  For a policy call, it is that policy asset,
+               so that later re-settings of the same policy don't pollute the current
+               setting of that policy.  However, for key sets and reads, it is not the
+               key asset, but its policy. */
+    // Methods:
+        virtual vector<psa_asset*>::iterator resolve_asset (bool create_asset_bool,
+                                                            psa_asset_usage where) = 0;
+        virtual bool copy_call_to_asset (void) = 0;
+        virtual bool copy_asset_to_call (void) = 0;
+        virtual void fill_in_prep_code (void) = 0;
+        virtual void fill_in_command (void) = 0;
+        void write_out_prep_code (ofstream &test_file);
+        void write_out_command (ofstream &test_file);
+        void write_out_check_code (ofstream &test_file);
+        psa_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                  asset_search how_asset_found);  // (constructor)
+        ~psa_call (void);
+
+protected:
+    // Data members:
+        string prep_code;  // declarations and such prior to all of the calls
+        string call_code;  // for the call itself
+        string check_code;  // for the code to check success of the call
+        static long unique_id_counter;  // counts off unique IDs for assets
+    // Methods:
+        virtual void calc_result_code (void) = 0;
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+class sst_call : public psa_call
+{
+public:
+    // Data members:  // (low value in hiding these behind setters and getters)
+    // Methods:
+        vector<psa_asset*>::iterator resolve_asset (bool create_asset_bool,
+                                                    psa_asset_usage where);
+        sst_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                  asset_search how_asset_found);  // (constructor)
+        ~sst_call (void);
+
+protected:
+    // Data members:
+    // Methods:
+        void calc_result_code (void);
+
+private:
+    // Data members:
+    // Methods:
+};
+
+class crypto_call : public psa_call
+{
+public:
+    // Data members:  // (low value in hiding these behind setters and getters)
+    // Methods:
+        bool copy_asset_to_call (void);
+        crypto_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                    asset_search how_asset_found);  // (constructor)
+        ~crypto_call (void);
+
+protected:
+    // Data members:
+    // Methods:
+        void calc_result_code (void);
+           // for now, the method-overide buck stops here, but that'll probably change
+
+private:
+    // Data members:
+    // Methods:
+};
+
+class security_call : public psa_call
+   /* Strictly speaking, these don't really correspond to PSA calls, so it's a little
+      iffy to subclass them from psa_call.  However, the calling patterns work out
+      right. */
+{
+public:
+    // Data members:  // (low value in hiding these behind setters and getters)
+    // Methods:
+        vector<psa_asset*>::iterator resolve_asset (bool create_asset_bool,
+                                                    psa_asset_usage where);
+        security_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                       asset_search how_asset_found);  // (constructor)
+        ~security_call (void);
+
+protected:
+    // Data members:
+    // Methods:
+        void calc_result_code (void);
+           // Should never be invoked, since security calls generate no PSA calls.
+
+private:
+    // Data members:
+    // Methods:
+};
+
+#endif  // PSA_CALL_HPP
diff --git a/tf_fuzz/calls/psa_call.o b/tf_fuzz/calls/psa_call.o
new file mode 100644
index 0000000..7caabe5
--- /dev/null
+++ b/tf_fuzz/calls/psa_call.o
Binary files differ
diff --git a/tf_fuzz/calls/security_call.cpp b/tf_fuzz/calls/security_call.cpp
new file mode 100644
index 0000000..a99496a
--- /dev/null
+++ b/tf_fuzz/calls/security_call.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <cstdlib>
+
+#include "class_forwards.hpp"
+
+#include "boilerplate.hpp"
+#include "gibberish.hpp"
+#include "compute.hpp"
+#include "randomization.hpp"
+#include "string_ops.hpp"
+#include "data_blocks.hpp"
+#include "psa_asset.hpp"
+#include "find_or_create_asset.hpp"
+#include "template_line.hpp"
+#include "tf_fuzz.hpp"
+#include "crypto_asset.hpp"
+#include "psa_call.hpp"
+#include "security_call.hpp"
+#include "sst_asset.hpp"
+
+
+
+/**********************************************************************************
+   Methods of class hash_call follow:
+**********************************************************************************/
+
+hash_call::hash_call (tf_fuzz_info *test_state,    // (constructor)
+                          long &call_ser_no,
+                          asset_search how_asset_found)
+                             : security_call(test_state, call_ser_no, how_asset_found)
+{
+    call_description = "hash call";
+}
+hash_call::~hash_call (void)
+{
+    // Nothing further to delete.
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool hash_call::copy_call_to_asset (void)
+{
+    // The assets are not directly involved in this call.
+    return true;
+}
+
+bool hash_call::copy_asset_to_call (void)
+{
+    // The assets are not directly involved in this call.
+    return true;
+}
+
+/* Note:  These functions are overridden in all subclasses, but they still need to be
+          defined, or the linker gives the error "undefined reference to `vtable... */
+void hash_call::fill_in_prep_code (void)
+{
+    // No prep code for hash comparisons.
+}
+
+void hash_call::fill_in_command (void)
+{
+    if (asset_info.asset_name_vector.size() > 1) {  // nothing to compare with less than 2
+        // Fill in preceding comment:
+        // Fill in the hash-comparison code itself:
+        for (auto outer = asset_info.asset_name_vector.begin();
+             outer < asset_info.asset_name_vector.end();
+             ++outer) {
+            for (auto inner = outer+1;
+                 inner < asset_info.asset_name_vector.end();
+                 ++inner) {
+                call_code.append ("    if (  " + *outer + "_act_hash == " + *inner
+                                           + "_act_hash) {\n");
+                call_code.append (  "        TEST_FAIL(\"Probable data leak between assets "
+                                  + *outer + " and " + *inner + ".\\n\");\n");
+                call_code.append ("        return;\n");
+                call_code.append ("    }\n");
+                // TODO:  Pull this from boilerplate!!
+            }
+        }
+    } else {
+        call_code.assign ("    /* Cannot compare hashes;  only one asset specified. */\n");
+
+    }
+}
+
+/**********************************************************************************
+   End of methods of class hash_call.
+**********************************************************************************/
diff --git a/tf_fuzz/calls/security_call.hpp b/tf_fuzz/calls/security_call.hpp
new file mode 100644
index 0000000..e55a278
--- /dev/null
+++ b/tf_fuzz/calls/security_call.hpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef SECURITY_CALL_HPP
+#define SECURITY_CALL_HPP
+
+#include <string>
+#include <vector>
+
+/* This project's header files #including other project headers quickly becomes
+   unrealistically complicated.  The only solution is for each .cpp to include
+   the headers it needs. */
+
+
+using namespace std;
+
+class hash_call : public security_call
+{
+public:
+    // Data members:  // (low value in hiding these behind setters and getters)
+    // Methods:
+        bool copy_call_to_asset (void);
+        bool copy_asset_to_call (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        /* Hash checks are different from the rest in that there's a single "call" --
+           not a PSA call though -- for all of the assets cited in the template line.
+           In other cases, create a single call for each asset cited by the template
+           line, but in this case it's a single call for all of them. */
+        hash_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                    asset_search how_asset_found);  // (constructor)
+        ~hash_call (void);
+
+protected:
+    // Data members:
+    // Methods:
+//        void calc_result_code (void);  for *now* keep this in security_call::
+
+private:
+    // Data members:
+    // Methods:
+};
+
+#endif // #ifndef SECURITY_CALL_HPP
diff --git a/tf_fuzz/calls/security_call.o b/tf_fuzz/calls/security_call.o
new file mode 100644
index 0000000..5cfd78c
--- /dev/null
+++ b/tf_fuzz/calls/security_call.o
Binary files differ
diff --git a/tf_fuzz/calls/sst_call.cpp b/tf_fuzz/calls/sst_call.cpp
new file mode 100644
index 0000000..9aa7762
--- /dev/null
+++ b/tf_fuzz/calls/sst_call.cpp
@@ -0,0 +1,492 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "class_forwards.hpp"
+
+#include "boilerplate.hpp"
+#include "gibberish.hpp"
+#include "compute.hpp"
+#include "string_ops.hpp"
+#include "data_blocks.hpp"
+#include "psa_asset.hpp"
+#include "find_or_create_asset.hpp"
+#include "template_line.hpp"
+#include "tf_fuzz.hpp"
+#include "crypto_asset.hpp"
+#include "psa_call.hpp"
+#include "sst_call.hpp"
+#include "sst_asset.hpp"
+#include "crypto_asset.hpp"
+#include "variables.hpp"
+
+
+
+/**********************************************************************************
+   Methods of class sst_set_call follow:
+**********************************************************************************/
+
+sst_set_call::sst_set_call (tf_fuzz_info *test_state,    // (constructor)
+                            long &call_ser_no,
+                            asset_search how_asset_found)
+                                : sst_call(test_state, call_ser_no, how_asset_found)
+{
+    // Copy the boilerplate text into local buffers:
+    prep_code.assign ("");  // will fill in, depending upon template line content
+    call_code.assign (test_state->bplate->bplate_string[set_sst_call]);
+    check_code.assign (test_state->bplate->bplate_string[set_sst_check]);
+    call_description = "SST-set call";
+}
+sst_set_call::~sst_set_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool sst_set_call::copy_call_to_asset (void)
+{
+    vector<psa_asset*>::iterator found_asset;
+
+    found_asset = resolve_asset (yes_create_asset, psa_asset_usage::all);
+    // Copy over everything relevant:
+    if (asset_info.how_asset_found != asset_search::not_found) {
+        asset_info.the_asset = reinterpret_cast<sst_asset*>(*found_asset);
+            /* Note:  The vector is base-class, but the assets in this list
+                      themselves *really are* sst_asset-type objects. */
+        int i = asset_info.the_asset->set_data.n_set_vars;  // save this
+        asset_info.the_asset->set_data = set_data;  // TO DO:  does this make sense?!
+        asset_info.the_asset->set_data.n_set_vars = set_data.n_set_vars = ++i;
+        asset_info.the_asset->set_data.flags_string.assign (set_data.flags_string);
+        if (asset_info.how_asset_found == asset_search::created_new) {
+            asset_info.the_asset->asset_info.name_specified = asset_info.name_specified;
+            asset_info.the_asset->asset_info.set_name (asset_info.get_name());
+            asset_info.the_asset->asset_info.asset_ser_no = asset_info.asset_ser_no;
+            asset_info.the_asset->asset_info.id_n = asset_info.id_n;
+        }
+    }
+    return true;
+}
+
+bool sst_set_call::copy_asset_to_call (void)
+{
+    // Get updated asset info from the asset:
+    asset_info.asset_ser_no = asset_info.the_asset->asset_info.asset_ser_no;
+    asset_info.id_n = asset_info.the_asset->asset_info.id_n;
+    exp_data.n_exp_vars = asset_info.the_asset->exp_data.n_exp_vars;
+    exp_data.data = asset_info.the_asset->exp_data.data;
+    return true;
+}
+
+void sst_set_call::fill_in_prep_code (void)
+{
+    string var_name, length_var_name, var_name_suffix, length_var_name_suffix,
+           temp_string;
+    vector<variable_info>::iterator assign_variable;
+
+    if (assign_data_var_specified) {
+        var_name.assign (assign_data_var + "_data");
+        length_var_name.assign (assign_data_var + "_length");
+        /* If actual-data variable doesn't already exist, create variable tracker,
+           and write declaration for it: */
+        assign_variable = test_state->find_var (assign_data_var);
+        if (assign_variable == test_state->variable.end()) {
+            // No such variable exists, so:
+            test_state->make_var (assign_data_var);
+            assign_variable = test_state->find_var (assign_data_var);
+            prep_code.append (test_state->bplate->bplate_string[declare_big_string]);
+            find_replace_1st ("$var", var_name, prep_code);
+            temp_string = (char *) assign_variable->value;
+            find_replace_1st ("$init", temp_string, prep_code);
+            // Actual-data length:
+            prep_code.append (test_state->bplate->bplate_string[declare_size_t]);
+            find_replace_1st ("$var", length_var_name, prep_code);
+            find_replace_1st ("$init", to_string(temp_string.length()), prep_code);
+            // Offset (always 0 for now):
+            find_replace_1st ("$offset", "0", prep_code);
+        }
+    } else {
+        // Single string of two lines declaring string data and its length:
+        var_name_suffix = "_set_data";
+        length_var_name_suffix = "_set_length";
+        if (set_data.n_set_vars > 0) {
+            var_name_suffix += "_" + to_string(set_data.n_set_vars);
+            length_var_name_suffix += "_" + to_string(set_data.n_set_vars);
+            // We'll increment set_data.n_set_vars after we fill in the call itself.
+        }
+        var_name.assign (asset_info.get_name() + var_name_suffix);
+        length_var_name.assign (asset_info.get_name() + length_var_name_suffix);
+        prep_code = test_state->bplate->bplate_string[declare_string];
+        find_replace_1st ("$var", var_name, prep_code);
+        find_replace_1st ("$init", set_data.get(), prep_code);
+        temp_string.assign (test_state->bplate->bplate_string[declare_int]);
+        find_replace_1st ("static int", "static uint32_t", temp_string);
+        prep_code.append (temp_string);
+        find_replace_1st ("$var", length_var_name, prep_code);
+        find_replace_1st ("$init", to_string(set_data.get().length()), prep_code);
+    }
+}
+
+void sst_set_call::fill_in_command (void)
+{
+    string var_name, length_var_name, var_name_suffix, length_var_name_suffix,
+           temp_string;
+
+    // Fill in preceding comment:
+    if (asset_info.how_asset_found == asset_search::created_new) {
+        find_replace_1st ("$op", "Creating", call_code);
+    } else {
+        find_replace_1st ("$op", "Resetting", call_code);
+    }
+    if (asset_info.name_specified) {
+        find_replace_1st ("$description", "\"" + asset_info.get_name() + ",\"",
+                          call_code);
+    } else {
+        find_replace_1st ("$description",
+                          "UID = " + to_string((long) asset_info.id_n), call_code);
+    }
+    if (set_data.string_specified) {
+        find_replace_1st ("$data_source",
+                          "\"" + set_data.get().substr (0, 10) + "...\"",
+                          call_code);
+    } else if (set_data.file_specified) {
+        find_replace_1st ("$data_source", "from file " + set_data.file_path,
+                          call_code);
+    } else {
+        find_replace_1st (" $data_source", "", call_code);
+    }
+    // Fill in the PSA command itself:
+    if (assign_data_var_specified) {
+        var_name.assign (assign_data_var + "_data");
+        length_var_name.assign (assign_data_var + "_length");
+    } else {
+        var_name_suffix = "_set_data";
+        if (set_data.n_set_vars > 0) {
+            var_name_suffix += "_" + to_string(set_data.n_set_vars);
+        }
+        var_name.assign (asset_info.get_name() + var_name_suffix);
+        length_var_name_suffix = "_set_length";
+        if (set_data.n_set_vars > 0) {
+            length_var_name_suffix += "_" + to_string(set_data.n_set_vars);
+        }
+        length_var_name.assign (asset_info.get_name() + length_var_name_suffix);
+    }
+    find_replace_1st ("$data", var_name, call_code);
+    find_replace_1st ("$flags", set_data.flags_string, call_code);
+    string id_string = to_string((long) asset_info.id_n);
+    find_replace_1st ("$uid", id_string, call_code);
+    find_replace_1st ("$length", length_var_name, call_code);
+    // Figure out what expected results:
+    if (   set_data.flags_string == "PSA_STORAGE_FLAG_WRITE_ONCE"
+        && set_data.n_set_vars > 0) {
+        exp_data.pf_specified = true;
+        exp_data.pf_result_string = "PSA_ERROR_NOT_PERMITTED";
+    }
+    calc_result_code();
+}
+
+/**********************************************************************************
+   End of methods of class sst_set_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class sst_get_call follow:
+**********************************************************************************/
+
+sst_get_call::sst_get_call (tf_fuzz_info *test_state,    // (constructor)
+                            long &call_ser_no,
+                            asset_search how_asset_found)
+                                 : sst_call(test_state, call_ser_no, how_asset_found)
+{
+    // Copy the boilerplate text into local buffers:
+    prep_code.assign ("");
+    call_code.assign (test_state->bplate->bplate_string[get_sst_call]);
+    check_code.assign ("");
+        // depends upon the particular usage;  will get it in fill_in_command()
+    call_description = "SST-get call";
+}
+sst_get_call::~sst_get_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool sst_get_call::copy_call_to_asset (void)
+{
+    vector<psa_asset*>::iterator found_asset;
+
+    found_asset = resolve_asset (dont_create_asset, psa_asset_usage::active);
+    if (asset_info.how_asset_found != asset_search::not_found) {
+        // will be found for set calls, but not necessarily others
+        asset_info.the_asset = reinterpret_cast<sst_asset*>(*found_asset);
+           // Note:  Vector is of base-class type, but the assets *are* sst_asset.
+        /* Locating the asset is all we need to do here;  copy_asset_to_call() will
+           do the rest. */
+    }
+    return true;
+    // TODO:  Shouldn't data be copied over?
+}
+
+bool sst_get_call::copy_asset_to_call (void)
+{
+    if (asset_info.the_asset != nullptr) {
+        // will be found for set calls, but not necessarily others
+        set_data.string_specified = asset_info.the_asset->set_data.string_specified;
+        set_data.file_specified = asset_info.the_asset->set_data.file_specified;
+        set_data.set (asset_info.the_asset->set_data.get());
+        set_data.flags_string = asset_info.the_asset->set_data.flags_string;
+        asset_info.id_n = asset_info.the_asset->asset_info.id_n;
+        asset_info.asset_ser_no = asset_info.the_asset->asset_info.asset_ser_no;
+        asset_info.name_specified = asset_info.the_asset->asset_info.name_specified;
+        asset_info.the_asset->exp_data.n_exp_vars++;
+        exp_data.n_exp_vars = asset_info.the_asset->exp_data.n_exp_vars;
+    }
+    return true;
+}
+
+void sst_get_call::fill_in_prep_code (void)
+{
+    string var_base, var_name, length_var_name, temp_string, var_name_suffix,
+           expected;
+    vector<variable_info>::iterator act_variable, exp_variable;
+
+    if (!(print_data || hash_data)) {
+        // Checking asset data verbatim against expected, so:
+        if (exp_data.data_var_specified) {
+            // Template specified a variable name to "check" against;  use that:
+            var_base.assign (exp_data.data_var);
+            exp_variable = test_state->find_var (var_base);
+            if (exp_variable == test_state->variable.end()) {
+                test_state->make_var (var_base);
+                exp_variable = test_state->find_var (var_base);
+                var_name = var_base + "_data";
+                prep_code.append (test_state->bplate->bplate_string[declare_string]);
+                find_replace_1st ("$var", var_name, prep_code);
+                temp_string = (char *) exp_variable->value;
+                find_replace_1st ("$init", temp_string, prep_code);
+                // Expected-data length:
+                temp_string.assign (test_state->bplate->bplate_string[declare_int]);
+                find_replace_1st ("static int", "static size_t", temp_string);
+            }
+        } else {
+            if (exp_data.data_specified) {
+                // Checking against literal expected data:
+                expected.assign (exp_data.data);
+            } else {
+                // Check against what we believe the asset to contain:
+                expected.assign (set_data.get());
+            }
+            var_name_suffix = "_exp_data";
+            if (exp_data.n_exp_vars > 0) {
+                var_name_suffix =
+                    var_name_suffix + "_" + to_string(exp_data.n_exp_vars);
+            }
+            var_name.assign (asset_info.get_name() + var_name_suffix);
+            prep_code.assign(test_state->bplate->bplate_string[declare_string]);
+            find_replace_1st("$var", var_name, prep_code);
+            find_replace_1st("$init", expected, prep_code);
+        }
+    }
+    // Actual data:
+    if (assign_data_var_specified) {
+        var_base.assign (assign_data_var);
+    } else {
+        var_base.assign (asset_info.get_name() + "_act");
+    }
+    var_name.assign (var_base + "_data");
+    length_var_name.assign (var_base + "_length");
+    /* If actual-data variable doesn't already exist, create variable tracker,
+       and write declaration for it: */
+    act_variable = test_state->find_var (var_base);
+    if (act_variable == test_state->variable.end()) {
+        test_state->make_var (var_base);
+        act_variable = test_state->find_var (var_base);
+        prep_code.append (test_state->bplate->bplate_string[declare_big_string]);
+        find_replace_1st ("$var", var_name, prep_code);
+        temp_string = (char *) act_variable->value;
+        find_replace_1st ("$init", temp_string, prep_code);
+        // Actual-data length:
+        temp_string.assign (test_state->bplate->bplate_string[declare_int]);
+        find_replace_1st ("static int", "static size_t", temp_string);
+        prep_code.append (temp_string);
+        find_replace_1st ("$var", length_var_name, prep_code);
+        find_replace_1st ("$init", to_string(temp_string.length()), prep_code);
+        // Offset (always 0 for now):
+        find_replace_1st ("$offset", "0", prep_code);
+    }
+    // If hashing the (actual) data, then create a variable for that:
+    if (hash_data && !act_variable->hash_declared) {
+        var_name = var_base + "_hash";
+        prep_code.append (test_state->bplate->bplate_string[declare_generic]);
+            // where to put the hash of the data
+        find_replace_1st ("$type", "uint32_t", prep_code);
+        find_replace_1st ("$var", var_name, prep_code);
+        find_replace_1st ("$init", "0", prep_code);  // for now...
+        act_variable->hash_declared = true;
+    }
+}
+
+void sst_get_call::fill_in_command (void)
+{
+    string exp_var_name, act_var_name, act_data_length, hash_var_name,
+    id_string, var_name_suffix;
+
+/* TODO:  Flesh-out/fix this (it was a good try/start, but not quite right):
+    // Fill in preceding comment:
+    if (asset_info.how_asset_found == asset_search::created_new) {
+        find_replace_1st ("$op", "Creating", call_code);
+    } else {
+        find_replace_1st ("$op", "Resetting", call_code);
+    }
+    if (asset_info.name_specified) {
+        find_replace_1st ("$description", "\"" + asset_info.get_name() + ",\"",
+                          call_code);
+    } else {
+        find_replace_1st ("$description",
+                          "UID = " + to_string((long) asset_info.id_n), call_code);
+    }
+    if (set_data.string_specified) {
+        find_replace_1st ("$data_source",
+                          "\"" + data.substr (0, 10) + "...\"",
+                          call_code);
+    } else if (set_data.file_specified) {
+        find_replace_1st ("$data_source", "from file " + set_data.file_path,
+                          call_code);
+    } else {
+        find_replace_1st (" $data_source", "", call_code);
+    }
+*/    // Fill in the call itself:
+    if (print_data || hash_data) {
+        // Dump to variable;  no data-check code needed:
+        check_code.assign (test_state->bplate->bplate_string[get_sst_check]);
+    } else {
+        // Check either against literal or variable, so need data-check code too:
+        check_code.assign (test_state->bplate->bplate_string[get_sst_check_all]);
+    }
+    /* Note:  Can fill in the check code identically between the dump-to-variable
+              and check-data cases, because the boilerplate for the former is just an
+              abbreviated version of the latter.  The find_replace_1st() calls for
+              the check-data stuff will just simply not have any effect. */
+    if (exp_data.data_var_specified) {
+        // Check against data in variable:
+        exp_var_name.assign (exp_data.data_var + "_data");
+    } else {
+        var_name_suffix = "_exp_data";
+        if (exp_data.n_exp_vars > 0) {
+            var_name_suffix =
+                var_name_suffix + "_" + to_string(exp_data.n_exp_vars);
+        }
+        exp_var_name.assign (asset_info.get_name() + var_name_suffix);
+    }
+    if (assign_data_var_specified) {
+        act_var_name.assign (assign_data_var + "_data");
+        act_data_length.assign (assign_data_var + "_length");
+    } else {
+        act_var_name.assign (asset_info.get_name() + "_act_data");
+        act_data_length.assign (asset_info.get_name() + "_act_length");
+    }
+
+    id_string = to_string((long) asset_info.id_n);
+    // Fill in the PSA command itself:
+    find_replace_1st ("$uid", id_string, call_code);
+    find_replace_all ("$length", to_string(set_data.get().length()), call_code);
+    find_replace_1st ("$offset", to_string(set_data.data_offset), call_code);
+    find_replace_1st ("$exp_data", exp_var_name, call_code);
+    find_replace_all ("$act_data", act_var_name, call_code);
+    find_replace_all ("$act_length", act_data_length, call_code);
+    // Perform most of the same substitutions in the check_code:
+// TODO:  Make data checks contingent upon the PSA call itself passing?
+    find_replace_1st ("$offset", "0", check_code);
+    find_replace_1st ("$exp_data", exp_var_name, check_code);
+    find_replace_all ("$act_data", act_var_name, check_code);
+    find_replace_all ("$length", act_data_length, check_code);
+    if (print_data) {
+        check_code.append (test_state->bplate->bplate_string[test_log]);
+        find_replace_1st ("$message", act_var_name, check_code);
+    }
+    if (hash_data) {
+        hash_var_name.assign (asset_info.get_name() + "_act_hash");
+            // this is where to put the hash of the data
+        check_code.append (test_state->bplate->bplate_string[get_sst_hash]);
+        find_replace_all ("$act_data_var", act_var_name, check_code);
+        find_replace_all ("$hash_var", hash_var_name, check_code);
+    }
+    // Figure out what expected results:
+    calc_result_code();  // this only fills $expect check_code
+    // Fill in expected data, actual data, and length:
+}
+
+/**********************************************************************************
+   End of methods of class sst_get_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class sst_remove_call follow:
+**********************************************************************************/
+
+sst_remove_call::sst_remove_call (tf_fuzz_info *test_state,    // (constructor)
+                                  long &call_ser_no,
+                                  asset_search how_asset_found)
+                                 : sst_call(test_state, call_ser_no, how_asset_found)
+{
+    // Copy the boilerplate text into local buffers:
+    prep_code.assign ("");
+    call_code.assign (test_state->bplate->bplate_string[remove_sst]);
+    check_code.assign (test_state->bplate->bplate_string[remove_sst_check]);
+    call_description = "SST-remove call";
+}
+sst_remove_call::~sst_remove_call (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+bool sst_remove_call::copy_call_to_asset (void)
+{
+    vector<psa_asset*>::iterator found_asset;
+
+    found_asset = resolve_asset (dont_create_asset, psa_asset_usage::all);
+    if (asset_info.how_asset_found != asset_search::not_found) {
+        asset_info.the_asset = reinterpret_cast<sst_asset*>(*found_asset);
+           // Note:  Vector is of base-class type, but the assets *are* sst_asset.
+        if (asset_info.how_asset_found == asset_search::found_active) {
+            // Delete asset;  move it from active vector to deleted vector:
+            test_state->deleted_sst_asset.push_back (asset_info.the_asset);
+            test_state->active_sst_asset.erase (found_asset);
+        }  /* if not active, we'll deem the call expected to fail. */
+    }
+    return true;
+}
+
+bool sst_remove_call::copy_asset_to_call (void)
+{
+    if (asset_info.the_asset != nullptr) {
+        set_data.string_specified = asset_info.the_asset->set_data.string_specified;
+        set_data.file_specified = asset_info.the_asset->set_data.file_specified;
+        set_data.flags_string = asset_info.the_asset->set_data.flags_string;
+        asset_info.id_n = asset_info.the_asset->asset_info.id_n;
+        asset_info.name_specified = asset_info.the_asset->asset_info.name_specified;
+    }
+    return true;
+}
+
+void sst_remove_call::fill_in_prep_code (void)
+{
+    // No prep-code.
+    return;  // just to have something to pin a breakpoint onto
+}
+
+void sst_remove_call::fill_in_command (void)
+{
+    // Fill in the call:
+    string id_string = to_string((long) asset_info.id_n);
+    find_replace_1st ("$uid", id_string, call_code);
+    // Fill in expected results:
+    calc_result_code();  // this only fills $expect check_code
+}
+
+/**********************************************************************************
+   End of methods of class sst_remove_call.
+**********************************************************************************/
+
diff --git a/tf_fuzz/calls/sst_call.hpp b/tf_fuzz/calls/sst_call.hpp
new file mode 100644
index 0000000..537b21f
--- /dev/null
+++ b/tf_fuzz/calls/sst_call.hpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef SST_CALL_HPP
+#define SST_CALL_HPP
+
+#include <string>
+#include <vector>
+#include <cstdint>
+
+/* This project's header files #including other project headers quickly becomes
+   unrealistically complicated.  The only solution is for each .cpp to include
+   the headers it needs.
+#include "sst_asset.hpp"
+#include "psa_call.hpp"
+*/
+
+
+using namespace std;
+
+class sst_set_call : public sst_call
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_call_to_asset (void);
+        bool copy_asset_to_call (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        sst_set_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                      asset_search how_asset_found);  // (constructor)
+        ~sst_set_call (void);
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+class sst_get_call : public sst_call
+{
+public:
+    // Data members:
+        uint32_t offset;
+        uint32_t data_length;
+        string data_var_name;
+    // Methods:
+        bool copy_call_to_asset (void);
+        bool copy_asset_to_call (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        sst_get_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                      asset_search how_asset_found);  // (constructor)
+        ~sst_get_call (void);
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+class sst_remove_call : public sst_call
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_call_to_asset (void);
+        bool copy_asset_to_call (void);
+        void fill_in_prep_code (void);
+        void fill_in_command (void);
+        sst_remove_call (tf_fuzz_info *test_state, long &asset_ser_no,
+                      asset_search how_asset_found);  // (constructor)
+        ~sst_remove_call (void);
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+#endif  // SST_CALL_HPP
+
diff --git a/tf_fuzz/calls/sst_call.o b/tf_fuzz/calls/sst_call.o
new file mode 100644
index 0000000..8b92b0d
--- /dev/null
+++ b/tf_fuzz/calls/sst_call.o
Binary files differ
diff --git a/tf_fuzz/class_forwards.hpp b/tf_fuzz/class_forwards.hpp
new file mode 100644
index 0000000..6099fbe
--- /dev/null
+++ b/tf_fuzz/class_forwards.hpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/* The .hpp files in this project being so self-referential, this file forward-
+   declares all classes before any are attempted to be used. */
+
+#ifndef CLASS_FORWARDS_HPP
+#define CLASS_FORWARDS_HPP
+
+using namespace std;
+
+// find_or_create_asset.hpp:
+enum class asset_search;
+enum class psa_asset_usage;
+enum class psa_asset_search;
+enum class psa_asset_type;
+
+// data_blocks.hpp:
+class expect_info;
+class set_data_info;
+class asset_name_id_info;
+
+// variables.hpp:
+class variable_info;
+
+// template_line.hpp:
+class template_line;
+class sst_template_line;
+class key_template_line;
+class policy_template_line;
+
+// sst_template_line.hpp:
+class set_sst_template_line;
+class remove_sst_template_line;
+class read_sst_template_line;
+
+// crypto_template_line.hpp:
+class set_key_template_line;
+class remove_key_template_line;
+class read_key_template_line;
+class set_policy_template_line;
+class read_policy_template_line;
+
+// security.hpp:
+class security;
+class security_hash;
+
+// psa_call.hpp:
+class psa_call;
+class sst_call;
+class crypto_call;
+
+// sst_call.hpp:
+class sst_set_call;
+class sst_get_call;
+class sst_remove_call;
+
+// crypto_call.hpp:
+class policy_call;
+class key_call;
+class init_policy_call;
+class reset_policy_call;
+class set_policy_usage_call;
+class add_policy_usage_call;
+class set_policy_lifetime_call;
+class set_policy_algorithm_call;
+class set_policy_size_call;
+class set_policy_type_call;
+class get_policy_lifetime_call;
+class get_policy_size_call;
+class get_policy_type_call;
+class get_policy_algorithm_call;
+class get_policy_usage_call;
+class print_policy_usage_call;
+class get_key_policy_call;
+class generate_key_call;
+class create_key_call;
+class copy_key_call;
+class read_key_data_call;
+class remove_key_call;
+
+
+// ************************    INSERT THE NEW STUFF HERE!!
+
+
+class destroy_key_call;
+
+// psa_asset.hpp:
+class psa_asset;
+
+// sst_asset.hpp:
+class sst_asset;
+
+// crypto_asset.hpp:
+class crypto_asset;
+class key_asset;
+class policy_asset;
+class key_asset;
+
+// boilerplate.hpp"
+//enum class boilerplate_texts;  not really a "class," and no need to forward-reference it anyway
+class boilerplate;
+
+// gibberish.hpp:
+class gibberish;
+
+// tf_fuzz.hpp:
+class tf_fuzz_info;
+
+#endif  // #ifndef CLASS_FORWARDS_HPP
diff --git a/tf_fuzz/demo/1 b/tf_fuzz/demo/1
new file mode 100644
index 0000000..7b84f11
--- /dev/null
+++ b/tf_fuzz/demo/1
@@ -0,0 +1,2 @@
+purpose to create an SST asset;
+set sst uid 104 data "Very simple test" expect pass;
diff --git a/tf_fuzz/demo/10 b/tf_fuzz/demo/10
new file mode 100644
index 0000000..3e70099
--- /dev/null
+++ b/tf_fuzz/demo/10
@@ -0,0 +1,2 @@
+purpose to show what happens when you 'read' a non-existent asset;
+read sst name napoleon check "this won't work";
diff --git a/tf_fuzz/demo/11 b/tf_fuzz/demo/11
new file mode 100644
index 0000000..5fdd0fc
--- /dev/null
+++ b/tf_fuzz/demo/11
@@ -0,0 +1,2 @@
+purpose to illustrate that you can override TF-Fuzz's expected result;
+read sst name napoleon check "this won't work" expect pass;
diff --git a/tf_fuzz/demo/12 b/tf_fuzz/demo/12
new file mode 100644
index 0000000..c7825c5
--- /dev/null
+++ b/tf_fuzz/demo/12
@@ -0,0 +1,2 @@
+purpose to more-specifically override TF-Fuzz's expected result;
+read sst name napoleon check "this won't work" expect PSA_ERROR_GENERIC_ERROR;
diff --git a/tf_fuzz/demo/12.5 b/tf_fuzz/demo/12.5
new file mode 100644
index 0000000..2e7004b
--- /dev/null
+++ b/tf_fuzz/demo/12.5
@@ -0,0 +1,2 @@
+purpose to more-specifically override TF-Fuzz's expected result;
+read sst name napoleon check "this won't work" expect generic_error;
diff --git a/tf_fuzz/demo/13 b/tf_fuzz/demo/13
new file mode 100644
index 0000000..7edb72e
--- /dev/null
+++ b/tf_fuzz/demo/13
@@ -0,0 +1,4 @@
+purpose to illustrate deleting assets;
+set sst name george data *;
+remove sst name george;
+rm sst name george;
diff --git a/tf_fuzz/demo/14 b/tf_fuzz/demo/14
new file mode 100644
index 0000000..5b9485c
--- /dev/null
+++ b/tf_fuzz/demo/14
@@ -0,0 +1,3 @@
+purpose to remove something that doesn't exist;
+set sst name george data *;
+remove sst name ringo;
diff --git a/tf_fuzz/demo/15 b/tf_fuzz/demo/15
new file mode 100644
index 0000000..613439e
--- /dev/null
+++ b/tf_fuzz/demo/15
@@ -0,0 +1,3 @@
+purpose to show a more-interesting removal case;
+set sst name president george herbert walker bush data "read my lips";
+remove sst *active;  // remove *some* active asset
diff --git a/tf_fuzz/demo/16 b/tf_fuzz/demo/16
new file mode 100644
index 0000000..528a0ec
--- /dev/null
+++ b/tf_fuzz/demo/16
@@ -0,0 +1,6 @@
+purpose to show a more-interesting removal case;
+set sst name president george herbert walker bush data "no new taxes";
+remove sst *active;  // remove *some* active asset
+rm sst *active;  // remove *some other* active asset
+remove sst *act;  // remove *yet another* active asset
+rm sst *del;  // attempt to remove some asset that's already been removed
diff --git a/tf_fuzz/demo/17 b/tf_fuzz/demo/17
new file mode 100644
index 0000000..bdaeece
--- /dev/null
+++ b/tf_fuzz/demo/17
@@ -0,0 +1,8 @@
+purpose to try some more-complex randomization;
+set sst name neil buzz mike data *;
+2 to 5 of {
+    set sst name neil data "that's one small step for [a] man";
+    remove sst *active;
+    set sst name chris kraft data "wear the helmet";
+    remove sst name neil;
+}
diff --git a/tf_fuzz/demo/18 b/tf_fuzz/demo/18
new file mode 100644
index 0000000..f71335e
--- /dev/null
+++ b/tf_fuzz/demo/18
@@ -0,0 +1,9 @@
+purpose to shuffle the deck;
+set sst name Shiva Brahma Vishnu Ganapati data *;
+shuffle {
+    remove sst *active;
+    set sst name Brahma data "I am the creator";
+    set sst name Shiva data "I am the destroyer";
+    set sst name Vishnu data "I am the sustainer";
+    remove sst name Ganapati;
+}
diff --git a/tf_fuzz/demo/19 b/tf_fuzz/demo/19
new file mode 100644
index 0000000..173c45d
--- /dev/null
+++ b/tf_fuzz/demo/19
@@ -0,0 +1,4 @@
+purpose to show the early beginnings of security testing;
+set sst name charles babbage ada lovelace analytic engine alan turing bomb eniac edvac data *;
+read sst name charles babbage ada lovelace analytic engine alan turing bomb eniac edvac hash;
+secure hash neq charles babbage ada lovelace analytic engine alan turing bomb eniac edvac;
diff --git a/tf_fuzz/demo/2 b/tf_fuzz/demo/2
new file mode 100644
index 0000000..9af02c6
--- /dev/null
+++ b/tf_fuzz/demo/2
@@ -0,0 +1,2 @@
+purpose to give assets a human name;
+set sst name forecast data "cloudy with a 20% chance of weather" expect nothing;
diff --git a/tf_fuzz/demo/20 b/tf_fuzz/demo/20
new file mode 100644
index 0000000..6fda99a
--- /dev/null
+++ b/tf_fuzz/demo/20
@@ -0,0 +1,14 @@
+purpose to show that pretty short templates can produce a whole lot of varying test code;
+set sst name charles babbage ada lovelace alan turing bomb eniac edvac data *;
+read sst name charles babbage ada lovelace alan turing bomb eniac edvac hash;
+secure hash neq charles babbage ada lovelace alan turing bomb eniac edvac;
+remove sst *active;
+5 to 10 of {
+    set sst name * data *;
+    remove sst *active;
+    set sst name babbles charage data "I'm confused!";
+    set sst name alace adlove data "wait, something's still not right here...";
+    remove sst name turing;
+    set sst name charles babbage data "that's better";
+    remove sst *deleted;
+}
diff --git a/tf_fuzz/demo/21 b/tf_fuzz/demo/21
new file mode 100644
index 0000000..8a609e2
--- /dev/null
+++ b/tf_fuzz/demo/21
@@ -0,0 +1,2 @@
+purpose to define a policy mostly-default (random) policy;
+set policy name nothingMuch attr export volatile;
diff --git a/tf_fuzz/demo/22 b/tf_fuzz/demo/22
new file mode 100644
index 0000000..fba0d53
--- /dev/null
+++ b/tf_fuzz/demo/22
@@ -0,0 +1,2 @@
+purpose to create a policy with random name, with type and algorithm using abbreviated keywords;
+set policy name * type rsa_public_key alg rsa_pss_base;
diff --git a/tf_fuzz/demo/23 b/tf_fuzz/demo/23
new file mode 100644
index 0000000..deb35b2
--- /dev/null
+++ b/tf_fuzz/demo/23
@@ -0,0 +1,2 @@
+purpose to create multiple policies with attributes including key size (523);
+set policy name aPolicy anotherPolicy yetAnother alg sha_256 attr 523 noexport;
diff --git a/tf_fuzz/demo/24 b/tf_fuzz/demo/24
new file mode 100644
index 0000000..dddc8f3
--- /dev/null
+++ b/tf_fuzz/demo/24
@@ -0,0 +1,3 @@
+purpose to create a default (random) policy and then print it to the log;
+set policy name randomPolicy;
+read policy name randomPolicy print;
diff --git a/tf_fuzz/demo/25 b/tf_fuzz/demo/25
new file mode 100644
index 0000000..912019c
--- /dev/null
+++ b/tf_fuzz/demo/25
@@ -0,0 +1,3 @@
+purpose to create a default (random) policy and create a key using it (no key material specified);
+set policy name randomPolicy;
+set key name akey policy randomPolicy;
diff --git a/tf_fuzz/demo/26 b/tf_fuzz/demo/26
new file mode 100644
index 0000000..9093bd1
--- /dev/null
+++ b/tf_fuzz/demo/26
@@ -0,0 +1,4 @@
+purpose to create a default (random) policy and create a key using it (random key data specified), then copy that key with another random policy;
+set policy name randomPolicy anotherPolicy;
+set key name aKey policy randomPolicy data *;
+set key name aNewKey from aKey policy anotherPolicy;
diff --git a/tf_fuzz/demo/27 b/tf_fuzz/demo/27
new file mode 100644
index 0000000..76a62c8
--- /dev/null
+++ b/tf_fuzz/demo/27
@@ -0,0 +1,4 @@
+purpose to do the same sort of things as #26, but change around operands;
+set policy name randomPolicy anotherPolicy;
+set key name aKey data * policy randomPolicy;
+set key name aNewKey from *active policy anotherPolicy;
diff --git a/tf_fuzz/demo/28 b/tf_fuzz/demo/28
new file mode 100644
index 0000000..e9fd0d8
--- /dev/null
+++ b/tf_fuzz/demo/28
@@ -0,0 +1,4 @@
+purpose to create a key, then read the key data ("material") into a variable;
+set policy name somePolicy alg sha3_224 attr noexport volatile;
+set key name aKey data * policy somePolicy;
+read key name aKey var keyDataVar;
diff --git a/tf_fuzz/demo/29 b/tf_fuzz/demo/29
new file mode 100644
index 0000000..072b30d
--- /dev/null
+++ b/tf_fuzz/demo/29
@@ -0,0 +1,4 @@
+purpose to create a key, then read the key data ("material") into a variable;
+set policy name somePolicy attr copy decrypt persistent alg xts;
+set key name aKey data * policy somePolicy;
+read key name aKey check keyDataVar expect fail;
diff --git a/tf_fuzz/demo/3 b/tf_fuzz/demo/3
new file mode 100644
index 0000000..8f41603
--- /dev/null
+++ b/tf_fuzz/demo/3
@@ -0,0 +1,2 @@
+purpose to show that TF-Fuzz can infer results;
+set sst name john data "Take a holiday in Spain";
diff --git a/tf_fuzz/demo/30 b/tf_fuzz/demo/30
new file mode 100644
index 0000000..47ebe4c
--- /dev/null
+++ b/tf_fuzz/demo/30
@@ -0,0 +1,4 @@
+purpose to create a key, then read the key data ("material") into a variable;
+set policy name somePolicy alg rsa_pkcs1v15_sign_base attr derive noverify;
+set key name aKey data * policy somePolicy;
+read key name aKey check "12345678" expect fail;
diff --git a/tf_fuzz/demo/31 b/tf_fuzz/demo/31
new file mode 100644
index 0000000..18039a0
--- /dev/null
+++ b/tf_fuzz/demo/31
@@ -0,0 +1,4 @@
+purpose to create a key, then read the key data ("material") into a variable;
+set policy name somePolicy attr sign verify copy alg arc4;
+set key name aKey data * policy somePolicy;
+read key name aKey print;
diff --git a/tf_fuzz/demo/32 b/tf_fuzz/demo/32
new file mode 100644
index 0000000..533fcf5
--- /dev/null
+++ b/tf_fuzz/demo/32
@@ -0,0 +1,4 @@
+purpose to create then remove a key;
+set policy name somePolicy attr sign verify copy alg arc4;
+set key name aKey data * policy somePolicy;
+remove key name aKey;
diff --git a/tf_fuzz/demo/33 b/tf_fuzz/demo/33
new file mode 100644
index 0000000..5cfa287
--- /dev/null
+++ b/tf_fuzz/demo/33
@@ -0,0 +1,6 @@
+purpose to set SST creation flags;
+set sst name hasCF data "this asset has write-once" flag write_once;
+set sst name hasCF2 data "this asset has also write-once" flag wo;
+set sst name alsoHasCF data "this asset has no flags" flag none expect pass;
+set sst name alsoHasCF2 data "this asset has NO_CONFIDENTIALITY" flag ncf;
+set sst name yetAnother data "this asset has NO_REPLAY_PROTECTION" flag nrp;
diff --git a/tf_fuzz/demo/34 b/tf_fuzz/demo/34
new file mode 100644
index 0000000..9fa46e9
--- /dev/null
+++ b/tf_fuzz/demo/34
@@ -0,0 +1,3 @@
+purpose to set an offset on psa_ps_get();
+set sst name whoNose data *;
+read sst name whoNose print offset 10;
diff --git a/tf_fuzz/demo/35 b/tf_fuzz/demo/35
new file mode 100644
index 0000000..60fc978
--- /dev/null
+++ b/tf_fuzz/demo/35
@@ -0,0 +1,4 @@
+purpose to verify we can't write multiple times to a write-once SST asset;
+set sst name writeOnce data * flag wo;
+set sst name writeOnce data *;
+set sst name writeOnce data *;
diff --git a/tf_fuzz/demo/4 b/tf_fuzz/demo/4
new file mode 100644
index 0000000..912c23a
--- /dev/null
+++ b/tf_fuzz/demo/4
@@ -0,0 +1,2 @@
+purpose to show how to randomize data;
+set sst name gibberish data *;
diff --git a/tf_fuzz/demo/5 b/tf_fuzz/demo/5
new file mode 100644
index 0000000..5290f27
--- /dev/null
+++ b/tf_fuzz/demo/5
@@ -0,0 +1,2 @@
+purpose to show how to randomize name and data;
+set sst name * data *;
diff --git a/tf_fuzz/demo/6 b/tf_fuzz/demo/6
new file mode 100644
index 0000000..2e86d75
--- /dev/null
+++ b/tf_fuzz/demo/6
@@ -0,0 +1,2 @@
+purpose to show a nice party trick;
+set sst name john paul george and ringo data *;
diff --git a/tf_fuzz/demo/7 b/tf_fuzz/demo/7
new file mode 100644
index 0000000..903027e
--- /dev/null
+++ b/tf_fuzz/demo/7
@@ -0,0 +1,2 @@
+purpose same with UIDs;
+set sst uid 17 19 24 31 34 41 data *;
diff --git a/tf_fuzz/demo/8 b/tf_fuzz/demo/8
new file mode 100644
index 0000000..03b22d9
--- /dev/null
+++ b/tf_fuzz/demo/8
@@ -0,0 +1,3 @@
+purpose to create and show an asset;
+set sst name snortwaggle data *;
+read sst name snortwaggle check "almost certainly not *this*" expect fail;
diff --git a/tf_fuzz/demo/9 b/tf_fuzz/demo/9
new file mode 100644
index 0000000..72cc269
--- /dev/null
+++ b/tf_fuzz/demo/9
@@ -0,0 +1,4 @@
+purpose to dump to a variable or to the log;
+set sst name greebledorf data *;
+read sst name greebledorf check a_variable;
+read sst name greebledorf print;
diff --git a/tf_fuzz/demo/README b/tf_fuzz/demo/README
new file mode 100644
index 0000000..4dc4bbe
--- /dev/null
+++ b/tf_fuzz/demo/README
@@ -0,0 +1,10 @@
+This directory contains some example usages of TF-Fuzz, in a form that makes it
+easy to run each case and quickly see the results.
+
+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/demo_dir.html
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/demo/chkgcc b/tf_fuzz/demo/chkgcc
new file mode 100644
index 0000000..fff9770
--- /dev/null
+++ b/tf_fuzz/demo/chkgcc
@@ -0,0 +1,14 @@
+echo
+echo "Check-compiling..."
+echo
+gcc -I../../../../trusted-firmware-m-backup/test/suites/sst \
+    -I../../../../trusted-firmware-m-backup/interface/include \
+    -I../../../../trusted-firmware-m-backup \
+    -I../../../../trusted-firmware-m-backup/test/suites/crypto \
+    -I../../../secure_fw/spm/include \
+    -I../../../../CMSIS_5/CMSIS/Core/Include \
+    -Werror -Wunused-variable \
+    -c tossThis.c
+echo
+echo "Check-compile complete."
+echo
diff --git a/tf_fuzz/demo/r b/tf_fuzz/demo/r
new file mode 100644
index 0000000..d9b8978
--- /dev/null
+++ b/tf_fuzz/demo/r
@@ -0,0 +1,18 @@
+#!/usr/bin/bash
+# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+clear
+cat $1
+#sleep 5
+echo
+echo
+echo
+echo
+echo
+echo
+echo --------------------------------------------------
+echo
+echo $ ../tfz -v $1 tossThis.c
+../tfz -v $1 tossThis.c
diff --git a/tf_fuzz/docs/asset_dir.rst b/tf_fuzz/docs/asset_dir.rst
new file mode 100644
index 0000000..4eb358d
--- /dev/null
+++ b/tf_fuzz/docs/asset_dir.rst
@@ -0,0 +1,30 @@
+########################
+'assets'-directory guide
+########################
+
+************
+Introduction
+************
+
+This directory contains C++ header and program files for classes of objects that
+track PSA assets, while generating a directed-random test.  Notably this is
+during the Simulate phase, after Parse phase, which parses the test-template
+file, and prior to writing out the generated C code.
+
+***********************************************
+``.../tools/tf_fuzz/assets`` directory contents
+***********************************************
+.. code-block:: bash
+
+    crypto_asset.cpp  psa_asset.cpp  sst_asset.cpp
+    crypto_asset.hpp  psa_asset.hpp  sst_asset.hpp
+
+These hold current state of those assets as the run is simulated, after the
+exact sequence of PSA commands to be executed is generated by the Parse stage.
+Simulation only occurs to a level of detail of being able to predict pass/fail
+status, and asset data.  Generally speaking, it does not simulate
+secure-partition code.
+
+--------------
+
+*Copyright (c) 2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/docs/boilerplate_dir.rst b/tf_fuzz/docs/boilerplate_dir.rst
new file mode 100644
index 0000000..d4aea0e
--- /dev/null
+++ b/tf_fuzz/docs/boilerplate_dir.rst
@@ -0,0 +1,27 @@
+#############################
+'boilerplate'-directory guide
+#############################
+
+************
+Introduction
+************
+
+This directory contains the C++ header and code files to work with the
+customizable, "boilerplate" code snippets in the ``...tools/tf_fuzz/lib``
+directory.  Mostly what this code does is read these code snippets into an
+STL ``vector`` of, essentially, named strings.
+
+****************************************************
+``.../tools/tf_fuzz/boilerplate`` directory contents
+****************************************************
+.. code-block:: bash
+
+    boilerplate.cpp  boilerplate.hpp
+
+This is currently implemented as a vector of strings, with a parallel vector
+of ``const int`` array-index names.  (In the future, it may make sense to
+manage the boilerplate code in a C++ STL ``map``-type container.)
+
+--------------
+
+*Copyright (c) 2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/docs/calls_dir.rst b/tf_fuzz/docs/calls_dir.rst
new file mode 100644
index 0000000..17c2491
--- /dev/null
+++ b/tf_fuzz/docs/calls_dir.rst
@@ -0,0 +1,33 @@
+#######################
+'calls'-directory guide
+#######################
+
+************
+Introduction
+************
+
+These classes define objects that describe everything needed to generate a PSA
+call.  The Parse phase, which parses the test-template file, generates an C++
+STL ``vector`` of ``psa_call``-class objects describing the series of PSA calls
+chosen for the test to run, based upon the test template and the random seed.
+
+More-specifically class psa_class is an abstract class, and this vector contains
+objects of derived classes, each derived class defining a particular call type.
+Each ``psa_call``-subclass object encapsulates the initial and expected data,
+expected pass/fail results, and other information about the call.
+
+**********************************************
+``.../tools/tf_fuzz/calls`` directory contents
+**********************************************
+.. code-block:: bash
+
+    crypto_call.cpp  psa_call.cpp  security_call.cpp  sst_call.cpp
+    crypto_call.hpp  psa_call.hpp  security_call.hpp  sst_call.hpp
+
+In the future, it's probably possible to, for target systems that can support
+sufficiently large memory footprints, instead of writing these calls out to a
+``.c`` file, to directly execute these PSA calls.
+
+--------------
+
+*Copyright (c) 2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/docs/demo_dir.rst b/tf_fuzz/docs/demo_dir.rst
new file mode 100644
index 0000000..fb49fe7
--- /dev/null
+++ b/tf_fuzz/docs/demo_dir.rst
@@ -0,0 +1,46 @@
+######################
+'demo'-directory guide
+######################
+
+************
+Introduction
+************
+
+This directory contains some example usages of TF-Fuzz, in a form that makes it
+easy to run each case and quickly see the results.
+
+An example way to use this directory:
+
+- Add ``./`` to your ``$PATH`` variable, for convenience (see below).
+- Using any text editor that provides for tabbed editing (e.g., Nedit) pop
+  up all files in this directory, each in a separate tab.
+- In a shell window, run each demo test, and view a file called
+  ``tossThis2`` (that name to suggest we delete that file after we're done)
+  to view the generated C code.
+
+The ``purpose`` line in each test describes what each demo illustrates.
+
+Bear in mind that these are not intended as practical use cases, but just for
+illustration.  In the first few cases, the TF-Fuzz tool is not very "smart";
+that is, TF-Fuzz only provides a very-compact test-specification format.  As
+the test number increases, the TF-Fuzz tool infers for you more about test.
+
+*********************************************
+``.../tools/tf_fuzz/demo`` directory contents
+*********************************************
+.. code-block:: bash
+
+    1  10  11  12  13  14  15  16  17  18  19  2  3  4  5  6  7  8  9  r
+
+The numbered files are test-template files -- input to TF-Fuzz -- for
+demonstrating what it can do.
+
+The ``r`` shell script is designed to make it quick and easy to run the demo
+tests one by one:  just type ``r 5`` for example.  The very short script name
+``r`` and the very-short, numbered demo-test file names were chosen to make it
+easy to quickly see example usages.  To see sequentially more-involved usages
+of the tool, go through these demos in order.
+
+--------------
+
+*Copyright (c) 2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/docs/index.rst b/tf_fuzz/docs/index.rst
new file mode 100644
index 0000000..ee74714
--- /dev/null
+++ b/tf_fuzz/docs/index.rst
@@ -0,0 +1,13 @@
+TF-Fuzz
+=======
+
+.. toctree::
+    :maxdepth: 1
+    :caption: Contents
+    :glob:
+
+    *
+
+--------------
+
+*Copyright (c) 2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/docs/lib_dir.rst b/tf_fuzz/docs/lib_dir.rst
new file mode 100644
index 0000000..fbc54dd
--- /dev/null
+++ b/tf_fuzz/docs/lib_dir.rst
@@ -0,0 +1,33 @@
+#####################
+'lib'-directory guide
+#####################
+
+************
+Introduction
+************
+
+This directory contains the customizable "boilerplate" code snippets used to
+write out C source code.  The file in this directory currently, is that for
+TF-M, but other comparable frameworks could be addressed with equivalent files
+taylored for the required syntax of that other framework.
+
+Which file to use for this process is selected by setting two environment
+variables pointing to that file:  One for the ``lib`` directory and one for the
+file itself within that directory.  In ``bash`` syntax,
+
+.. code-block:: bash
+
+    export TF_FUZZ_LIB_DIR=<path to this TF-M installation>/tools/tf_fuzz/lib
+    export TF_FUZZ_BPLATE=tfm_boilerplate.txt
+
+
+********************************************
+``.../tools/tf_fuzz/lib`` directory contents
+********************************************
+.. code-block:: bash
+
+    tfm_boilerplate.txt
+
+--------------
+
+*Copyright (c) 2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/docs/parser_dir.rst b/tf_fuzz/docs/parser_dir.rst
new file mode 100644
index 0000000..ddbca5a
--- /dev/null
+++ b/tf_fuzz/docs/parser_dir.rst
@@ -0,0 +1,27 @@
+########################
+'parser'-directory guide
+########################
+
+************
+Introduction
+************
+
+Users' test-template files are parsed using a Lex/YACC grammar, to make the
+test-template language easily extensible.  Much of the actual work is done in
+helper functions, but the Lex/YACC grammar manages the process.
+
+***********************************************
+``.../tools/tf_fuzz/parser`` directory contents
+***********************************************
+.. code-block:: bash
+
+    tf_fuzz_grammar.l  tf_fuzz_grammar.y
+
+This directory contains the Lex and YACC grammars for parsing the TF-Fuzz
+command "language," if it can be called that.  The
+``tf_fuzz_grammar.tab.cpp/.hpp`` files generated also form the executive for
+the entire parsing process.
+
+--------------
+
+*Copyright (c) 2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/docs/regression_dir.rst b/tf_fuzz/docs/regression_dir.rst
new file mode 100644
index 0000000..ec4ea6d
--- /dev/null
+++ b/tf_fuzz/docs/regression_dir.rst
@@ -0,0 +1,169 @@
+############################
+'regression'-directory guide
+############################
+
+************
+Introduction
+************
+
+This is a regression suite for the TF-Fuzz tool.  That is, tests to make sure
+that TF-Fuzz is still functioning properly after making changes.  Note that
+this regression implementation tests the most basic aspects of TF-Fuzz's
+implementation, but is not yet complete.  Most notably, it does not yet test
+``*active`` and ``*deleted``, nor ``shuffle`` and ``2 to 5 of {...}``
+constructs.
+
+***************************************************
+``.../tools/tf_fuzz/regression`` directory contents
+***************************************************
+.. code-block:: bash
+
+    000001_set_sst_uid_data_expect_pass
+    000002_set_sst_name_data_expect_nothing
+    000003_set_sst_name_data
+    000004_set_sst_name_rand_data
+    000005_set_sst_rand_name_rand_data
+    000006_set_sst_multi_name_rand_data
+    000007_set_sst_multi_uid_rand_data
+    000008_set_sst_name_rand_data_read_check_wrong
+    000009_set_sst_name_rand_data_read_check_var_read_print
+    000010_read_nonexistent_sst_check_string
+    000011_read_nonexistent_sst_check_string_expect_pass
+    000012_read_nonexistent_sst_check_string_expect_other
+    000013_set_sst_name_rand_data_remove_twice
+    000014_set_sst_name_rand_data_remove_other
+    000015_set_sst_name_only
+    000016_set_sst_single_asset_set_multiple_times
+    000017_read_sst_check_single_asset_multiple_times
+    000018_000016_and_000017
+    000019_read_asset_to_variable_set_other_asset
+    add_these_tests
+    function2OpenFiles
+    README
+    regress
+    regress_lib
+
+******************************
+Files for Each Regression Test
+******************************
+
+Here's the overall regression scheme:
+
+- ``bash regress`` from this directory runs regression.  It will fail with an
+  error if a problem is found.  If it runs to completion, then regression has
+  passed.
+
+- Each test is in its own sub-directory containing these files, by name (always
+  same name):
+
+  - ``template``:  The test-template file to be run though the TF-Fuzz under
+    test, called "the DUT TF-Fuzz" here.
+
+  - ``exp_stdout_stderr``:  The *expected*, combined ``stdout`` and ``stderr``
+    from running TF-Fuzz in verbose mode ``-v``.  This file contains wildcard
+    expressions to be checked (more on that below).
+
+  - ``exp_test.c``:  The *expected* output C code.  This file also contains
+    wildcard expressions to be resolved against the DUT TF-Fuzz output (again,
+    more on that below).
+
+  - ``stdout_stderr`` (if present):  The *actual* combined ``stdout`` and
+    ``stderr`` from running the DUT TF-Fuzz in verbose mode ``-v``, during
+    regression testing.
+
+  - ``test.c`` (if present):  The output C code generated from running the DUT
+    TF-Fuzz in verbose mode ``-v``, during regression testing.
+
+  - ``check.py``:  This Python 3 script compares expected to actual
+    ``stdout``/``stderr`` and C-test code, resolving wildcard references in
+    ``exp_stdout_stderr`` and ``exp_test.c``.  Each test directory has its own
+    script customized to the needs of that particular test, but they mostly
+    just runs TF-Fuzz, opens files, then invokes functions in the
+    ``regress_lib`` directory, which do the majority of the actual work.
+
+********************************
+How ``check.py`` Assesses a Test
+********************************
+
+To illustrate how ``check.py`` checks a regression test, below is a ``diff`` of
+``test.c`` and ``exp_test.c`` file files, from
+``./000005_set_sst_rand_name_rand_data/``, at the time of writing this:
+
+.. code-block:: bash
+
+    47,48c47,48
+    <     static uint8_t koxjis_data[] = "Gaa wuqnoe xoq uhoz qof er uaycuuf?";
+    <     static int koxjis_data_size = 35;
+    ---
+    >     static uint8_t @@@003@@@_data[] = "@@002@10@@[a-z\ ]*[\.\?\!]";
+    >     static int @@@003@@@_data_size = \d+;
+    53,55c53,55
+    <     /* Creating SST asset "koxjis," with data "Gaa wuqnoe...". */
+    <     sst_status = psa_ps_set(2110, koxjis_data_size, koxjis_data,
+    <                             PSA_STORAGE_FLAG_NONE);
+    ---
+    >     /* Creating SST asset "@@@003@@@," with data "@@002@10@@...". */
+    >     sst_status = psa_ps_set(@@@001@@@, @@@003@@@_data_size, @@@003@@@_data,
+    >                             PSA_STORAGE_FLAG_[A-Z_]+);
+    63c63
+    <     psa_ps_remove(2110);
+    ---
+    >     psa_ps_remove(@@@001@@@);
+
+``check.py``, short summary, performs a Python ``re.match()`` line-by-line the
+generated ``test.c`` against the ``exp_test.c`` file.  However, ``exp_test.c``,
+in addition to Python regular expressions, also contains "special" wildcards,
+described below.
+
+*********
+Wildcards
+*********
+
+The wildcards in the ``exp_stdout_stderr`` and ``exp_test.c`` files are of
+three basic natures, using the examples shown above (please reference them
+above to clearly understand the ideas here):
+
+.. list-table::
+   :widths: 20 80
+
+   * - ``[a-z\ ]*[\.\?\!]`` or ``[A-Z_]+``
+     - | These are Python regex pattern matches for what characters are expected
+       | at those places.  The data consist of quasi-sentences, capitalized at
+       | the beginning.  The capitalized character is covered by the
+       | ``@@002@10@@`` (see below) before it.  The ``[a-z\ ]*[\.\?\!]`` is a
+       | Python-regex match for all remaining characters of the sentence:  A
+       | sequence of zero or more lower-case letters or blanks followed by
+       | sentence-ending punctuation.
+
+   * - ``@@@001@@@`` (``@@@``, a pattern number, ``@@@``)
+     - | This denotes a particular pattern of characters, until the expected and
+       | actual character streams re-sync again.  The important thing, however,
+       | is that what this wildcard stands for *must be consistent* throughout
+       | the comparison!  In this case above, ``@@@001@@@`` in the ``exp_test.c``
+       | must consistently match ``8617`` everywhere throughout the ``test.c``
+       | file.  Of course, the ``8617`` is different for different random-seed
+       | values.  The number between the two ``@@@`` occurrences in the wildcard
+       | designates which pattern must consistently match.
+
+   * - ``@@002@10@@`` (``@@``, a pattern number, ``@``, a pattern size, ``@@``)
+     - | This is a slight variant upon the previous wildcard, in which a specific
+       | match length is required.  In lines 47 and 48 above, random data
+       | generated consists of 10 characters (thus the ... ``@10@@`` in the
+       | wildcard) ``Gaa wuqnoe`` followed by other characters we don't care
+       | about;  they can be anything.  Thus ``@@002@10@@[a-z\ ]*[\.\?\!]`` in
+       | line 47:  The ``@@002@10@@`` denotes a pattern number 002 for a length
+       | of 10 characters that must match ``Gaa wuqnoe`` in this case, followed
+       | by some arbitrary number of characters we don't care about, thus
+       | ``[a-z\ ]*[\.\?\!]`` -- a sequence of lower-case letters or spaces,
+       | capped off with normal sentence-ending punctuation.
+
+After the ``check.py`` capability -- resolving these wildcards -- for this
+purpose is fleshed out, we shall have to figure out how to address
+``shuffle {}`` and ``5 to 8 of {}`` randomizations.
+
+The ``add_these_tests`` directory contains regression tests of the above nature
+that the regression framework is not currently able to address.
+
+--------------
+
+*Copyright (c) 2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/docs/template_dir.rst b/tf_fuzz/docs/template_dir.rst
new file mode 100644
index 0000000..86dbbfa
--- /dev/null
+++ b/tf_fuzz/docs/template_dir.rst
@@ -0,0 +1,23 @@
+##########################
+'template'-directory guide
+##########################
+
+************
+Introduction
+************
+
+These classes describe "tracker" objects for parsing test templates, and for
+generating PSA calls from them.
+
+*************************************************
+``.../tools/tf_fuzz/template`` directory contents
+*************************************************
+.. code-block:: bash
+
+    crypto_template_line.cpp  secure_template_line.hpp  template_line.cpp
+    crypto_template_line.hpp  sst_template_line.cpp     template_line.hpp
+    secure_template_line.cpp  sst_template_line.hpp
+
+--------------
+
+*Copyright (c) 2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/docs/tests_dir.rst b/tf_fuzz/docs/tests_dir.rst
new file mode 100644
index 0000000..8226451
--- /dev/null
+++ b/tf_fuzz/docs/tests_dir.rst
@@ -0,0 +1,21 @@
+#######################
+'tests'-directory guide
+#######################
+
+************
+Introduction
+************
+
+These are just more examples of test-template-file content.  They're not really
+organized *tests* as such.
+
+**********************************************
+``.../tools/tf_fuzz/tests`` directory contents
+**********************************************
+.. code-block:: bash
+
+    example_template  sstReads  sstSets
+
+--------------
+
+*Copyright (c) 2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/docs/tf_fuzz_dir.rst b/tf_fuzz/docs/tf_fuzz_dir.rst
new file mode 100644
index 0000000..6ad0a38
--- /dev/null
+++ b/tf_fuzz/docs/tf_fuzz_dir.rst
@@ -0,0 +1,124 @@
+#######################################
+TF-Fuzz (Trusted-Firmware Fuzzer) guide
+#######################################
+
+************
+Introduction
+************
+
+TF-Fuzz is a TF-M fuzzing tool, at the PSA-call level.  At the time of writing
+this at least, presentations available at:
+
+- https://www.trustedfirmware.org/docs/TF-M_Fuzzing_Tool_TFOrg.pdf
+- https://zoom.us/rec/share/1dxZcZit111IadadyFqFU7IoP5X5aaa8gXUdr_UInxmMbyLzEqEmXQdx79-IWQ9p
+
+(These presentation materials may not all be viewable by all parties.)
+
+To build TF-Fuzz, simply type ``make`` in this directory.  The executable,
+called ``tfz``, is placed in this directory.
+
+To run ``tfz``, two environment variables must first be assigned.  In bash
+syntax:
+
+.. code-block:: bash
+
+    export TF_FUZZ_LIB_DIR=<path to this TF-M installation>/tools/tf_fuzz/lib
+    export TF_FUZZ_BPLATE=tfm_boilerplate.txt
+
+Examples of usage can be found in the ``demo`` directory.
+
+**********************************
+``.../tf_fuzz`` directory contents
+**********************************
+.. code-block:: bash
+
+    assets       calls               demo      parser    tests        regression
+    backupStuff  class_forwards.hpp  lib       document    tf_fuzz.cpp  utility
+    boilerplate  commands            Makefile  template  tf_fuzz.hpp  visualStudio
+
+*************
+Code Overview
+*************
+To help understand the code, below is a C++-class hierarchy used in this code
+base.  They are explained further in the documents in their respective
+directories, so the file names where the classes are defined is listed below (this,
+very roughly in order of functional interactions, of chronological usage during
+execution, and of most-to-least importance):
+
+.. code-block:: bash
+
+    template_line                         ./template/template_line.hpp
+        sst_template_line                 ./template/template_line.hpp
+            read_sst_template_line        ./template/sst_template_line.hpp
+            remove_sst_template_line      ./template/sst_template_line.hpp
+            set_sst_template_line         ./template/sst_template_line.hpp
+        policy_template_line              ./template/template_line.hpp
+            read_policy_template_line     ./template/crypto_template_line.hpp
+            set_policy_template_line      ./template/crypto_template_line.hpp
+        key_template_line                 ./template/template_line.hpp
+            read_key_template_line        ./template/crypto_template_line.hpp
+            remove_key_template_line      ./template/crypto_template_line.hpp
+            set_key_template_line         ./template/crypto_template_line.hpp
+        security_template_line            ./template/template_line.hpp
+            security_hash_template_line   ./template/secure_template_line.hpp
+
+    psa_call                              ./calls/psa_call.hpp
+        crypto_call                       ./calls/psa_call.hpp
+            policy_call                   ./calls/crypto_call.hpp
+                init_policy_call          ./calls/crypto_call.hpp
+                reset_policy_call         ./calls/crypto_call.hpp
+                add_policy_usage_call     ./calls/crypto_call.hpp
+                set_policy_lifetime_call  ./calls/crypto_call.hpp
+                set_policy_type_call      ./calls/crypto_call.hpp
+                set_policy_algorithm_call ./calls/crypto_call.hpp
+                set_policy_usage_call     ./calls/crypto_call.hpp
+                get_policy_lifetime_call  ./calls/crypto_call.hpp
+                get_policy_type_call      ./calls/crypto_call.hpp
+                get_policy_algorithm_call ./calls/crypto_call.hpp
+                get_policy_usage_call     ./calls/crypto_call.hpp
+                get_policy_size_call      ./calls/crypto_call.hpp
+                get_policy_call           ./calls/crypto_call.hpp
+            key_call                      ./calls/crypto_call.hpp
+                generate_key_call         ./calls/crypto_call.hpp
+                create_key_call           ./calls/crypto_call.hpp
+                copy_key_call             ./calls/crypto_call.hpp
+                read_key_data_call        ./calls/crypto_call.hpp
+                remove_key_call           ./calls/crypto_call.hpp
+        sst_call                         ./calls/psa_call.hpp
+            sst_remove_call              ./calls/sst_call.hpp
+            sst_get_call                 ./calls/sst_call.hpp
+            sst_set_call                 ./calls/sst_call.hpp
+        security_call                    ./calls/psa_call.hpp
+            hash_call                    ./calls/security_call.hpp
+
+    boilerplate                          ./boilerplate/boilerplate.hpp
+
+    psa_asset                            ./assets/psa_asset.hpp
+        crypto_asset                     ./assets/crypto_asset.hpp
+            policy_asset                 ./assets/crypto_asset.hpp
+            key_asset                    ./assets/crypto_asset.hpp
+        sst_asset                        ./assets/sst_asset.hpp
+
+    tf_fuzz_info                         ./tf_fuzz.hpp
+
+    variables                            ./utility/variables.hpp
+    crc32                                ./utility/compute.hpp
+
+    gibberish                            ./utility/gibberish.hpp
+
+    expect_info                          ./utility/data_blocks.hpp
+    set_data_info                        ./utility/data_blocks.hpp
+    asset_name_id_info                   ./utility/data_blocks.hpp
+
+TF-Fuzz now has better-organized management of variables in the generated code.
+In particular, it maintains a list of variables named in the test template, and
+implicit in the code, notably variables assets are ``read`` into.  It also now has
+completely separate execution phases to parse the test template, simulate the
+sequence of PSA calls generated, and write out the expected results.  That
+simulation is only in enough detail to predict expected results.  Since TF-Fuzz
+currectly mostly addresses only SST calls, that simulation is very simple in
+nature -- just tracking data movement.
+
+--------------
+
+*Copyright (c) 2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/docs/utility_dir.rst b/tf_fuzz/docs/utility_dir.rst
new file mode 100644
index 0000000..89ad060
--- /dev/null
+++ b/tf_fuzz/docs/utility_dir.rst
@@ -0,0 +1,24 @@
+#########################
+'utility'-directory guide
+#########################
+
+************
+Introduction
+************
+
+As its name implies, this ``.../tf_fuzz/utility`` directory just contains
+various utility-compute code.
+
+************************************************
+``.../tools/tf_fuzz/utility`` directory contents
+************************************************
+.. code-block:: bash
+
+    compute.cpp      find_or_create_asset.hpp  randomization.cpp  string_ops.hpp
+    compute.hpp      gibberish.cpp             randomization.hpp
+    data_blocks.cpp  gibberish.hpp             Source.cpp
+    data_blocks.hpp  interactive.c             string_ops.cpp
+
+--------------
+
+*Copyright (c) 2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/docs/visualStudio_dir.rst b/tf_fuzz/docs/visualStudio_dir.rst
new file mode 100644
index 0000000..a70bbf8
--- /dev/null
+++ b/tf_fuzz/docs/visualStudio_dir.rst
@@ -0,0 +1,26 @@
+##############################
+'visualStudio'-directory guide
+##############################
+
+************
+Introduction
+************
+
+This is just things to support running and debug under Microsoft Visual Studio
+(Visual Studio is a trademark of Microsoft Corporation).  So far, it contains
+a "stand-in" for the ``unistd.h`` library, and more specifically, the
+``isatty()`` call in that library, which is used by Lex and YACC.  Other
+functions may be added later as needed.  At some time in the future, an
+up-coming "interactive mode" for interactively creating test templates may
+need an actual working ``isatty()``, but that's not ready yet.
+
+*************************************************
+.../tools/tf_fuzz/visualStudio directory contents
+*************************************************
+.. code-block:: bash
+
+    unistd.c  unistd.h
+
+--------------
+
+*Copyright (c) 2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/generate_test_suite.sh b/tf_fuzz/generate_test_suite.sh
new file mode 100755
index 0000000..80e0b38
--- /dev/null
+++ b/tf_fuzz/generate_test_suite.sh
@@ -0,0 +1,209 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+set -e
+
+SUITE_DIR_NAME=tfm_fuzz
+
+show_help()
+{
+    echo "Usage: $0 <template_dir> <suites_dir> "
+    echo ""
+    echo "Where: "
+    echo "    template_dir: The directory containing template files for the"
+    echo "                  fuzzing tool"
+    echo "    suites_dir:   The directory to generate the test suite to."
+}
+
+if [ $# != 2 ]
+then
+    echo "Invalid number of parameters."
+    show_help
+    exit 1
+fi
+
+INPUT_DIR=$1
+SUITES_DIR=$2
+
+# Check that the input directory exists
+if [ ! -d "$INPUT_DIR" ]
+then
+    echo "Template directory '$INPUT_DIR' doesn't exist"
+    exit 1
+fi
+
+# Check that the input directory contains files
+if [ `ls "$INPUT_DIR"| wc -l` == 0 ]
+then
+    echo "Template directory '$INPUT_DIR' doesn't contain files"
+    exit 1
+fi
+
+if [ ! -d "$SUITES_DIR" ]
+then
+    echo "Suites directory '$SUITES_DIR' doesn't exist"
+    exit 1
+fi
+
+# Check whether a fuzz test suite was generated before
+if [ -d "$SUITES_DIR/$SUITE_DIR_NAME" ]
+then
+    echo "'$SUITE_DIR_NAME' exists."
+    echo "A TF fuzz test suite is already generated, please delete it before running this script"
+    exit 1
+fi
+
+#get absolute path of the suit dir TF_FUZZ
+pushd $SUITES_DIR > /dev/null
+SUITE_ABSOLUTE_DIR=`pwd`/$SUITE_DIR_NAME
+popd
+
+# creating directory for the fuzz tests tool
+echo "Creating '$SUITES_DIR/$SUITE_DIR_NAME/non_secure'"
+mkdir -p $SUITES_DIR/$SUITE_DIR_NAME/non_secure
+
+# generate additional files for the suite:
+CMAKELIST=$SUITES_DIR/$SUITE_DIR_NAME/CMakeLists.txt
+TESTSUITE=$SUITES_DIR/$SUITE_DIR_NAME/non_secure/tf_fuzz_testsuite.c
+TESTSUITE_HEADER=$SUITES_DIR/$SUITE_DIR_NAME/non_secure/tf_fuzz_testsuite.h
+
+# generate data for the testcases
+# Iterate over the testcase files and
+# - Run the fuzzer on the test template
+# - Generate a test function name, and replace the generic test_thread to that
+#   in the generated c file
+# - append the generated c file to the CmakeList file.
+declare -A FILENAMES
+declare -A FUNC_NAMES
+declare -A PURPOSES
+for f in `ls $INPUT_DIR`
+do
+    FILE="$SUITES_DIR/$SUITE_DIR_NAME/non_secure/$f.c"
+    FILENAMES[$f]=$FILE
+
+    SEED=$RANDOM
+    echo "Generating testcase $f with seed $SEED"
+    ./tfz -z $INPUT_DIR/$f $FILE $SEED
+
+    echo "in File ${FILENAMES[$f]}"
+
+    PURPOSE=`grep -A 1 'Test purpose' $FILE | tail -n 1 | cut -d '*' -f 2 | sed -e 's/^[[:space:]]*//'`
+    PURPOSES[$f]=$PURPOSE
+
+    FUNC_NAME="$PURPOSE"
+    FUNC_NAME=`echo "$FUNC_NAME" | \
+               sed 's/^\s*//g; s/\s*$//g; s/\s\s*/_/g'`
+    FUNC_NAME=`echo "$FUNC_NAME" | \
+               sed 's/\-/_/g; s/"//g; s/\\\//g'`
+    FUNC_NAME=`echo "$FUNC_NAME" | \
+               sed "s/#//g; s/'//g; s/,//g; s/(//g; s/)//g"`
+    FUNC_NAMES[$f]=$FUNC_NAME
+
+    echo "    Changing 'test_thread' to '${FUNC_NAMES[$f]}'"
+
+    sed -i "s/test_thread/$FUNC_NAME/g" $FILE
+
+done
+
+# generate the non-secure testsuite file
+echo '#include <stdio.h>' >> $TESTSUITE
+echo '#include <string.h>' >> $TESTSUITE
+echo '' >> $TESTSUITE
+echo '#include "tfm_api.h"' >> $TESTSUITE
+echo '#include "psa_manifest/sid.h"' >> $TESTSUITE
+echo '#include "test_framework.h"' >> $TESTSUITE
+echo '' >> $TESTSUITE
+echo '/* Forward declaring static test functions */' >> $TESTSUITE
+for f in `ls $INPUT_DIR`
+do
+    echo "static void test_${FUNC_NAMES[$f]}(struct test_result_t *ret);" >> $TESTSUITE
+done
+echo '/* Forward declaring functions */' >> $TESTSUITE
+for f in `ls $INPUT_DIR`
+do
+    echo "void ${FUNC_NAMES[$f]}(struct test_result_t *ret);" >> $TESTSUITE
+done
+echo '' >> $TESTSUITE
+echo 'static struct test_t tf_fuzz_tests[] = {' >> $TESTSUITE
+for f in `ls $INPUT_DIR`
+do
+    echo "    {&test_${FUNC_NAMES[$f]}, \"${FUNC_NAMES[$f]}\", \"${PURPOSES[$f]}\", {0} }," >> $TESTSUITE
+done
+echo '}; ' >> $TESTSUITE
+echo '' >> $TESTSUITE
+echo 'void register_testsuite_tf_fuzz_test(struct test_suite_t *p_test_suite)' >> $TESTSUITE
+echo '{' >> $TESTSUITE
+echo '    uint32_t list_size;' >> $TESTSUITE
+echo '' >> $TESTSUITE
+echo '    list_size = (sizeof(tf_fuzz_tests) / sizeof(tf_fuzz_tests[0]));' >> $TESTSUITE
+echo '' >> $TESTSUITE
+echo '    set_testsuite("TF-M fuzz tests (TF_FUZZ_TEST)",' >> $TESTSUITE
+echo '                  tf_fuzz_tests, list_size, p_test_suite);' >> $TESTSUITE
+echo '}' >> $TESTSUITE
+echo '' >> $TESTSUITE
+for f in `ls $INPUT_DIR`
+do
+    echo "static void test_${FUNC_NAMES[$f]}(struct test_result_t *ret)" >> $TESTSUITE
+    echo '{' >> $TESTSUITE
+    echo "    ${FUNC_NAMES[$f]}(ret);" >> $TESTSUITE
+    echo '    if (ret->val != TEST_PASSED) {' >> $TESTSUITE
+    echo '        return;' >> $TESTSUITE
+    echo '    }' >> $TESTSUITE
+    echo '' >> $TESTSUITE
+    echo '}' >> $TESTSUITE
+done
+
+# generate the CmakeList file
+echo "cmake_policy(SET CMP0079 NEW)" >> $CMAKELIST
+echo "" >> $CMAKELIST
+echo "add_library(tfm_test_suite_tf_fuzz_ns STATIC EXCLUDE_FROM_ALL)" >> $CMAKELIST
+echo "" >> $CMAKELIST
+echo "target_sources(tfm_test_suite_tf_fuzz_ns" >> $CMAKELIST
+echo "    PRIVATE" >> $CMAKELIST
+for f in `ls $INPUT_DIR`
+do
+    echo "        $SUITE_ABSOLUTE_DIR/non_secure/$f.c" >> $CMAKELIST
+done
+echo "        $SUITE_ABSOLUTE_DIR/non_secure/tf_fuzz_testsuite.c" >> $CMAKELIST
+echo ")" >> $CMAKELIST
+echo "" >> $CMAKELIST
+echo "target_include_directories(tfm_test_suite_tf_fuzz_ns" >> $CMAKELIST
+echo "    PUBLIC" >> $CMAKELIST
+echo "        ./non_secure" >> $CMAKELIST
+echo "    PRIVATE" >> $CMAKELIST
+echo "        ." >> $CMAKELIST
+echo ")" >> $CMAKELIST
+echo "" >> $CMAKELIST
+echo "target_link_libraries(tfm_test_suite_tf_fuzz_ns" >> $CMAKELIST
+echo "    PRIVATE" >> $CMAKELIST
+echo "        tfm_test_framework_ns" >> $CMAKELIST
+echo "        tfm_test_suite_its_ns" >> $CMAKELIST
+echo ")" >> $CMAKELIST
+echo "" >> $CMAKELIST
+echo "target_link_libraries(tfm_ns_tests" >> $CMAKELIST
+echo "    INTERFACE" >> $CMAKELIST
+echo "        tfm_test_suite_tf_fuzz_ns" >> $CMAKELIST
+echo ")" >> $CMAKELIST
+
+# generate the testsuite header file
+echo '#ifndef __PSA_API_FUZZ_TESTSUITE_H__' >> $TESTSUITE_HEADER
+echo '#define __PSA_API_FUZZ_TESTSUITE_H__' >> $TESTSUITE_HEADER
+echo '' >> $TESTSUITE_HEADER
+echo 'void register_testsuite_tf_fuzz_test(struct test_suite_t *p_test_suite);' >> $TESTSUITE_HEADER
+echo '' >> $TESTSUITE_HEADER
+echo '#endif /* __PSA_API_FUZZ_TESTSUITE_H__ */' >> $TESTSUITE_HEADER
+
+# print some instruction on the screen
+echo ''
+echo ''
+echo '========================================================================='
+echo '= The test suite generation is done. It can be compiled to TF-M by'
+echo '= providing the following options to the CMake generate command:'
+echo '='
+echo '=     -DTFM_FUZZER_TOOL_TESTS=1'
+echo '=     -DTFM_FUZZER_TOOL_TESTS_CMAKE_INC_PATH='$SUITE_ABSOLUTE_DIR
+echo '========================================================================='
diff --git a/tf_fuzz/lib/README b/tf_fuzz/lib/README
new file mode 100644
index 0000000..7c46edc
--- /dev/null
+++ b/tf_fuzz/lib/README
@@ -0,0 +1,10 @@
+This directory contains the customizable "boilerplate" code snippets used to
+write out C source 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/lib_dir.html
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/lib/human_boilerplate.txt b/tf_fuzz/lib/human_boilerplate.txt
new file mode 100644
index 0000000..f475902
--- /dev/null
+++ b/tf_fuzz/lib/human_boilerplate.txt
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+This file is a library text file of boilerplate-text snippets.  TF-Fuzz reads in these
+snippets and then performs targeted text substitutions upon them, to create the indi-
+vidual PSA commands, and other important code snippets.  This one in particular
+library-text file is used to create a human-readable summary of the actual code.  It's
+not exactly documentation as such, but more of just a human-oriented flow of the
+generated test code.
+
+Four extremely important things about this file:
+*  The individual text snippets are separated by "backtick" (AKA back-apostrophe)
+   characters (see below).  This means that text snippets of TF code can't use backtick
+   characters (reasonably safe for C code).
+*  The text snippets are *positional*.  The loop in boilerplate.cpp reads them in, in
+   the order they appear in this file, into a vector of strings.  The "const int"s in
+   boilerplate.hpp assign symbolic names to the vector indices.  It is therefore
+   *critical* that the, for example, 11th backtick-delineated text snippet in this file,
+   be read into the 11 string in this vector of strings!
+*  This first text snippet that you're now reading -- a README about this file -- is
+   ignored by this boilerplate.cpp loop;  it is not read into this vector of snippets.
+*  To make it easier to track the positional nature of the text snippets in this file,
+   the first three characters, plus the leading \n, of these snippets is trimmed off
+   and ignored.  These first three characters in each string comprise a sequence
+   number, for Check against the "const int" list in boilerplate.hpp.  So, these
+   tags are literally the exactly the 3 characters directly after the backtick termi-
+   nating the previous string.
+`000
+This test is intended:
+    $purpose.
+
+    It starts with essential #include directives.
+`001
+
+    The code continues with declaration and definitions of helper functions
+    that perform a simple hashing of data.  This hash allows many different
+    blocks of data to be compared to each other in all combinations.  Nominally
+    this is to find data leaks between variables.
+`002
+
+    Next is a declaration of the thread function that performs the generated
+    test, then...
+
+`003          `004
+    Declaration of int-type variable called $var, with initial value "$init"
+`005
+    Declaration of uint8_t unchanging array, $var, with initial value of:
+        $init
+`006
+    Declaration of uint8_t array, $var, with initial value of:
+        $init
+        A lot of space is given to this array anticipating that it will be over-
+        written with potentially large read-data.
+`007
+    Declaration of size_t-type variable called $var, 
+        with initial value "$init".
+`008
+    Declaration of psa_key_attributes_t-type variable called $var.
+`009
+    Declaration of psa_algorithm_t-type variable called $var.
+`010
+    Declaration of psa_key_lifetime_t-type variable called $var.
+`011
+    Declaration of psa_key_type_t-type variable $var;
+`012
+    Declaration of psa_key_usage_t-type variable $var;
+`013
+    Declaration of psa_key_handle_t-type variable $var;
+`014
+    Declaration of $type-type variable called $var, with initial value "$init".
+`015
+
+    Writing to the message log:
+        $message.
+`016
+
+    Test-teardown delete of SST asset UID $uid.
+`017
+    Verify that the previous call was successful.
+`018
+
+    Test-teardown delete of key asset, handle "$handle."
+`019
+    Verify that the previous call was successful.
+`020
+
+And this is the end of the test.
+`021 PSA_SUCCESS`022 PSA_ERROR_DOES_NOT_EXIST`023
+
+    Set an SST asset:
+    *  UID = $uid, length = $length,
+    *  data = $data, and
+    *  creation flags = $flags.
+`024
+    Verify that previous had a result of $expect.
+`025
+
+    Read (get) SST-asset data:
+    *  UID = $uid, length = $length,
+    *  actual data in $act_data, and
+    *  actual length in $act_length.
+`026
+    Verify that previous had a result of $expect.
+`027
+    Verify that the previous SST get (read) had a result of "$expect,"
+        then a comparison of the values read, $act_data against $exp_data.
+`028
+    Hash the SST data in $act_data_var for later data-leak check,
+        resulting has being placed in $hash_var. */
+`029
+
+    Deletion of SST asset, UID = $uid.
+`030
+    Verify that previous SST-asset deletion had a result of $expect.
+`031
+    Initializing PSA-Crypto attributes (policy) "$policy".
+`032
+    Resetting key attributes (policy) for "$policy".
+`033
+    Adding a key-policy attribute of $flag to "$policy".
+`034
+    Setting key-policy "$policy"'s lifetime to $life.
+`035
+    Setting the key size for "$policy" to $size bits.
+`036
+    Setting the key type for "$policy" to $type.
+`037
+    Setting the key algorithm for "$policy" to $algorithm.
+`038
+    Setting key usage flags for "$policy" to $usage.
+`039
+    Reading key lifetime for "$policy" into variable $life.
+`040
+    Reading key lifetime for "$policy" into variable $life,
+        and displaying it to the log file.
+
+`041
+    Reading key size into variable $size, for key policy "$policy".
+`042
+    Reading key type into variable $type, for key policy "$policy".
+`043
+    Reading key type into variable $type, for key policy "$policy",
+        and displaying it to the log file.
+`044
+    Reading key algorithm into variable $algorithm, for key policy "$policy".
+`045
+    Reading key algorithm into variable $algorithm, for key policy "$policy",
+        and displaying it to the log file.
+`046
+    Reading key usage into variable $usage, for key policy "$policy".
+`047
+    Displaying to the log the presence or not of key-policy usage
+        $usage_string for key-policy "$policy",
+        as either $print_usage_true_string or $print_usage_false_string.
+`048
+    Reading attributes (policy) for key $key into variable "$policy".
+`049
+    Verify that previous get (read) of key policies had result of $expect.
+`050
+    Generate key (no key data specified) $key, from policy "$policy".
+`051
+    Verify that previous key generation had result of $expect.
+`052
+    Creating key for key $key:
+    *  Policy = "$policy", 
+    *  Data variable = $data, and
+    *  Length = $length.
+`053
+    Verify that key-creation had result of $expect.
+`054
+    Copying a key:
+    *  Master key = $master,
+    *  Copy key = $copy, and
+    *  New-key policy = "$policy".
+`055
+    Verify that key-export (read of key data) had result of $expect.
+`056
+    Verify that key-data read into $act_data, matches dat in $exp_data.
+`057
+    Export (read) of key data for $key:
+    *  Data variable = $data,
+    *  Data-length variable = $length, and
+    *  Actual data-size variable = $act_size.
+`058
+    Verify that key-export (read of key data) had result of $expect.
+`059
+    Delete key $key.
+`060
+    Verify that key-delete had result of $expect.
+`
diff --git a/tf_fuzz/lib/tfm_boilerplate.txt b/tf_fuzz/lib/tfm_boilerplate.txt
new file mode 100644
index 0000000..dcec086
--- /dev/null
+++ b/tf_fuzz/lib/tfm_boilerplate.txt
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+This file is a library text file of boilerplate-text snippets.  TF-Fuzz reads in these
+snippets and then performs targeted text substitutions upon them, to create the indi-
+vidual PSA commands, and other important code snippets.  This one in particular
+library-text file is what might be called the "personality module" for writing tests
+with TF-M syntax.
+
+Four extremely important things about this file:
+*  The individual text snippets are separated by "backtick" (AKA back-apostrophe)
+   characters (see below).  This means that text snippets of TF code can't use backtick
+   characters (reasonably safe for C code).
+*  The text snippets are *positional*.  The loop in boilerplate.cpp reads them in, in
+   the order they appear in this file, into a vector of strings.  The "const int"s in
+   boilerplate.hpp assign symbolic names to the vector indices.  It is therefore
+   *critical* that the, for example, 11th backtick-delineated text snippet in this file,
+   be read into the 11 string in this vector of strings!
+*  This first text snippet that you're now reading -- a README about this file -- is
+   ignored by this boilerplate.cpp loop;  it is not read into this vector of snippets.
+*  To make it easier to track the positional nature of the text snippets in this file,
+   the first three characters, plus the leading \n, of these snippets is trimmed off
+   and ignored.  These first three characters in each string comprise a sequence
+   number, for checking against the "const int" list in boilerplate.hpp.  So, these
+   tags are literally the exactly the 3 characters directly after the backtick termi-
+   nating the previous string.
+`000
+/*
+ * Test purpose:
+ *     $purpose
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "psa/protected_storage.h"
+#include "psa/crypto.h"
+#include "test_framework.h"
+`001
+
+static uint32_t shift_reg = 0x55555555;
+static int i;  /* generic counter variable */
+
+static void seed_hasher (void)
+{
+    shift_reg = 0x55555555;
+}
+
+static uint32_t lfsr_1b (uint32_t a_bit)
+{
+    int odd;
+    uint32_t polynomial = 0xb4bcd35c;
+
+    odd = ((shift_reg ^ a_bit) & 1) == 1;
+    shift_reg >>= 1;
+    if (odd == 1) {
+        shift_reg ^= polynomial;
+    }
+    if (shift_reg == 0) {
+        /* Should never happen, but... */
+        seed_hasher();
+    }
+    return shift_reg;
+}
+
+static uint32_t crc_byte (uint8_t a_byte)
+{
+    int i;
+    for (i = 0;  i < 8;  i++) {
+        lfsr_1b ((uint32_t) a_byte);
+        a_byte >>= 1;
+    }
+    return shift_reg;
+}
+
+`002
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+`003
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test $purpose");
+`004
+    static int $var = $init;
+`005
+    static uint8_t $var[] = "$init";
+`006
+    static uint8_t $var[2048] = "$init";
+`007
+    static size_t $var = $init;
+`008
+    static psa_key_attributes_t $var;
+`009
+    static psa_algorithm_t $var;
+`010
+    static psa_key_lifetime_t $var;
+`011
+    static psa_key_type_t $var;
+`012
+    static psa_key_usage_t $var;
+`013
+    static psa_key_handle_t $var;
+`014
+    $type $var = $init;
+`015
+    TEST_LOG("$message");
+`016
+    psa_ps_remove($uid);
+`017
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+`018
+    psa_destroy_key($handle);
+`019
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down a crypto asset upon test completion");
+        return;
+    }
+`020
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
+`021 PSA_SUCCESS`022 PSA_ERROR_DOES_NOT_EXIST`023
+    /* $op SST asset $description with data $data_source. */
+    sst_status = psa_ps_set($uid, $length, $data,
+                            $flags);
+`024
+    if (sst_status != $expect) {
+        TEST_FAIL("psa_ps_set() expected $expect.");
+        return;
+    }
+`025
+    sst_status = psa_ps_get($uid, $offset, $length, $act_data,
+                            &$act_length);
+`026
+    if (sst_status != $expect) {
+        TEST_FAIL("psa_ps_get() expected $expect.");
+        return;
+    }
+`027
+    if (sst_status != $expect) {
+        TEST_FAIL("psa_ps_get() expected $expect.");
+        return;
+    }
+    /* Check that the data is correct */
+    if (memcmp($act_data, $exp_data,
+                   $length) != 0) {
+        TEST_FAIL("Read data should be equal to result data");
+        return;
+    }
+`028
+    /* Hash the actual data for later data-leak checking: */
+    seed_hasher();
+    for (i = 0;  i < strlen((char *) $act_data_var);  ++i) {
+        crc_byte ($act_data_var[i]);
+    }
+    /* $hash_var = shift_reg; */
+`029
+    sst_status = psa_ps_remove($uid);
+`030
+    if (sst_status != $expect) {
+        TEST_FAIL("psa_ps_remove() expected $expect.");
+        return;
+    }
+`031
+    $policy = psa_key_attributes_init();
+`032
+    psa_reset_key_attributes (&$policy);
+`033
+    psa_set_key_usage_flags (
+            &$policy,
+               psa_get_key_usage_flags (&$policy)
+            |  $flag
+    );
+`034
+    psa_set_key_lifetime (&$policy, $life);
+`035
+    psa_set_key_bits (&$policy, $size);
+`036
+    psa_set_key_type (&$policy, $type);
+`037
+    psa_set_key_algorithm (&$policy, $algorithm);
+`038
+    psa_set_key_usage_flags (&$policy, $usage);
+`039
+    $life = psa_get_key_lifetime (&$policy);
+`040
+    $life = psa_get_key_lifetime (&$policy);
+    if ($life == PSA_KEY_LIFETIME_VOLATILE) {
+        TEST_LOG("$policy:  Lifetime is volatile.");
+    } else {
+        TEST_LOG("$policy:  Lifetime is persistent.");
+    }
+`041
+    $size = psa_get_key_bits (&$policy);
+`042
+    $type = psa_get_key_type (&$policy);
+`043
+    $type = psa_get_key_type (&$policy);
+    TEST_LOG("$policy:  Key-type code == $type.");
+`044
+    $algorithm = psa_get_key_algorithm (&$policy);
+`045
+    $algorithm = psa_get_key_algorithm (&$policy);
+    TEST_LOG("$policy:  Key-algorithm code == $algorithm.");
+`046
+    $usage = psa_get_key_usage_flags (&$policy);
+`047
+    if (($usage & $usage_string) != 0) {
+        TEST_LOG("$policy:  $print_usage_true_string.");
+    } else {
+        TEST_LOG("$policy:  $print_usage_false_string.");
+    }
+`048
+    crypto_status = psa_get_key_attributes ($key, &$policy);
+`049
+    if (crypto_status != $expect) {
+        TEST_FAIL("psa_get_key_attributes() expected $expect.");
+        return;
+    }
+`050
+    crypto_status = psa_generate_key (&$policy, &$key);
+`051
+    if (crypto_status != $expect) {
+        TEST_FAIL("psa_generate_key() expected $expect.");
+        return;
+    }
+`052
+    crypto_status
+        = psa_import_key (&$policy, $data, $length, &$key);
+`053
+    if (crypto_status != $expect) {
+        TEST_FAIL("psa_import_key() expected $expect.");
+        return;
+    }
+`054
+    crypto_status = psa_copy_key ($master, &$policy, &$copy);
+`055
+    if (crypto_status != $expect) {
+        TEST_FAIL("psa_copy_key() expected $expect.");
+        return;
+    }
+`056
+    /* Check that the data is correct */
+    if (memcmp($act_data, $exp_data,
+                   $length) != 0) {
+        TEST_FAIL("Read data should be equal to result data");
+        return;
+    }
+`057
+    crypto_status
+        = psa_export_key ($key, $data, $length, &$act_size);
+`058
+    if (crypto_status != $expect) {
+        TEST_FAIL("psa_export_key() expected $expect.");
+        return;
+    }
+`059
+    crypto_status = psa_destroy_key($key);
+`060
+    if (crypto_status != $expect) {
+        TEST_FAIL("psa_destroy_key() expected $expect.");
+        return;
+    }
+`
diff --git a/tf_fuzz/parser/README b/tf_fuzz/parser/README
new file mode 100644
index 0000000..8301488
--- /dev/null
+++ b/tf_fuzz/parser/README
@@ -0,0 +1,10 @@
+This directory contains the Lex and YACC grammars for parsing the TF-Fuzz command
+"language" (if it can be called a language as such).
+
+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/parser_dir.html
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/parser/tf_fuzz_grammar.l b/tf_fuzz/parser/tf_fuzz_grammar.l
new file mode 100644
index 0000000..429e60c
--- /dev/null
+++ b/tf_fuzz/parser/tf_fuzz_grammar.l
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+
+%{
+#include "class_forwards.hpp"
+#include "boilerplate.hpp"
+#include "gibberish.hpp"
+#include "compute.hpp"
+#include "string_ops.hpp"
+#include "data_blocks.hpp"
+#include "psa_asset.hpp"
+#include "sst_asset.hpp"
+#include "crypto_asset.hpp"
+#include "find_or_create_asset.hpp"
+#include "template_line.hpp"
+#include "tf_fuzz.hpp"
+#include "psa_call.hpp"
+#include "tf_fuzz_grammar.tab.hpp"
+
+int yycolumn = 1;
+
+//char *yytext;
+
+#define YY_USER_ACTION yylloc.first_line = yylloc.last_line = yylineno; \
+    yylloc.first_column = yycolumn; yylloc.last_column = yycolumn + yyleng - 1; \
+    yycolumn += yyleng; \
+    yylval.str = strdup(yytext);
+
+void yyerror (tf_fuzz_info *, const char *str)
+    /* not sure why it sends the yyparse() argument to yyerror(), but OK... */
+{
+    fprintf (stderr, "tf_fuzz template on line %d, at text = \"%s\":  %s\n",
+            yylineno, yytext, str);
+    exit (1);
+}
+
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+%}
+
+%x BLOCK_COMMENT
+
+%option yylineno
+%option nodefault
+%option noyywrap
+%array
+
+%%
+
+\r                        ;   /* ignore all \r */
+\/\/.*\n                  ;   /* ignore C++-style line comments */
+purpose[ \t]+[^;]*;       return PURPOSE;
+"/*"                      {BEGIN(BLOCK_COMMENT);}
+<BLOCK_COMMENT>"*/"       {BEGIN(INITIAL);}
+<BLOCK_COMMENT>\n         ;
+<BLOCK_COMMENT>.          ;
+  /* Root commands: */
+set                       return SET;
+read                      return READ;
+remove                    return REMOVE;
+rm                        return REMOVE;
+secure                    return SECURE;
+sec                       return SECURE;
+done                      return DONE;
+  /* PSA-asset types: */
+sst                       return SST;
+key                       return KEY;
+policy                    return POLICY;
+  /* Other root-command operands: */
+expect                    return EXPECT;
+exp                       return EXPECT;
+pass                      return PASS;
+fail                      return FAIL;
+nothing                   return NOTHING;
+error                     return ERROR;
+\{                        return OPEN_BRACE;
+\}                        return CLOSE_BRACE;
+;                         return SEMICOLON;
+name                      return NAME;
+uid                       return UID;
+data                      return DATA;
+\*                        return STAR;
+active                    return ACTIVE;
+act                       return ACTIVE;
+deleted                   return DELETED;
+del                       return DELETED;
+removed                   return DELETED;
+check                     return CHECK;
+chk                       return CHECK;
+var                       return VAR;
+print                     return PRINT;
+hash                      return HASH;
+neq                       return NEQ;
+dfname                    return DFNAME;
+shuffle                   return SHUFFLE;
+shuf                      return SHUFFLE;
+to                        return TO;
+of                        return OF;
+  /* SST creation keywords: */
+flag                      return FLAG;
+none                      return NONE;
+write_once                return WRITE_ONCE;
+wo                        return WRITE_ONCE;
+no_rp                     return NO_RP;
+nrp                       return NO_RP;
+no_conf                   return NO_CONF;
+ncf                       return NO_CONF;
+  /* Offset into an SST asset */
+offset                    return OFFSET;
+  /* Policy keywords: */
+attributes                return ATTR;
+attr                      return ATTR;
+type                      return TYPE;
+algorithm                 return ALG;
+alg                       return ALG;
+  /* Policy-usage and -lifetime keywords: */
+export                    return EXPORT;
+exp                       return EXPORT;
+noexport                  return NOEXPORT;
+nex                       return NOEXPORT;
+copy                      return COPY;
+nocopy                    return NOCOPY;
+encrypt                   return ENCRYPT;
+encr                      return ENCRYPT;
+noencrypt                 return NOENCRYPT;
+nenc                      return NOENCRYPT;
+decrypt                   return DECRYPT;
+decr                      return DECRYPT;
+nodecrypt                 return NODECRYPT;
+ndecr                     return NODECRYPT;
+sign                      return SIGN;
+nosign                    return NOSIGN;
+verify                    return VERIFY;
+ver                       return VERIFY;
+noverify                  return NOVERIFY;
+nver                      return NOVERIFY;
+derive                    return DERIVE;
+der                       return DERIVE;
+noderive                  return NODERIVE;
+nder                      return NODERIVE;
+persistent                return PERSISTENT;
+pers                      return PERSISTENT;
+volatile                  return VOLATILE;
+vol                       return VOLATILE;
+from                      return FROM;
+with                      return WITH;
+  /* Structure operands: */
+[a-zA-z][a-zA-Z_0-9]*     {yylval.str = yytext; return IDENTIFIER_TOK;}
+[+-]?[0-9]*               {yylval.valueN = atol(yytext); return NUMBER_TOK;}
+\'[a-zA-Z_0-9\/\.]+\'     {yylval.str = yytext; return FILE_PATH_TOK;}
+\"[^\"]*\"                {yylval.str = yytext; return LITERAL_TOK;}
+\[[a-fA-F 0-9]*\]         {yylval.str = yytext; return HEX_LIST;}
+                              /* inside quotes:  anything but a quote, or nothing */
+[ \t\n\r]                 ;   /* ignore white space */
+.                         yyerror ((tf_fuzz_info *) NULL, "Unexpected character");
+
+%%
+
diff --git a/tf_fuzz/parser/tf_fuzz_grammar.lex.c b/tf_fuzz/parser/tf_fuzz_grammar.lex.c
new file mode 100644
index 0000000..48c715b
--- /dev/null
+++ b/tf_fuzz/parser/tf_fuzz_grammar.lex.c
@@ -0,0 +1,2548 @@
+#line 2 "parser/tf_fuzz_grammar.lex.c"
+
+#line 4 "parser/tf_fuzz_grammar.lex.c"
+
+#define  YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 6
+#define YY_FLEX_SUBMINOR_VERSION 0
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with  platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types. 
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t; 
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN               (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN              (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN              (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX               (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX              (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX              (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX              (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX             (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX             (4294967295U)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else	/* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif	/* defined (__STDC__) */
+#endif	/* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart(yyin  )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+extern yy_size_t yyleng;
+
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+    /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
+     *       access to the local variable yy_act. Since yyless() is a macro, it would break
+     *       existing scanners that call yyless() from OUTSIDE yylex. 
+     *       One obvious solution it to make yy_act a global. I tried that, and saw
+     *       a 5% performance hit in a non-yylineno scanner, because yy_act is
+     *       normally declared as a register variable-- so it is not worth it.
+     */
+    #define  YY_LESS_LINENO(n) \
+            do { \
+                int yyl;\
+                for ( yyl = n; yyl < yyleng; ++yyl )\
+                    if ( yytext[yyl] == '\n' )\
+                        --yylineno;\
+            }while(0)
+    #define YY_LINENO_REWIND_TO(dst) \
+            do {\
+                const char *p;\
+                for ( p = yy_cp-1; p >= (dst); --p)\
+                    if ( *p == '\n' )\
+                        --yylineno;\
+            }while(0)
+    
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		*yy_cp = (yy_hold_char); \
+		YY_RESTORE_YY_MORE_OFFSET \
+		(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+		} \
+	while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr)  )
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+	{
+	FILE *yy_input_file;
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	yy_size_t yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	int yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+    int yy_bs_lineno; /**< The line count. */
+    int yy_bs_column; /**< The column count. */
+    
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via yyrestart()), so that the user can continue scanning by
+	 * just pointing yyin at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+
+	};
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+                          : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+static int yy_n_chars;		/* number of characters read into yy_ch_buf */
+yy_size_t yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0;		/* whether we need to initialize */
+static int yy_start = 0;	/* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart (FILE *input_file  );
+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size  );
+void yy_delete_buffer (YY_BUFFER_STATE b  );
+void yy_flush_buffer (YY_BUFFER_STATE b  );
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer  );
+void yypop_buffer_state (void );
+
+static void yyensure_buffer_stack (void );
+static void yy_load_buffer_state (void );
+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file  );
+
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size  );
+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str  );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len  );
+
+void *yyalloc (yy_size_t  );
+void *yyrealloc (void *,yy_size_t  );
+void yyfree (void *  );
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){ \
+        yyensure_buffer_stack (); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            yy_create_buffer(yyin,YY_BUF_SIZE ); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+	}
+
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){\
+        yyensure_buffer_stack (); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            yy_create_buffer(yyin,YY_BUF_SIZE ); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+	}
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define yywrap() (/*CONSTCOND*/1)
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int yylineno;
+
+int yylineno = 1;
+
+extern char yytext[];
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
+static int yy_get_next_buffer (void );
+#if defined(__GNUC__) && __GNUC__ >= 3
+__attribute__((__noreturn__))
+#endif
+static void yy_fatal_error (yyconst char msg[]  );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+	(yytext_ptr) = yy_bp; \
+	yyleng = (size_t) (yy_cp - yy_bp); \
+	(yy_hold_char) = *yy_cp; \
+	*yy_cp = '\0'; \
+	if ( yyleng >= YYLMAX ) \
+		YY_FATAL_ERROR( "token too large, exceeds YYLMAX" ); \
+	yy_flex_strncpy( yytext, (yytext_ptr), yyleng + 1 ); \
+	(yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 98
+#define YY_END_OF_BUFFER 99
+/* This struct is not used in this scanner,
+   but its presence is necessary. */
+struct yy_trans_info
+	{
+	flex_int32_t yy_verify;
+	flex_int32_t yy_nxt;
+	};
+static yyconst flex_int16_t yy_accept[310] =
+    {   0,
+       92,   92,    0,    0,   99,   97,   96,   96,    1,   97,
+       97,   30,   92,   97,   92,   26,   91,   91,   91,   91,
+       91,   91,   91,   91,   91,   91,   91,   91,   91,   91,
+       91,   91,   91,   91,   24,   25,    7,    6,    7,    0,
+       94,    0,   92,    4,    0,   91,    0,   91,   95,   91,
+       91,   91,   91,   91,   91,   91,   91,   91,   91,   91,
+       91,   91,   91,   91,   91,   91,   91,   91,   91,   91,
+       91,   91,   91,   46,   91,   91,   91,   91,   91,   91,
+       11,   91,   91,   91,   91,   45,   91,   91,   91,   91,
+       91,   91,   50,   91,    5,   93,    0,    2,   32,   60,
+
+       91,   91,   37,   91,   91,   91,   34,   82,   91,   91,
+       91,   91,   19,   91,   91,   91,   91,   16,   91,   54,
+       91,   91,   41,   64,   91,   91,   91,   91,   91,   91,
+       91,   91,   52,   91,   91,   91,   91,   91,   91,   91,
+       91,   91,   13,    8,   91,   91,   15,   91,   28,   38,
+       78,   88,   91,   91,   91,   91,   57,   91,   65,   29,
+       72,   91,   91,   91,   14,   68,   91,   91,   91,   21,
+       47,   89,   40,   27,   91,   84,   70,   91,   91,   91,
+       91,   91,   91,   48,   91,   91,   91,   80,   91,   20,
+       86,   91,   91,   91,    9,   91,   91,   44,   75,   58,
+
+       91,   91,   90,   91,   91,   91,   91,   36,   91,   91,
+       91,   91,   91,   23,   91,   91,   74,   91,   51,   91,
+       91,   91,   91,   91,   91,   91,   91,   91,   91,   91,
+       39,   91,   91,   91,   91,   91,   91,   91,   31,   91,
+       91,   91,   91,   81,   42,   91,   18,   61,   91,   66,
+       91,   91,   91,   91,   76,   91,   91,   55,   91,   17,
+       91,   10,   12,   91,   77,   91,   91,   91,   91,   71,
+       33,   67,   53,   91,   91,   91,   91,   22,   91,   91,
+       91,   35,   43,   91,   91,   91,   91,   91,   83,   91,
+       63,   79,   91,    0,   87,   91,   59,   91,   73,   69,
+
+       91,    0,    0,    3,   91,   56,   85,   49,    0
+    } ;
+
+static yyconst YY_CHAR yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    4,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    5,    1,    6,    1,    1,    1,    1,    7,    1,
+        1,    8,    9,    1,    9,   10,   11,   12,   12,   12,
+       12,   12,   12,   12,   12,   12,   12,    1,   13,    1,
+        1,    1,    1,    1,   14,   14,   14,   14,   14,   14,
+       15,   15,   15,   15,   15,   15,   15,   15,   15,   15,
+       15,   15,   15,   15,   15,   15,   15,   15,   15,   15,
+       16,   17,   18,   17,   19,   17,   20,   21,   22,   23,
+
+       24,   25,   26,   27,   28,   15,   29,   30,   31,   32,
+       33,   34,   35,   36,   37,   38,   39,   40,   41,   42,
+       43,   15,   44,    1,   45,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst YY_CHAR yy_meta[46] =
+    {   0,
+        1,    1,    1,    1,    2,    1,    1,    1,    1,    3,
+        3,    4,    1,    4,    5,    1,    1,    2,    5,    4,
+        4,    4,    4,    4,    4,    5,    5,    5,    5,    5,
+        5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
+        5,    5,    5,    1,    1
+    } ;
+
+static yyconst flex_uint16_t yy_base[317] =
+    {   0,
+        0,    0,   43,   44,  359,  360,  360,  360,  360,  352,
+        0,  360,  345,   42,  344,  360,    0,   49,   26,   22,
+       55,   26,   46,  335,  330,   69,  328,   61,   53,   59,
+       65,  324,   79,   78,  360,  360,  360,  360,  340,  344,
+      360,  342,  336,  360,  344,    0,  328,    0,  360,  307,
+      318,  305,   36,  308,  303,   85,  308,  307,  316,  301,
+      302,  307,  314,  300,  295,  288,  299,  304,  304,   78,
+      103,  293,  302,  300,  287,  287,  292,  293,  284,   70,
+        0,   94,  280,  292,  279,    0,  282,  292,  278,  277,
+      282,  273,    0,  282,  360,  360,  306,  360,  280,  274,
+
+      270,  283,    0,  261,  283,  266,  277,  272,  279,  274,
+      261,  263,   71,  265,  268,  262,  265,    0,  267,    0,
+       95,  268,    0,    0,   97,  256,  264,   86,  263,  258,
+      258,  260,    0,  247,  245,  244,  243,  251,  246,  243,
+      253,  242,  235,    0,  248,  240,    0,  247,    0,    0,
+      242,  249,  241,  229,  226,  229,  236,  234,    0,    0,
+      219,  223,  220,  228,    0,  215,  221,  234,  219,    0,
+        0,    0,    0,    0,  218,    0,    0,  220,  218,  217,
+      101,  228,  215,    0,  222,  219,  210,    0,  221,    0,
+      216,  221,  204,  208,    0,  200,  203,  213,    0,    0,
+
+      212,  198,    0,  211,  210,  205,  211,    0,  197,  206,
+      205,  204,  193,    0,  188,  187,    0,  192,    0,  180,
+      186,  193,  184,  186,  186,  185,  188,  177,  177,  170,
+        0,  175,  187,  186,  179,  165,  179,  187,    0,  167,
+      165,  165,  179,    0,    0,  163,    0,    0,  175,    0,
+      156,  158,  154,  160,    0,  169,  169,    0,  155,    0,
+      168,  168,    0,  166,    0,  159,  155,  160,  148,    0,
+        0,    0,    0,  151,  160,  143,  116,    0,  109,  127,
+      134,    0,    0,  126,  117,  117,  122,  100,    0,   96,
+        0,    0,   98,  140,    0,  107,    0,   87,    0,    0,
+
+       40,   46,  142,  360,   33,    0,    0,    0,  360,  155,
+      160,  163,  165,  170,  174,  178
+    } ;
+
+static yyconst flex_int16_t yy_def[317] =
+    {   0,
+      309,    1,  310,  310,  309,  309,  309,  309,  309,  311,
+      312,  309,  309,  309,  309,  309,  313,  313,  313,  313,
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+      313,  313,  313,  313,  309,  309,  309,  309,  309,  311,
+      309,  312,  309,  309,  314,  313,  315,   18,  309,  313,
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+      313,  313,  313,  313,  309,  309,  314,  309,  313,  313,
+
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+      313,  313,  313,  313,  313,  313,  313,  313,  313,  313,
+      313,  313,  313,  316,  313,  313,  313,  313,  313,  313,
+
+      313,  316,  316,  309,  313,  313,  313,  313,    0,  309,
+      309,  309,  309,  309,  309,  309
+    } ;
+
+static yyconst flex_uint16_t yy_nxt[406] =
+    {   0,
+        6,    7,    8,    9,    7,   10,   11,   12,   13,    6,
+       14,   15,   16,   17,   17,   18,   17,   17,   17,   19,
+       17,   20,   21,   22,   23,   17,   24,   17,   25,   17,
+       17,   26,   27,   28,   17,   29,   30,   31,   32,   33,
+       34,   17,   17,   35,   36,   38,   38,   50,   53,   44,
+       39,   39,   45,   47,   54,   51,  308,   59,  304,  102,
+       48,   60,   48,   52,  103,   62,   49,   61,   48,   48,
+       48,   48,   48,   48,   55,   63,   80,  307,   56,   57,
+       75,   64,   82,   81,   76,   83,   84,   58,   67,  141,
+       68,   69,   70,   77,  168,   85,   78,   86,   89,   79,
+
+      142,   71,   90,  169,   72,   92,  106,   87,   73,  122,
+       93,   91,  123,   94,  107,  143,  175,  182,  178,  124,
+      108,  125,  221,  306,  126,  127,  128,  183,  305,  301,
+      176,  144,  179,  300,  129,  294,  222,  299,  294,  130,
+      131,  303,  132,  303,  303,  298,  303,  297,  296,  295,
+      293,  292,  304,  291,  304,   37,   37,   37,   37,   37,
+       40,   40,   40,   40,   40,   42,   42,   42,   46,   46,
+       97,   97,   97,   97,   97,   47,  290,   47,  302,  302,
+      302,  302,  302,  289,  288,  287,  286,  285,  284,  283,
+      282,  281,  280,  279,  278,  277,  276,  275,  274,  273,
+
+      272,  271,  270,  269,  268,  267,  266,  265,  264,  263,
+      262,  261,  260,  259,  258,  257,  256,  255,  254,  253,
+      252,  251,  250,  249,  248,  247,  246,  245,  244,  243,
+      242,  241,  240,  239,  238,  237,  236,  235,  234,  233,
+      232,  231,  230,  229,  228,  227,  226,  225,  224,  223,
+      220,  219,  218,  217,  216,  215,  214,  213,  212,  211,
+      210,  209,  208,  207,  206,  205,  204,  203,  202,  201,
+      200,  199,  198,  197,  196,  195,  194,  193,  192,  191,
+      190,  189,  188,  187,  186,  185,  184,  181,  180,  177,
+      174,  173,  172,  171,  170,  167,  166,  165,  164,  163,
+
+      162,  161,  160,  159,  158,  157,  156,  155,   98,  154,
+      153,  152,  151,  150,  149,  148,  147,  146,  145,  140,
+      139,  138,  137,  136,  135,  134,  133,  121,  120,  119,
+      118,  117,  116,  115,  114,  113,  112,  111,  110,  109,
+      105,  104,  101,  100,   99,   49,   98,   43,   96,   41,
+       95,   88,   74,   66,   65,   43,   43,   41,  309,    5,
+      309,  309,  309,  309,  309,  309,  309,  309,  309,  309,
+      309,  309,  309,  309,  309,  309,  309,  309,  309,  309,
+      309,  309,  309,  309,  309,  309,  309,  309,  309,  309,
+      309,  309,  309,  309,  309,  309,  309,  309,  309,  309,
+
+      309,  309,  309,  309,  309
+    } ;
+
+static yyconst flex_int16_t yy_chk[406] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    3,    4,   19,   20,   14,
+        3,    4,   14,   18,   20,   19,  305,   22,  302,   53,
+       18,   22,   18,   19,   53,   23,   18,   22,   18,   18,
+       18,   18,   18,   18,   21,   23,   29,  301,   21,   21,
+       28,   23,   30,   29,   28,   30,   30,   21,   26,   80,
+       26,   26,   26,   28,  113,   30,   28,   31,   33,   28,
+
+       80,   26,   33,  113,   26,   34,   56,   31,   26,   70,
+       34,   33,   70,   34,   56,   82,  121,  128,  125,   70,
+       56,   71,  181,  298,   71,   71,   71,  128,  296,  293,
+      121,   82,  125,  290,   71,  281,  181,  288,  281,   71,
+       71,  294,   71,  303,  294,  287,  303,  286,  285,  284,
+      280,  279,  294,  277,  303,  310,  310,  310,  310,  310,
+      311,  311,  311,  311,  311,  312,  312,  312,  313,  313,
+      314,  314,  314,  314,  314,  315,  276,  315,  316,  316,
+      316,  316,  316,  275,  274,  269,  268,  267,  266,  264,
+      262,  261,  259,  257,  256,  254,  253,  252,  251,  249,
+
+      246,  243,  242,  241,  240,  238,  237,  236,  235,  234,
+      233,  232,  230,  229,  228,  227,  226,  225,  224,  223,
+      222,  221,  220,  218,  216,  215,  213,  212,  211,  210,
+      209,  207,  206,  205,  204,  202,  201,  198,  197,  196,
+      194,  193,  192,  191,  189,  187,  186,  185,  183,  182,
+      180,  179,  178,  175,  169,  168,  167,  166,  164,  163,
+      162,  161,  158,  157,  156,  155,  154,  153,  152,  151,
+      148,  146,  145,  143,  142,  141,  140,  139,  138,  137,
+      136,  135,  134,  132,  131,  130,  129,  127,  126,  122,
+      119,  117,  116,  115,  114,  112,  111,  110,  109,  108,
+
+      107,  106,  105,  104,  102,  101,  100,   99,   97,   94,
+       92,   91,   90,   89,   88,   87,   85,   84,   83,   79,
+       78,   77,   76,   75,   74,   73,   72,   69,   68,   67,
+       66,   65,   64,   63,   62,   61,   60,   59,   58,   57,
+       55,   54,   52,   51,   50,   47,   45,   43,   42,   40,
+       39,   32,   27,   25,   24,   15,   13,   10,    5,  309,
+      309,  309,  309,  309,  309,  309,  309,  309,  309,  309,
+      309,  309,  309,  309,  309,  309,  309,  309,  309,  309,
+      309,  309,  309,  309,  309,  309,  309,  309,  309,  309,
+      309,  309,  309,  309,  309,  309,  309,  309,  309,  309,
+
+      309,  309,  309,  309,  309
+    } ;
+
+/* Table of booleans, true if rule could match eol. */
+static yyconst flex_int32_t yy_rule_can_match_eol[99] =
+    {   0,
+0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0,     };
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int yy_flex_debug;
+int yy_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+#ifndef YYLMAX
+#define YYLMAX 8192
+#endif
+
+char yytext[YYLMAX];
+char *yytext_ptr;
+#line 1 "parser/tf_fuzz_grammar.l"
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#line 10 "parser/tf_fuzz_grammar.l"
+#include "class_forwards.hpp"
+#include "boilerplate.hpp"
+#include "gibberish.hpp"
+#include "compute.hpp"
+#include "string_ops.hpp"
+#include "data_blocks.hpp"
+#include "psa_asset.hpp"
+#include "sst_asset.hpp"
+#include "crypto_asset.hpp"
+#include "find_or_create_asset.hpp"
+#include "template_line.hpp"
+#include "tf_fuzz.hpp"
+#include "psa_call.hpp"
+#include "tf_fuzz_grammar.tab.hpp"
+
+int yycolumn = 1;
+
+//char *yytext;
+
+#define YY_USER_ACTION yylloc.first_line = yylloc.last_line = yylineno; \
+    yylloc.first_column = yycolumn; yylloc.last_column = yycolumn + yyleng - 1; \
+    yycolumn += yyleng; \
+    yylval.str = strdup(yytext);
+
+void yyerror (tf_fuzz_info *, const char *str)
+    /* not sure why it sends the yyparse() argument to yyerror(), but OK... */
+{
+    fprintf (stderr, "tf_fuzz template on line %d, at text = \"%s\":  %s\n",
+            yylineno, yytext, str);
+    exit (1);
+}
+
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+
+#line 738 "parser/tf_fuzz_grammar.lex.c"
+
+#define INITIAL 0
+#define BLOCK_COMMENT 1
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Accessor methods to globals.
+   These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy (void );
+
+int yyget_debug (void );
+
+void yyset_debug (int debug_flag  );
+
+YY_EXTRA_TYPE yyget_extra (void );
+
+void yyset_extra (YY_EXTRA_TYPE user_defined  );
+
+FILE *yyget_in (void );
+
+void yyset_in  (FILE * _in_str  );
+
+FILE *yyget_out (void );
+
+void yyset_out  (FILE * _out_str  );
+
+yy_size_t yyget_leng (void );
+
+char *yyget_text (void );
+
+int yyget_lineno (void );
+
+void yyset_lineno (int _line_number  );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap (void );
+#else
+extern int yywrap (void );
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+    
+    static void yyunput (int c,char *buf_ptr  );
+    
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+		{ \
+		int c = '*'; \
+		size_t n; \
+		for ( n = 0; n < max_size && \
+			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+			buf[n] = (char) c; \
+		if ( c == '\n' ) \
+			buf[n++] = (char) c; \
+		if ( c == EOF && ferror( yyin ) ) \
+			YY_FATAL_ERROR( "input in flex scanner failed" ); \
+		result = n; \
+		} \
+	else \
+		{ \
+		errno=0; \
+		while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+			{ \
+			if( errno != EINTR) \
+				{ \
+				YY_FATAL_ERROR( "input in flex scanner failed" ); \
+				break; \
+				} \
+			errno=0; \
+			clearerr(yyin); \
+			} \
+		}\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex (void);
+
+#define YY_DECL int yylex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK /*LINTED*/break;
+#endif
+
+#define YY_RULE_SETUP \
+	YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+	yy_state_type yy_current_state;
+	char *yy_cp, *yy_bp;
+	int yy_act;
+    
+	if ( !(yy_init) )
+		{
+		(yy_init) = 1;
+
+#ifdef YY_USER_INIT
+		YY_USER_INIT;
+#endif
+
+		if ( ! (yy_start) )
+			(yy_start) = 1;	/* first start state */
+
+		if ( ! yyin )
+			yyin = stdin;
+
+		if ( ! yyout )
+			yyout = stdout;
+
+		if ( ! YY_CURRENT_BUFFER ) {
+			yyensure_buffer_stack ();
+			YY_CURRENT_BUFFER_LVALUE =
+				yy_create_buffer(yyin,YY_BUF_SIZE );
+		}
+
+		yy_load_buffer_state( );
+		}
+
+	{
+#line 55 "parser/tf_fuzz_grammar.l"
+
+
+#line 960 "parser/tf_fuzz_grammar.lex.c"
+
+	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
+		{
+		yy_cp = (yy_c_buf_p);
+
+		/* Support of yytext. */
+		*yy_cp = (yy_hold_char);
+
+		/* yy_bp points to the position in yy_ch_buf of the start of
+		 * the current run.
+		 */
+		yy_bp = yy_cp;
+
+		yy_current_state = (yy_start);
+yy_match:
+		do
+			{
+			YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
+			if ( yy_accept[yy_current_state] )
+				{
+				(yy_last_accepting_state) = yy_current_state;
+				(yy_last_accepting_cpos) = yy_cp;
+				}
+			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+				{
+				yy_current_state = (int) yy_def[yy_current_state];
+				if ( yy_current_state >= 310 )
+					yy_c = yy_meta[(unsigned int) yy_c];
+				}
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+			++yy_cp;
+			}
+		while ( yy_base[yy_current_state] != 360 );
+
+yy_find_action:
+		yy_act = yy_accept[yy_current_state];
+		if ( yy_act == 0 )
+			{ /* have to back up */
+			yy_cp = (yy_last_accepting_cpos);
+			yy_current_state = (yy_last_accepting_state);
+			yy_act = yy_accept[yy_current_state];
+			}
+
+		YY_DO_BEFORE_ACTION;
+
+		if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
+			{
+			yy_size_t yyl;
+			for ( yyl = 0; yyl < yyleng; ++yyl )
+				if ( yytext[yyl] == '\n' )
+					   
+    yylineno++;
+;
+			}
+
+do_action:	/* This label is used only to access EOF actions. */
+
+		switch ( yy_act )
+	{ /* beginning of action switch */
+			case 0: /* must back up */
+			/* undo the effects of YY_DO_BEFORE_ACTION */
+			*yy_cp = (yy_hold_char);
+			yy_cp = (yy_last_accepting_cpos);
+			yy_current_state = (yy_last_accepting_state);
+			goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 57 "parser/tf_fuzz_grammar.l"
+;   /* ignore all \r */
+	YY_BREAK
+case 2:
+/* rule 2 can match eol */
+YY_RULE_SETUP
+#line 58 "parser/tf_fuzz_grammar.l"
+;   /* ignore C++-style line comments */
+	YY_BREAK
+case 3:
+/* rule 3 can match eol */
+YY_RULE_SETUP
+#line 59 "parser/tf_fuzz_grammar.l"
+return PURPOSE;
+	YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 60 "parser/tf_fuzz_grammar.l"
+{BEGIN(BLOCK_COMMENT);}
+	YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 61 "parser/tf_fuzz_grammar.l"
+{BEGIN(INITIAL);}
+	YY_BREAK
+case 6:
+/* rule 6 can match eol */
+YY_RULE_SETUP
+#line 62 "parser/tf_fuzz_grammar.l"
+;
+	YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 63 "parser/tf_fuzz_grammar.l"
+;
+	YY_BREAK
+/* Root commands: */
+case 8:
+YY_RULE_SETUP
+#line 65 "parser/tf_fuzz_grammar.l"
+return SET;
+	YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 66 "parser/tf_fuzz_grammar.l"
+return READ;
+	YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 67 "parser/tf_fuzz_grammar.l"
+return REMOVE;
+	YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 68 "parser/tf_fuzz_grammar.l"
+return REMOVE;
+	YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 69 "parser/tf_fuzz_grammar.l"
+return SECURE;
+	YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 70 "parser/tf_fuzz_grammar.l"
+return SECURE;
+	YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 71 "parser/tf_fuzz_grammar.l"
+return DONE;
+	YY_BREAK
+/* PSA-asset types: */
+case 15:
+YY_RULE_SETUP
+#line 73 "parser/tf_fuzz_grammar.l"
+return SST;
+	YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 74 "parser/tf_fuzz_grammar.l"
+return KEY;
+	YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 75 "parser/tf_fuzz_grammar.l"
+return POLICY;
+	YY_BREAK
+/* Other root-command operands: */
+case 18:
+YY_RULE_SETUP
+#line 77 "parser/tf_fuzz_grammar.l"
+return EXPECT;
+	YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 78 "parser/tf_fuzz_grammar.l"
+return EXPECT;
+	YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 79 "parser/tf_fuzz_grammar.l"
+return PASS;
+	YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 80 "parser/tf_fuzz_grammar.l"
+return FAIL;
+	YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 81 "parser/tf_fuzz_grammar.l"
+return NOTHING;
+	YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 82 "parser/tf_fuzz_grammar.l"
+return ERROR;
+	YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 83 "parser/tf_fuzz_grammar.l"
+return OPEN_BRACE;
+	YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 84 "parser/tf_fuzz_grammar.l"
+return CLOSE_BRACE;
+	YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 85 "parser/tf_fuzz_grammar.l"
+return SEMICOLON;
+	YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 86 "parser/tf_fuzz_grammar.l"
+return NAME;
+	YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 87 "parser/tf_fuzz_grammar.l"
+return UID;
+	YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 88 "parser/tf_fuzz_grammar.l"
+return DATA;
+	YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 89 "parser/tf_fuzz_grammar.l"
+return STAR;
+	YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 90 "parser/tf_fuzz_grammar.l"
+return ACTIVE;
+	YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 91 "parser/tf_fuzz_grammar.l"
+return ACTIVE;
+	YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 92 "parser/tf_fuzz_grammar.l"
+return DELETED;
+	YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 93 "parser/tf_fuzz_grammar.l"
+return DELETED;
+	YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 94 "parser/tf_fuzz_grammar.l"
+return DELETED;
+	YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 95 "parser/tf_fuzz_grammar.l"
+return CHECK;
+	YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 96 "parser/tf_fuzz_grammar.l"
+return CHECK;
+	YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 97 "parser/tf_fuzz_grammar.l"
+return VAR;
+	YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 98 "parser/tf_fuzz_grammar.l"
+return PRINT;
+	YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 99 "parser/tf_fuzz_grammar.l"
+return HASH;
+	YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 100 "parser/tf_fuzz_grammar.l"
+return NEQ;
+	YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 101 "parser/tf_fuzz_grammar.l"
+return DFNAME;
+	YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 102 "parser/tf_fuzz_grammar.l"
+return SHUFFLE;
+	YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 103 "parser/tf_fuzz_grammar.l"
+return SHUFFLE;
+	YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 104 "parser/tf_fuzz_grammar.l"
+return TO;
+	YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 105 "parser/tf_fuzz_grammar.l"
+return OF;
+	YY_BREAK
+/* SST creation keywords: */
+case 47:
+YY_RULE_SETUP
+#line 107 "parser/tf_fuzz_grammar.l"
+return FLAG;
+	YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 108 "parser/tf_fuzz_grammar.l"
+return NONE;
+	YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 109 "parser/tf_fuzz_grammar.l"
+return WRITE_ONCE;
+	YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 110 "parser/tf_fuzz_grammar.l"
+return WRITE_ONCE;
+	YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 111 "parser/tf_fuzz_grammar.l"
+return NO_RP;
+	YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 112 "parser/tf_fuzz_grammar.l"
+return NO_RP;
+	YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 113 "parser/tf_fuzz_grammar.l"
+return NO_CONF;
+	YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 114 "parser/tf_fuzz_grammar.l"
+return NO_CONF;
+	YY_BREAK
+/* Offset into an SST asset */
+case 55:
+YY_RULE_SETUP
+#line 116 "parser/tf_fuzz_grammar.l"
+return OFFSET;
+	YY_BREAK
+/* Policy keywords: */
+case 56:
+YY_RULE_SETUP
+#line 118 "parser/tf_fuzz_grammar.l"
+return ATTR;
+	YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 119 "parser/tf_fuzz_grammar.l"
+return ATTR;
+	YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 120 "parser/tf_fuzz_grammar.l"
+return TYPE;
+	YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 121 "parser/tf_fuzz_grammar.l"
+return ALG;
+	YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 122 "parser/tf_fuzz_grammar.l"
+return ALG;
+	YY_BREAK
+/* Policy-usage and -lifetime keywords: */
+case 61:
+YY_RULE_SETUP
+#line 124 "parser/tf_fuzz_grammar.l"
+return EXPORT;
+	YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 125 "parser/tf_fuzz_grammar.l"
+return EXPORT;
+	YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 126 "parser/tf_fuzz_grammar.l"
+return NOEXPORT;
+	YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 127 "parser/tf_fuzz_grammar.l"
+return NOEXPORT;
+	YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 128 "parser/tf_fuzz_grammar.l"
+return COPY;
+	YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 129 "parser/tf_fuzz_grammar.l"
+return NOCOPY;
+	YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 130 "parser/tf_fuzz_grammar.l"
+return ENCRYPT;
+	YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 131 "parser/tf_fuzz_grammar.l"
+return ENCRYPT;
+	YY_BREAK
+case 69:
+YY_RULE_SETUP
+#line 132 "parser/tf_fuzz_grammar.l"
+return NOENCRYPT;
+	YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 133 "parser/tf_fuzz_grammar.l"
+return NOENCRYPT;
+	YY_BREAK
+case 71:
+YY_RULE_SETUP
+#line 134 "parser/tf_fuzz_grammar.l"
+return DECRYPT;
+	YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 135 "parser/tf_fuzz_grammar.l"
+return DECRYPT;
+	YY_BREAK
+case 73:
+YY_RULE_SETUP
+#line 136 "parser/tf_fuzz_grammar.l"
+return NODECRYPT;
+	YY_BREAK
+case 74:
+YY_RULE_SETUP
+#line 137 "parser/tf_fuzz_grammar.l"
+return NODECRYPT;
+	YY_BREAK
+case 75:
+YY_RULE_SETUP
+#line 138 "parser/tf_fuzz_grammar.l"
+return SIGN;
+	YY_BREAK
+case 76:
+YY_RULE_SETUP
+#line 139 "parser/tf_fuzz_grammar.l"
+return NOSIGN;
+	YY_BREAK
+case 77:
+YY_RULE_SETUP
+#line 140 "parser/tf_fuzz_grammar.l"
+return VERIFY;
+	YY_BREAK
+case 78:
+YY_RULE_SETUP
+#line 141 "parser/tf_fuzz_grammar.l"
+return VERIFY;
+	YY_BREAK
+case 79:
+YY_RULE_SETUP
+#line 142 "parser/tf_fuzz_grammar.l"
+return NOVERIFY;
+	YY_BREAK
+case 80:
+YY_RULE_SETUP
+#line 143 "parser/tf_fuzz_grammar.l"
+return NOVERIFY;
+	YY_BREAK
+case 81:
+YY_RULE_SETUP
+#line 144 "parser/tf_fuzz_grammar.l"
+return DERIVE;
+	YY_BREAK
+case 82:
+YY_RULE_SETUP
+#line 145 "parser/tf_fuzz_grammar.l"
+return DERIVE;
+	YY_BREAK
+case 83:
+YY_RULE_SETUP
+#line 146 "parser/tf_fuzz_grammar.l"
+return NODERIVE;
+	YY_BREAK
+case 84:
+YY_RULE_SETUP
+#line 147 "parser/tf_fuzz_grammar.l"
+return NODERIVE;
+	YY_BREAK
+case 85:
+YY_RULE_SETUP
+#line 148 "parser/tf_fuzz_grammar.l"
+return PERSISTENT;
+	YY_BREAK
+case 86:
+YY_RULE_SETUP
+#line 149 "parser/tf_fuzz_grammar.l"
+return PERSISTENT;
+	YY_BREAK
+case 87:
+YY_RULE_SETUP
+#line 150 "parser/tf_fuzz_grammar.l"
+return VOLATILE;
+	YY_BREAK
+case 88:
+YY_RULE_SETUP
+#line 151 "parser/tf_fuzz_grammar.l"
+return VOLATILE;
+	YY_BREAK
+case 89:
+YY_RULE_SETUP
+#line 152 "parser/tf_fuzz_grammar.l"
+return FROM;
+	YY_BREAK
+case 90:
+YY_RULE_SETUP
+#line 153 "parser/tf_fuzz_grammar.l"
+return WITH;
+	YY_BREAK
+/* Structure operands: */
+case 91:
+YY_RULE_SETUP
+#line 155 "parser/tf_fuzz_grammar.l"
+{yylval.str = yytext; return IDENTIFIER_TOK;}
+	YY_BREAK
+case 92:
+YY_RULE_SETUP
+#line 156 "parser/tf_fuzz_grammar.l"
+{yylval.valueN = atol(yytext); return NUMBER_TOK;}
+	YY_BREAK
+case 93:
+YY_RULE_SETUP
+#line 157 "parser/tf_fuzz_grammar.l"
+{yylval.str = yytext; return FILE_PATH_TOK;}
+	YY_BREAK
+case 94:
+/* rule 94 can match eol */
+YY_RULE_SETUP
+#line 158 "parser/tf_fuzz_grammar.l"
+{yylval.str = yytext; return LITERAL_TOK;}
+	YY_BREAK
+case 95:
+YY_RULE_SETUP
+#line 159 "parser/tf_fuzz_grammar.l"
+{yylval.str = yytext; return HEX_LIST;}
+	YY_BREAK
+/* inside quotes:  anything but a quote, or nothing */
+case 96:
+/* rule 96 can match eol */
+YY_RULE_SETUP
+#line 161 "parser/tf_fuzz_grammar.l"
+;   /* ignore white space */
+	YY_BREAK
+case 97:
+YY_RULE_SETUP
+#line 162 "parser/tf_fuzz_grammar.l"
+yyerror ((tf_fuzz_info *) NULL, "Unexpected character");
+	YY_BREAK
+case 98:
+YY_RULE_SETUP
+#line 164 "parser/tf_fuzz_grammar.l"
+YY_FATAL_ERROR( "flex scanner jammed" );
+	YY_BREAK
+#line 1531 "parser/tf_fuzz_grammar.lex.c"
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(BLOCK_COMMENT):
+	yyterminate();
+
+	case YY_END_OF_BUFFER:
+		{
+		/* Amount of text matched not including the EOB char. */
+		int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+		/* Undo the effects of YY_DO_BEFORE_ACTION. */
+		*yy_cp = (yy_hold_char);
+		YY_RESTORE_YY_MORE_OFFSET
+
+		if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+			{
+			/* We're scanning a new file or input source.  It's
+			 * possible that this happened because the user
+			 * just pointed yyin at a new source and called
+			 * yylex().  If so, then we have to assure
+			 * consistency between YY_CURRENT_BUFFER and our
+			 * globals.  Here is the right place to do so, because
+			 * this is the first action (other than possibly a
+			 * back-up) that will match for the new input source.
+			 */
+			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+			YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+			}
+
+		/* Note that here we test for yy_c_buf_p "<=" to the position
+		 * of the first EOB in the buffer, since yy_c_buf_p will
+		 * already have been incremented past the NUL character
+		 * (since all states make transitions on EOB to the
+		 * end-of-buffer state).  Contrast this with the test
+		 * in input().
+		 */
+		if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+			{ /* This was really a NUL. */
+			yy_state_type yy_next_state;
+
+			(yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+			yy_current_state = yy_get_previous_state(  );
+
+			/* Okay, we're now positioned to make the NUL
+			 * transition.  We couldn't have
+			 * yy_get_previous_state() go ahead and do it
+			 * for us because it doesn't know how to deal
+			 * with the possibility of jamming (and we don't
+			 * want to build jamming into it because then it
+			 * will run more slowly).
+			 */
+
+			yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+			yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+			if ( yy_next_state )
+				{
+				/* Consume the NUL. */
+				yy_cp = ++(yy_c_buf_p);
+				yy_current_state = yy_next_state;
+				goto yy_match;
+				}
+
+			else
+				{
+				yy_cp = (yy_c_buf_p);
+				goto yy_find_action;
+				}
+			}
+
+		else switch ( yy_get_next_buffer(  ) )
+			{
+			case EOB_ACT_END_OF_FILE:
+				{
+				(yy_did_buffer_switch_on_eof) = 0;
+
+				if ( yywrap( ) )
+					{
+					/* Note: because we've taken care in
+					 * yy_get_next_buffer() to have set up
+					 * yytext, we can now set up
+					 * yy_c_buf_p so that if some total
+					 * hoser (like flex itself) wants to
+					 * call the scanner after we return the
+					 * YY_NULL, it'll still work - another
+					 * YY_NULL will get returned.
+					 */
+					(yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+					yy_act = YY_STATE_EOF(YY_START);
+					goto do_action;
+					}
+
+				else
+					{
+					if ( ! (yy_did_buffer_switch_on_eof) )
+						YY_NEW_FILE;
+					}
+				break;
+				}
+
+			case EOB_ACT_CONTINUE_SCAN:
+				(yy_c_buf_p) =
+					(yytext_ptr) + yy_amount_of_matched_text;
+
+				yy_current_state = yy_get_previous_state(  );
+
+				yy_cp = (yy_c_buf_p);
+				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+				goto yy_match;
+
+			case EOB_ACT_LAST_MATCH:
+				(yy_c_buf_p) =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+				yy_current_state = yy_get_previous_state(  );
+
+				yy_cp = (yy_c_buf_p);
+				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+				goto yy_find_action;
+			}
+		break;
+		}
+
+	default:
+		YY_FATAL_ERROR(
+			"fatal flex scanner internal error--no action found" );
+	} /* end of action switch */
+		} /* end of scanning one token */
+	} /* end of user's declarations */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+    	char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+	char *source = (yytext_ptr);
+	yy_size_t number_to_move, i;
+	int ret_val;
+
+	if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+		YY_FATAL_ERROR(
+		"fatal flex scanner internal error--end of buffer missed" );
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+		{ /* Don't try to fill the buffer, so this is an EOF. */
+		if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+			{
+			/* We matched a single character, the EOB, so
+			 * treat this as a final EOF.
+			 */
+			return EOB_ACT_END_OF_FILE;
+			}
+
+		else
+			{
+			/* We matched some text prior to the EOB, first
+			 * process it.
+			 */
+			return EOB_ACT_LAST_MATCH;
+			}
+		}
+
+	/* Try to read more data. */
+
+	/* First move last chars to start of buffer. */
+	number_to_move = (yy_size_t) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+	for ( i = 0; i < number_to_move; ++i )
+		*(dest++) = *(source++);
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+		/* don't do the read, it's not guaranteed to return an EOF,
+		 * just force an EOF
+		 */
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+	else
+		{
+			yy_size_t num_to_read =
+			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+		while ( num_to_read <= 0 )
+			{ /* Not enough room in the buffer - grow it. */
+
+			/* just a shorter name for the current buffer */
+			YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
+
+			int yy_c_buf_p_offset =
+				(int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+			if ( b->yy_is_our_buffer )
+				{
+				yy_size_t new_size = b->yy_buf_size * 2;
+
+				if ( new_size <= 0 )
+					b->yy_buf_size += b->yy_buf_size / 8;
+				else
+					b->yy_buf_size *= 2;
+
+				b->yy_ch_buf = (char *)
+					/* Include room in for 2 EOB chars. */
+					yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+				}
+			else
+				/* Can't grow it, we don't own it. */
+				b->yy_ch_buf = 0;
+
+			if ( ! b->yy_ch_buf )
+				YY_FATAL_ERROR(
+				"fatal error - scanner input buffer overflow" );
+
+			(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+						number_to_move - 1;
+
+			}
+
+		if ( num_to_read > YY_READ_BUF_SIZE )
+			num_to_read = YY_READ_BUF_SIZE;
+
+		/* Read in more data. */
+		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+			(yy_n_chars), num_to_read );
+
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	if ( (yy_n_chars) == 0 )
+		{
+		if ( number_to_move == YY_MORE_ADJ )
+			{
+			ret_val = EOB_ACT_END_OF_FILE;
+			yyrestart(yyin  );
+			}
+
+		else
+			{
+			ret_val = EOB_ACT_LAST_MATCH;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+				YY_BUFFER_EOF_PENDING;
+			}
+		}
+
+	else
+		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	if ((int) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+		/* Extend the array by 50%, plus the number we really need. */
+		int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
+		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+	}
+
+	(yy_n_chars) += number_to_move;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+	(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+	return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+    static yy_state_type yy_get_previous_state (void)
+{
+	yy_state_type yy_current_state;
+	char *yy_cp;
+    
+	yy_current_state = (yy_start);
+
+	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+		{
+		YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+		if ( yy_accept[yy_current_state] )
+			{
+			(yy_last_accepting_state) = yy_current_state;
+			(yy_last_accepting_cpos) = yy_cp;
+			}
+		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+			{
+			yy_current_state = (int) yy_def[yy_current_state];
+			if ( yy_current_state >= 310 )
+				yy_c = yy_meta[(unsigned int) yy_c];
+			}
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+		}
+
+	return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *	next_state = yy_try_NUL_trans( current_state );
+ */
+    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
+{
+	int yy_is_jam;
+    	char *yy_cp = (yy_c_buf_p);
+
+	YY_CHAR yy_c = 1;
+	if ( yy_accept[yy_current_state] )
+		{
+		(yy_last_accepting_state) = yy_current_state;
+		(yy_last_accepting_cpos) = yy_cp;
+		}
+	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+		{
+		yy_current_state = (int) yy_def[yy_current_state];
+		if ( yy_current_state >= 310 )
+			yy_c = yy_meta[(unsigned int) yy_c];
+		}
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+	yy_is_jam = (yy_current_state == 309);
+
+		return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_UNPUT
+
+    static void yyunput (int c, char * yy_bp )
+{
+	char *yy_cp;
+    
+    yy_cp = (yy_c_buf_p);
+
+	/* undo effects of setting up yytext */
+	*yy_cp = (yy_hold_char);
+
+	if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+		{ /* need to shift things up to make room */
+		/* +2 for EOB chars. */
+		yy_size_t number_to_move = (yy_n_chars) + 2;
+		char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+					YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+		char *source =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+		while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+			*--dest = *--source;
+
+		yy_cp += (int) (dest - source);
+		yy_bp += (int) (dest - source);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+		if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+			YY_FATAL_ERROR( "flex scanner push-back overflow" );
+		}
+
+	*--yy_cp = (char) c;
+
+    if ( c == '\n' ){
+        --yylineno;
+    }
+
+	(yytext_ptr) = yy_bp;
+	(yy_hold_char) = *yy_cp;
+	(yy_c_buf_p) = yy_cp;
+}
+
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+    static int yyinput (void)
+#else
+    static int input  (void)
+#endif
+
+{
+	int c;
+    
+	*(yy_c_buf_p) = (yy_hold_char);
+
+	if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+		{
+		/* yy_c_buf_p now points to the character we want to return.
+		 * If this occurs *before* the EOB characters, then it's a
+		 * valid NUL; if not, then we've hit the end of the buffer.
+		 */
+		if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+			/* This was really a NUL. */
+			*(yy_c_buf_p) = '\0';
+
+		else
+			{ /* need more input */
+			yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
+			++(yy_c_buf_p);
+
+			switch ( yy_get_next_buffer(  ) )
+				{
+				case EOB_ACT_LAST_MATCH:
+					/* This happens because yy_g_n_b()
+					 * sees that we've accumulated a
+					 * token and flags that we need to
+					 * try matching the token before
+					 * proceeding.  But for input(),
+					 * there's no matching to consider.
+					 * So convert the EOB_ACT_LAST_MATCH
+					 * to EOB_ACT_END_OF_FILE.
+					 */
+
+					/* Reset buffer status. */
+					yyrestart(yyin );
+
+					/*FALLTHROUGH*/
+
+				case EOB_ACT_END_OF_FILE:
+					{
+					if ( yywrap( ) )
+						return EOF;
+
+					if ( ! (yy_did_buffer_switch_on_eof) )
+						YY_NEW_FILE;
+#ifdef __cplusplus
+					return yyinput();
+#else
+					return input();
+#endif
+					}
+
+				case EOB_ACT_CONTINUE_SCAN:
+					(yy_c_buf_p) = (yytext_ptr) + offset;
+					break;
+				}
+			}
+		}
+
+	c = *(unsigned char *) (yy_c_buf_p);	/* cast for 8-bit char's */
+	*(yy_c_buf_p) = '\0';	/* preserve yytext */
+	(yy_hold_char) = *++(yy_c_buf_p);
+
+	if ( c == '\n' )
+		   
+    yylineno++;
+;
+
+	return c;
+}
+#endif	/* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * 
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+    void yyrestart  (FILE * input_file )
+{
+    
+	if ( ! YY_CURRENT_BUFFER ){
+        yyensure_buffer_stack ();
+		YY_CURRENT_BUFFER_LVALUE =
+            yy_create_buffer(yyin,YY_BUF_SIZE );
+	}
+
+	yy_init_buffer(YY_CURRENT_BUFFER,input_file );
+	yy_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * 
+ */
+    void yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
+{
+    
+	/* TODO. We should be able to replace this entire function body
+	 * with
+	 *		yypop_buffer_state();
+	 *		yypush_buffer_state(new_buffer);
+     */
+	yyensure_buffer_stack ();
+	if ( YY_CURRENT_BUFFER == new_buffer )
+		return;
+
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*(yy_c_buf_p) = (yy_hold_char);
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+	yy_load_buffer_state( );
+
+	/* We don't actually know whether we did this switch during
+	 * EOF (yywrap()) processing, but the only time this flag
+	 * is looked at is after yywrap() is called, so it's safe
+	 * to go ahead and always set it.
+	 */
+	(yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void yy_load_buffer_state  (void)
+{
+    	(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+	(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+	yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+	(yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * 
+ * @return the allocated buffer state.
+ */
+    YY_BUFFER_STATE yy_create_buffer  (FILE * file, int  size )
+{
+	YY_BUFFER_STATE b;
+    
+	b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_buf_size = (yy_size_t)size;
+
+	/* yy_ch_buf has to be 2 characters longer than the size given because
+	 * we need to put in 2 end-of-buffer characters.
+	 */
+	b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2  );
+	if ( ! b->yy_ch_buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_is_our_buffer = 1;
+
+	yy_init_buffer(b,file );
+
+	return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ * 
+ */
+    void yy_delete_buffer (YY_BUFFER_STATE  b )
+{
+    
+	if ( ! b )
+		return;
+
+	if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+	if ( b->yy_is_our_buffer )
+		yyfree((void *) b->yy_ch_buf  );
+
+	yyfree((void *) b  );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+    static void yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
+
+{
+	int oerrno = errno;
+    
+	yy_flush_buffer(b );
+
+	b->yy_input_file = file;
+	b->yy_fill_buffer = 1;
+
+    /* If b is the current buffer, then yy_init_buffer was _probably_
+     * called from yyrestart() or through yy_get_next_buffer.
+     * In that case, we don't want to reset the lineno or column.
+     */
+    if (b != YY_CURRENT_BUFFER){
+        b->yy_bs_lineno = 1;
+        b->yy_bs_column = 0;
+    }
+
+        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+    
+	errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * 
+ */
+    void yy_flush_buffer (YY_BUFFER_STATE  b )
+{
+    	if ( ! b )
+		return;
+
+	b->yy_n_chars = 0;
+
+	/* We always need two end-of-buffer characters.  The first causes
+	 * a transition to the end-of-buffer state.  The second causes
+	 * a jam in that state.
+	 */
+	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+	b->yy_buf_pos = &b->yy_ch_buf[0];
+
+	b->yy_at_bol = 1;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	if ( b == YY_CURRENT_BUFFER )
+		yy_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ *  the current state. This function will allocate the stack
+ *  if necessary.
+ *  @param new_buffer The new state.
+ *  
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+    	if (new_buffer == NULL)
+		return;
+
+	yyensure_buffer_stack();
+
+	/* This block is copied from yy_switch_to_buffer. */
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*(yy_c_buf_p) = (yy_hold_char);
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	/* Only push if top exists. Otherwise, replace top. */
+	if (YY_CURRENT_BUFFER)
+		(yy_buffer_stack_top)++;
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+	/* copied from yy_switch_to_buffer. */
+	yy_load_buffer_state( );
+	(yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ *  The next element becomes the new top.
+ *  
+ */
+void yypop_buffer_state (void)
+{
+    	if (!YY_CURRENT_BUFFER)
+		return;
+
+	yy_delete_buffer(YY_CURRENT_BUFFER );
+	YY_CURRENT_BUFFER_LVALUE = NULL;
+	if ((yy_buffer_stack_top) > 0)
+		--(yy_buffer_stack_top);
+
+	if (YY_CURRENT_BUFFER) {
+		yy_load_buffer_state( );
+		(yy_did_buffer_switch_on_eof) = 1;
+	}
+}
+
+/* Allocates the stack if it does not exist.
+ *  Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (void)
+{
+	yy_size_t num_to_alloc;
+    
+	if (!(yy_buffer_stack)) {
+
+		/* First allocation is just for 2 elements, since we don't know if this
+		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
+		 * immediate realloc on the next call.
+         */
+		num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
+		(yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+								(num_to_alloc * sizeof(struct yy_buffer_state*)
+								);
+		if ( ! (yy_buffer_stack) )
+			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+								  
+		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+				
+		(yy_buffer_stack_max) = num_to_alloc;
+		(yy_buffer_stack_top) = 0;
+		return;
+	}
+
+	if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+		/* Increase the buffer to prepare for a possible push. */
+		yy_size_t grow_size = 8 /* arbitrary grow size */;
+
+		num_to_alloc = (yy_buffer_stack_max) + grow_size;
+		(yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+								((yy_buffer_stack),
+								num_to_alloc * sizeof(struct yy_buffer_state*)
+								);
+		if ( ! (yy_buffer_stack) )
+			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+		/* zero only the new slots.*/
+		memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+		(yy_buffer_stack_max) = num_to_alloc;
+	}
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * 
+ * @return the newly allocated buffer state object. 
+ */
+YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
+{
+	YY_BUFFER_STATE b;
+    
+	if ( size < 2 ||
+	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
+	     base[size-1] != YY_END_OF_BUFFER_CHAR )
+		/* They forgot to leave room for the EOB's. */
+		return 0;
+
+	b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_pos = b->yy_ch_buf = base;
+	b->yy_is_our_buffer = 0;
+	b->yy_input_file = 0;
+	b->yy_n_chars = b->yy_buf_size;
+	b->yy_is_interactive = 0;
+	b->yy_at_bol = 1;
+	b->yy_fill_buffer = 0;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	yy_switch_to_buffer(b  );
+
+	return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * 
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ *       yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
+{
+    
+	return yy_scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ * 
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, yy_size_t  _yybytes_len )
+{
+	YY_BUFFER_STATE b;
+	char *buf;
+	yy_size_t n;
+	yy_size_t i;
+    
+	/* Get memory for full buffer, including space for trailing EOB's. */
+	n = _yybytes_len + 2;
+	buf = (char *) yyalloc(n  );
+	if ( ! buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+	for ( i = 0; i < _yybytes_len; ++i )
+		buf[i] = yybytes[i];
+
+	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+	b = yy_scan_buffer(buf,n );
+	if ( ! b )
+		YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+	/* It's okay to grow etc. this buffer, and we should throw it
+	 * away when we're done.
+	 */
+	b->yy_is_our_buffer = 1;
+
+	return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+			(void) fprintf( stderr, "%s\n", msg );
+	exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		yytext[yyleng] = (yy_hold_char); \
+		(yy_c_buf_p) = yytext + yyless_macro_arg; \
+		(yy_hold_char) = *(yy_c_buf_p); \
+		*(yy_c_buf_p) = '\0'; \
+		yyleng = yyless_macro_arg; \
+		} \
+	while ( 0 )
+
+/* Accessor  methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ * 
+ */
+int yyget_lineno  (void)
+{
+        
+    return yylineno;
+}
+
+/** Get the input stream.
+ * 
+ */
+FILE *yyget_in  (void)
+{
+        return yyin;
+}
+
+/** Get the output stream.
+ * 
+ */
+FILE *yyget_out  (void)
+{
+        return yyout;
+}
+
+/** Get the length of the current token.
+ * 
+ */
+yy_size_t yyget_leng  (void)
+{
+        return yyleng;
+}
+
+/** Get the current token.
+ * 
+ */
+
+char *yyget_text  (void)
+{
+        return yytext;
+}
+
+/** Set the current line number.
+ * @param _line_number line number
+ * 
+ */
+void yyset_lineno (int  _line_number )
+{
+    
+    yylineno = _line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param _in_str A readable stream.
+ * 
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE *  _in_str )
+{
+        yyin = _in_str ;
+}
+
+void yyset_out (FILE *  _out_str )
+{
+        yyout = _out_str ;
+}
+
+int yyget_debug  (void)
+{
+        return yy_flex_debug;
+}
+
+void yyset_debug (int  _bdebug )
+{
+        yy_flex_debug = _bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+        /* Initialization is the same as for the non-reentrant scanner.
+     * This function is called from yylex_destroy(), so don't allocate here.
+     */
+
+    /* We do not touch yylineno unless the option is enabled. */
+    yylineno =  1;
+    
+    (yy_buffer_stack) = 0;
+    (yy_buffer_stack_top) = 0;
+    (yy_buffer_stack_max) = 0;
+    (yy_c_buf_p) = (char *) 0;
+    (yy_init) = 0;
+    (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+    yyin = stdin;
+    yyout = stdout;
+#else
+    yyin = (FILE *) 0;
+    yyout = (FILE *) 0;
+#endif
+
+    /* For future reference: Set errno on error, since we are called by
+     * yylex_init()
+     */
+    return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy  (void)
+{
+    
+    /* Pop the buffer stack, destroying each element. */
+	while(YY_CURRENT_BUFFER){
+		yy_delete_buffer(YY_CURRENT_BUFFER  );
+		YY_CURRENT_BUFFER_LVALUE = NULL;
+		yypop_buffer_state();
+	}
+
+	/* Destroy the stack itself. */
+	yyfree((yy_buffer_stack) );
+	(yy_buffer_stack) = NULL;
+
+    /* Reset the globals. This is important in a non-reentrant scanner so the next time
+     * yylex() is called, initialization will occur. */
+    yy_init_globals( );
+
+    return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+		
+	int i;
+	for ( i = 0; i < n; ++i )
+		s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+	int n;
+	for ( n = 0; s[n]; ++n )
+		;
+
+	return n;
+}
+#endif
+
+void *yyalloc (yy_size_t  size )
+{
+			return (void *) malloc( size );
+}
+
+void *yyrealloc  (void * ptr, yy_size_t  size )
+{
+		
+	/* The cast to (char *) in the following accommodates both
+	 * implementations that use char* generic pointers, and those
+	 * that use void* generic pointers.  It works with the latter
+	 * because both ANSI C and C++ allow castless assignment from
+	 * any pointer type to void*, and deal with argument conversions
+	 * as though doing an assignment.
+	 */
+	return (void *) realloc( (char *) ptr, size );
+}
+
+void yyfree (void * ptr )
+{
+			free( (char *) ptr );	/* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 164 "parser/tf_fuzz_grammar.l"
+
+
+
+
diff --git a/tf_fuzz/parser/tf_fuzz_grammar.lex.o b/tf_fuzz/parser/tf_fuzz_grammar.lex.o
new file mode 100644
index 0000000..bba09f8
--- /dev/null
+++ b/tf_fuzz/parser/tf_fuzz_grammar.lex.o
Binary files differ
diff --git a/tf_fuzz/parser/tf_fuzz_grammar.output b/tf_fuzz/parser/tf_fuzz_grammar.output
new file mode 100644
index 0000000..aaadb77
--- /dev/null
+++ b/tf_fuzz/parser/tf_fuzz_grammar.output
@@ -0,0 +1,2471 @@
+Terminals unused in grammar
+
+   RAW_TEXT
+   EQUAL
+   ERROR
+
+
+Grammar
+
+    0 $accept: lines $end
+
+    1 lines: %empty
+    2      | line lines
+
+    3 line: PURPOSE
+    4     | block
+    5     | command SEMICOLON
+    6     | command expect SEMICOLON
+
+    7 command: set_command
+    8        | remove_command
+    9        | read_command
+   10        | secure_command
+   11        | done_command
+
+   12 expect: EXPECT PASS
+   13       | EXPECT FAIL
+   14       | EXPECT NOTHING
+   15       | EXPECT IDENTIFIER
+
+   16 set_command: SET SST sst_set_base_args sst_set_extended_args
+   17            | SET KEY key_set_args
+   18            | SET POLICY policy_set_args
+
+   19 read_command: READ SST sst_read_args
+   20             | READ KEY key_read_args
+   21             | READ POLICY policy_read_args
+
+   22 remove_command: REMOVE SST sst_remove_args
+   23               | REMOVE KEY key_remove_args
+
+   24 secure_command: SECURE HASH NEQ ASSET_IDENTIFIER_LIST
+
+   25 done_command: DONE
+
+   26 literal_or_random_data: DATA LITERAL
+   27                       | DATA STAR
+
+   28 sst_set_base_args: sst_asset_name literal_or_random_data
+   29                  | sst_asset_name
+   30                  | sst_asset_name VAR IDENTIFIER
+   31                  | sst_asset_name DFNAME sst_asset_set_file_path
+
+   32 sst_set_extended_args: %empty
+   33                      | FLAG sst_flags
+
+   34 sst_flags: %empty
+   35          | sst_flag sst_flags
+
+   36 sst_flag: none
+   37         | write_once
+   38         | no_rp
+   39         | no_conf
+
+   40 none: NONE
+
+   41 write_once: WRITE_ONCE
+
+   42 no_rp: NO_RP
+
+   43 no_conf: NO_CONF
+
+   44 sst_offset_spec: NUMBER_TOK
+
+   45 sst_read_args: sst_asset_name read_args sst_read_extended_args
+
+   46 read_args: VAR IDENTIFIER
+   47          | CHECK read_args_var_name
+   48          | CHECK LITERAL
+   49          | PRINT
+   50          | HASH
+   51          | DFNAME sst_asset_dump_file_path
+
+   52 sst_read_extended_args: %empty
+   53                       | OFFSET sst_offset_spec
+
+   54 sst_remove_args: sst_asset_name
+   55                | random_picked_asset
+
+   56 asset_designator: NAME ASSET_IDENTIFIER_LIST
+   57                 | NAME STAR
+
+   58 single_existing_asset: IDENTIFIER
+   59                      | random_picked_asset
+
+   60 random_picked_asset: STAR ACTIVE
+   61                    | STAR DELETED
+
+   62 sst_asset_name: asset_designator
+   63               | UID ASSET_NUMBER_LIST
+   64               | UID STAR
+
+   65 sst_asset_set_file_path: FILE_PATH
+
+   66 read_args_var_name: IDENTIFIER
+
+   67 sst_asset_dump_file_path: FILE_PATH
+
+   68 key_size: NUMBER_TOK
+
+   69 policy_usage_list: ATTR policy_usage policy_usages
+
+   70 policy_usages: %empty
+   71              | policy_usage policy_usages
+
+   72 export: EXPORT
+
+   73 noexport: NOEXPORT
+
+   74 copy: COPY
+
+   75 nocopy: NOCOPY
+
+   76 encrypt: ENCRYPT
+
+   77 noencrypt: NOENCRYPT
+
+   78 decrypt: DECRYPT
+
+   79 nodecrypt: NODECRYPT
+
+   80 sign: SIGN
+
+   81 nosign: NOSIGN
+
+   82 verify: VERIFY
+
+   83 noverify: NOVERIFY
+
+   84 derive: DERIVE
+
+   85 noderive: NODERIVE
+
+   86 persistent: PERSISTENT
+
+   87 volatle: VOLATILE
+
+   88 policy_usage: export
+   89             | copy
+   90             | encrypt
+   91             | decrypt
+   92             | sign
+   93             | verify
+   94             | derive
+   95             | noexport
+   96             | nocopy
+   97             | noencrypt
+   98             | nodecrypt
+   99             | nosign
+  100             | noverify
+  101             | noderive
+  102             | persistent
+  103             | volatle
+  104             | key_size
+
+  105 policy_type: TYPE IDENTIFIER
+
+  106 policy_algorithm: ALG IDENTIFIER
+
+  107 policy_specs: %empty
+  108             | policy_spec policy_specs
+
+  109 policy_spec: policy_usage_list
+  110            | policy_type
+  111            | policy_algorithm
+
+  112 policy_asset_spec: %empty
+  113                  | NAME ASSET_IDENTIFIER_LIST
+  114                  | NAME STAR
+
+  115 policy_asset_name: NAME IDENTIFIER
+  116                  | STAR ACTIVE
+  117                  | STAR DELETED
+  118                  | KEY IDENTIFIER
+
+  119 policy_set_args: policy_asset_spec policy_specs
+
+  120 policy_read_args: policy_asset_name read_args
+
+  121 key_set_sources: %empty
+  122                | key_set_source key_set_sources
+
+  123 key_set_source: literal_or_random_data
+  124               | POLICY IDENTIFIER
+
+  125 key_data_or_not: %empty
+  126                | literal_or_random_data
+
+  127 key_set_args: asset_designator key_set_sources
+  128             | asset_designator FROM single_existing_asset POLICY IDENTIFIER
+  129             | asset_designator key_data_or_not WITH policy_specs
+
+  130 key_remove_args: asset_designator
+
+  131 key_read_args: asset_designator read_args
+
+  132 block: SHUFFLE block_content
+  133      | exact_sel_count OF block_content
+  134      | low_sel_count TO high_sel_count OF block_content
+
+  135 block_content: open_brace lines close_brace
+  136              | line
+
+  137 open_brace: OPEN_BRACE
+
+  138 close_brace: CLOSE_BRACE
+
+  139 ASSET_NUMBER_LIST: ASSET_NUMBER ASSET_NUMBERS
+
+  140 ASSET_NUMBERS: %empty
+  141              | ASSET_NUMBER ASSET_NUMBERS
+
+  142 ASSET_NUMBER: NUMBER_TOK
+
+  143 ASSET_IDENTIFIER_LIST: ASSET_IDENTIFIER ASSET_IDENTIFIERS
+
+  144 ASSET_IDENTIFIERS: %empty
+  145                  | ASSET_IDENTIFIER ASSET_IDENTIFIERS
+
+  146 ASSET_IDENTIFIER: IDENTIFIER_TOK
+
+  147 IDENTIFIER: IDENTIFIER_TOK
+
+  148 FILE_PATH: FILE_PATH_TOK
+
+  149 exact_sel_count: NUMBER
+
+  150 low_sel_count: NUMBER
+
+  151 high_sel_count: NUMBER
+
+  152 NUMBER: NUMBER_TOK
+
+  153 LITERAL: LITERAL_TOK
+  154        | HEX_LIST
+
+
+Terminals, with rules where they appear
+
+$end (0) 0
+error (256)
+PURPOSE (258) 3
+RAW_TEXT (259)
+SET (260) 16 17 18
+READ (261) 19 20 21
+REMOVE (262) 22 23
+SECURE (263) 24
+DONE (264) 25
+SST (265) 16 19 22
+KEY (266) 17 20 23 118
+POLICY (267) 18 21 124 128
+NAME (268) 56 57 113 114 115
+UID (269) 63 64
+STAR (270) 27 57 60 61 64 114 116 117
+ACTIVE (271) 60 116
+DELETED (272) 61 117
+EQUAL (273)
+DATA (274) 26 27
+DFNAME (275) 31 51
+FLAG (276) 33
+NONE (277) 40
+WRITE_ONCE (278) 41
+NO_RP (279) 42
+NO_CONF (280) 43
+OFFSET (281) 53
+CHECK (282) 47 48
+VAR (283) 30 46
+HASH (284) 24 50
+NEQ (285) 24
+PRINT (286) 49
+EXPECT (287) 12 13 14 15
+PASS (288) 12
+FAIL (289) 13
+NOTHING (290) 14
+ERROR (291)
+IDENTIFIER_TOK (292) 146 147
+LITERAL_TOK (293) 153
+HEX_LIST (294) 154
+FILE_PATH_TOK (295) 148
+NUMBER_TOK (296) 44 68 142 152
+SEMICOLON (297) 5 6
+SHUFFLE (298) 132
+TO (299) 134
+OF (300) 133 134
+OPEN_BRACE (301) 137
+CLOSE_BRACE (302) 138
+ATTR (303) 69
+TYPE (304) 105
+ALG (305) 106
+EXPORT (306) 72
+COPY (307) 74
+ENCRYPT (308) 76
+DECRYPT (309) 78
+SIGN (310) 80
+VERIFY (311) 82
+DERIVE (312) 84
+NOEXPORT (313) 73
+NOCOPY (314) 75
+NOENCRYPT (315) 77
+NODECRYPT (316) 79
+NOSIGN (317) 81
+NOVERIFY (318) 83
+NODERIVE (319) 85
+PERSISTENT (320) 86
+VOLATILE (321) 87
+FROM (322) 128
+WITH (323) 129
+
+
+Nonterminals, with rules where they appear
+
+$accept (69)
+    on left: 0
+lines (70)
+    on left: 1 2, on right: 0 2 135
+line (71)
+    on left: 3 4 5 6, on right: 2 136
+command (72)
+    on left: 7 8 9 10 11, on right: 5 6
+expect (73)
+    on left: 12 13 14 15, on right: 6
+set_command (74)
+    on left: 16 17 18, on right: 7
+read_command (75)
+    on left: 19 20 21, on right: 9
+remove_command (76)
+    on left: 22 23, on right: 8
+secure_command (77)
+    on left: 24, on right: 10
+done_command (78)
+    on left: 25, on right: 11
+literal_or_random_data (79)
+    on left: 26 27, on right: 28 123 126
+sst_set_base_args (80)
+    on left: 28 29 30 31, on right: 16
+sst_set_extended_args (81)
+    on left: 32 33, on right: 16
+sst_flags (82)
+    on left: 34 35, on right: 33 35
+sst_flag (83)
+    on left: 36 37 38 39, on right: 35
+none (84)
+    on left: 40, on right: 36
+write_once (85)
+    on left: 41, on right: 37
+no_rp (86)
+    on left: 42, on right: 38
+no_conf (87)
+    on left: 43, on right: 39
+sst_offset_spec (88)
+    on left: 44, on right: 53
+sst_read_args (89)
+    on left: 45, on right: 19
+read_args (90)
+    on left: 46 47 48 49 50 51, on right: 45 120 131
+sst_read_extended_args (91)
+    on left: 52 53, on right: 45
+sst_remove_args (92)
+    on left: 54 55, on right: 22
+asset_designator (93)
+    on left: 56 57, on right: 62 127 128 129 130 131
+single_existing_asset (94)
+    on left: 58 59, on right: 128
+random_picked_asset (95)
+    on left: 60 61, on right: 55 59
+sst_asset_name (96)
+    on left: 62 63 64, on right: 28 29 30 31 45 54
+sst_asset_set_file_path (97)
+    on left: 65, on right: 31
+read_args_var_name (98)
+    on left: 66, on right: 47
+sst_asset_dump_file_path (99)
+    on left: 67, on right: 51
+key_size (100)
+    on left: 68, on right: 104
+policy_usage_list (101)
+    on left: 69, on right: 109
+policy_usages (102)
+    on left: 70 71, on right: 69 71
+export (103)
+    on left: 72, on right: 88
+noexport (104)
+    on left: 73, on right: 95
+copy (105)
+    on left: 74, on right: 89
+nocopy (106)
+    on left: 75, on right: 96
+encrypt (107)
+    on left: 76, on right: 90
+noencrypt (108)
+    on left: 77, on right: 97
+decrypt (109)
+    on left: 78, on right: 91
+nodecrypt (110)
+    on left: 79, on right: 98
+sign (111)
+    on left: 80, on right: 92
+nosign (112)
+    on left: 81, on right: 99
+verify (113)
+    on left: 82, on right: 93
+noverify (114)
+    on left: 83, on right: 100
+derive (115)
+    on left: 84, on right: 94
+noderive (116)
+    on left: 85, on right: 101
+persistent (117)
+    on left: 86, on right: 102
+volatle (118)
+    on left: 87, on right: 103
+policy_usage (119)
+    on left: 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104,
+    on right: 69 71
+policy_type (120)
+    on left: 105, on right: 110
+policy_algorithm (121)
+    on left: 106, on right: 111
+policy_specs (122)
+    on left: 107 108, on right: 108 119 129
+policy_spec (123)
+    on left: 109 110 111, on right: 108
+policy_asset_spec (124)
+    on left: 112 113 114, on right: 119
+policy_asset_name (125)
+    on left: 115 116 117 118, on right: 120
+policy_set_args (126)
+    on left: 119, on right: 18
+policy_read_args (127)
+    on left: 120, on right: 21
+key_set_sources (128)
+    on left: 121 122, on right: 122 127
+key_set_source (129)
+    on left: 123 124, on right: 122
+key_data_or_not (130)
+    on left: 125 126, on right: 129
+key_set_args (131)
+    on left: 127 128 129, on right: 17
+key_remove_args (132)
+    on left: 130, on right: 23
+key_read_args (133)
+    on left: 131, on right: 20
+block (134)
+    on left: 132 133 134, on right: 4
+block_content (135)
+    on left: 135 136, on right: 132 133 134
+open_brace (136)
+    on left: 137, on right: 135
+close_brace (137)
+    on left: 138, on right: 135
+ASSET_NUMBER_LIST (138)
+    on left: 139, on right: 63
+ASSET_NUMBERS (139)
+    on left: 140 141, on right: 139 141
+ASSET_NUMBER (140)
+    on left: 142, on right: 139 141
+ASSET_IDENTIFIER_LIST (141)
+    on left: 143, on right: 24 56 113
+ASSET_IDENTIFIERS (142)
+    on left: 144 145, on right: 143 145
+ASSET_IDENTIFIER (143)
+    on left: 146, on right: 143 145
+IDENTIFIER (144)
+    on left: 147, on right: 15 30 46 58 66 105 106 115 118 124 128
+FILE_PATH (145)
+    on left: 148, on right: 65 67
+exact_sel_count (146)
+    on left: 149, on right: 133
+low_sel_count (147)
+    on left: 150, on right: 134
+high_sel_count (148)
+    on left: 151, on right: 134
+NUMBER (149)
+    on left: 152, on right: 149 150 151
+LITERAL (150)
+    on left: 153 154, on right: 26 48
+
+
+State 0
+
+    0 $accept: . lines $end
+
+    PURPOSE     shift, and go to state 1
+    SET         shift, and go to state 2
+    READ        shift, and go to state 3
+    REMOVE      shift, and go to state 4
+    SECURE      shift, and go to state 5
+    DONE        shift, and go to state 6
+    NUMBER_TOK  shift, and go to state 7
+    SHUFFLE     shift, and go to state 8
+
+    $default  reduce using rule 1 (lines)
+
+    lines            go to state 9
+    line             go to state 10
+    command          go to state 11
+    set_command      go to state 12
+    read_command     go to state 13
+    remove_command   go to state 14
+    secure_command   go to state 15
+    done_command     go to state 16
+    block            go to state 17
+    exact_sel_count  go to state 18
+    low_sel_count    go to state 19
+    NUMBER           go to state 20
+
+
+State 1
+
+    3 line: PURPOSE .
+
+    $default  reduce using rule 3 (line)
+
+
+State 2
+
+   16 set_command: SET . SST sst_set_base_args sst_set_extended_args
+   17            | SET . KEY key_set_args
+   18            | SET . POLICY policy_set_args
+
+    SST     shift, and go to state 21
+    KEY     shift, and go to state 22
+    POLICY  shift, and go to state 23
+
+
+State 3
+
+   19 read_command: READ . SST sst_read_args
+   20             | READ . KEY key_read_args
+   21             | READ . POLICY policy_read_args
+
+    SST     shift, and go to state 24
+    KEY     shift, and go to state 25
+    POLICY  shift, and go to state 26
+
+
+State 4
+
+   22 remove_command: REMOVE . SST sst_remove_args
+   23               | REMOVE . KEY key_remove_args
+
+    SST  shift, and go to state 27
+    KEY  shift, and go to state 28
+
+
+State 5
+
+   24 secure_command: SECURE . HASH NEQ ASSET_IDENTIFIER_LIST
+
+    HASH  shift, and go to state 29
+
+
+State 6
+
+   25 done_command: DONE .
+
+    $default  reduce using rule 25 (done_command)
+
+
+State 7
+
+  152 NUMBER: NUMBER_TOK .
+
+    $default  reduce using rule 152 (NUMBER)
+
+
+State 8
+
+  132 block: SHUFFLE . block_content
+
+    PURPOSE     shift, and go to state 1
+    SET         shift, and go to state 2
+    READ        shift, and go to state 3
+    REMOVE      shift, and go to state 4
+    SECURE      shift, and go to state 5
+    DONE        shift, and go to state 6
+    NUMBER_TOK  shift, and go to state 7
+    SHUFFLE     shift, and go to state 8
+    OPEN_BRACE  shift, and go to state 30
+
+    line             go to state 31
+    command          go to state 11
+    set_command      go to state 12
+    read_command     go to state 13
+    remove_command   go to state 14
+    secure_command   go to state 15
+    done_command     go to state 16
+    block            go to state 17
+    block_content    go to state 32
+    open_brace       go to state 33
+    exact_sel_count  go to state 18
+    low_sel_count    go to state 19
+    NUMBER           go to state 20
+
+
+State 9
+
+    0 $accept: lines . $end
+
+    $end  shift, and go to state 34
+
+
+State 10
+
+    2 lines: line . lines
+
+    PURPOSE     shift, and go to state 1
+    SET         shift, and go to state 2
+    READ        shift, and go to state 3
+    REMOVE      shift, and go to state 4
+    SECURE      shift, and go to state 5
+    DONE        shift, and go to state 6
+    NUMBER_TOK  shift, and go to state 7
+    SHUFFLE     shift, and go to state 8
+
+    $default  reduce using rule 1 (lines)
+
+    lines            go to state 35
+    line             go to state 10
+    command          go to state 11
+    set_command      go to state 12
+    read_command     go to state 13
+    remove_command   go to state 14
+    secure_command   go to state 15
+    done_command     go to state 16
+    block            go to state 17
+    exact_sel_count  go to state 18
+    low_sel_count    go to state 19
+    NUMBER           go to state 20
+
+
+State 11
+
+    5 line: command . SEMICOLON
+    6     | command . expect SEMICOLON
+
+    EXPECT     shift, and go to state 36
+    SEMICOLON  shift, and go to state 37
+
+    expect  go to state 38
+
+
+State 12
+
+    7 command: set_command .
+
+    $default  reduce using rule 7 (command)
+
+
+State 13
+
+    9 command: read_command .
+
+    $default  reduce using rule 9 (command)
+
+
+State 14
+
+    8 command: remove_command .
+
+    $default  reduce using rule 8 (command)
+
+
+State 15
+
+   10 command: secure_command .
+
+    $default  reduce using rule 10 (command)
+
+
+State 16
+
+   11 command: done_command .
+
+    $default  reduce using rule 11 (command)
+
+
+State 17
+
+    4 line: block .
+
+    $default  reduce using rule 4 (line)
+
+
+State 18
+
+  133 block: exact_sel_count . OF block_content
+
+    OF  shift, and go to state 39
+
+
+State 19
+
+  134 block: low_sel_count . TO high_sel_count OF block_content
+
+    TO  shift, and go to state 40
+
+
+State 20
+
+  149 exact_sel_count: NUMBER .
+  150 low_sel_count: NUMBER .
+
+    TO        reduce using rule 150 (low_sel_count)
+    $default  reduce using rule 149 (exact_sel_count)
+
+
+State 21
+
+   16 set_command: SET SST . sst_set_base_args sst_set_extended_args
+
+    NAME  shift, and go to state 41
+    UID   shift, and go to state 42
+
+    sst_set_base_args  go to state 43
+    asset_designator   go to state 44
+    sst_asset_name     go to state 45
+
+
+State 22
+
+   17 set_command: SET KEY . key_set_args
+
+    NAME  shift, and go to state 41
+
+    asset_designator  go to state 46
+    key_set_args      go to state 47
+
+
+State 23
+
+   18 set_command: SET POLICY . policy_set_args
+
+    NAME  shift, and go to state 48
+
+    $default  reduce using rule 112 (policy_asset_spec)
+
+    policy_asset_spec  go to state 49
+    policy_set_args    go to state 50
+
+
+State 24
+
+   19 read_command: READ SST . sst_read_args
+
+    NAME  shift, and go to state 41
+    UID   shift, and go to state 42
+
+    sst_read_args     go to state 51
+    asset_designator  go to state 44
+    sst_asset_name    go to state 52
+
+
+State 25
+
+   20 read_command: READ KEY . key_read_args
+
+    NAME  shift, and go to state 41
+
+    asset_designator  go to state 53
+    key_read_args     go to state 54
+
+
+State 26
+
+   21 read_command: READ POLICY . policy_read_args
+
+    KEY   shift, and go to state 55
+    NAME  shift, and go to state 56
+    STAR  shift, and go to state 57
+
+    policy_asset_name  go to state 58
+    policy_read_args   go to state 59
+
+
+State 27
+
+   22 remove_command: REMOVE SST . sst_remove_args
+
+    NAME  shift, and go to state 41
+    UID   shift, and go to state 42
+    STAR  shift, and go to state 60
+
+    sst_remove_args      go to state 61
+    asset_designator     go to state 44
+    random_picked_asset  go to state 62
+    sst_asset_name       go to state 63
+
+
+State 28
+
+   23 remove_command: REMOVE KEY . key_remove_args
+
+    NAME  shift, and go to state 41
+
+    asset_designator  go to state 64
+    key_remove_args   go to state 65
+
+
+State 29
+
+   24 secure_command: SECURE HASH . NEQ ASSET_IDENTIFIER_LIST
+
+    NEQ  shift, and go to state 66
+
+
+State 30
+
+  137 open_brace: OPEN_BRACE .
+
+    $default  reduce using rule 137 (open_brace)
+
+
+State 31
+
+  136 block_content: line .
+
+    $default  reduce using rule 136 (block_content)
+
+
+State 32
+
+  132 block: SHUFFLE block_content .
+
+    $default  reduce using rule 132 (block)
+
+
+State 33
+
+  135 block_content: open_brace . lines close_brace
+
+    PURPOSE     shift, and go to state 1
+    SET         shift, and go to state 2
+    READ        shift, and go to state 3
+    REMOVE      shift, and go to state 4
+    SECURE      shift, and go to state 5
+    DONE        shift, and go to state 6
+    NUMBER_TOK  shift, and go to state 7
+    SHUFFLE     shift, and go to state 8
+
+    $default  reduce using rule 1 (lines)
+
+    lines            go to state 67
+    line             go to state 10
+    command          go to state 11
+    set_command      go to state 12
+    read_command     go to state 13
+    remove_command   go to state 14
+    secure_command   go to state 15
+    done_command     go to state 16
+    block            go to state 17
+    exact_sel_count  go to state 18
+    low_sel_count    go to state 19
+    NUMBER           go to state 20
+
+
+State 34
+
+    0 $accept: lines $end .
+
+    $default  accept
+
+
+State 35
+
+    2 lines: line lines .
+
+    $default  reduce using rule 2 (lines)
+
+
+State 36
+
+   12 expect: EXPECT . PASS
+   13       | EXPECT . FAIL
+   14       | EXPECT . NOTHING
+   15       | EXPECT . IDENTIFIER
+
+    PASS            shift, and go to state 68
+    FAIL            shift, and go to state 69
+    NOTHING         shift, and go to state 70
+    IDENTIFIER_TOK  shift, and go to state 71
+
+    IDENTIFIER  go to state 72
+
+
+State 37
+
+    5 line: command SEMICOLON .
+
+    $default  reduce using rule 5 (line)
+
+
+State 38
+
+    6 line: command expect . SEMICOLON
+
+    SEMICOLON  shift, and go to state 73
+
+
+State 39
+
+  133 block: exact_sel_count OF . block_content
+
+    PURPOSE     shift, and go to state 1
+    SET         shift, and go to state 2
+    READ        shift, and go to state 3
+    REMOVE      shift, and go to state 4
+    SECURE      shift, and go to state 5
+    DONE        shift, and go to state 6
+    NUMBER_TOK  shift, and go to state 7
+    SHUFFLE     shift, and go to state 8
+    OPEN_BRACE  shift, and go to state 30
+
+    line             go to state 31
+    command          go to state 11
+    set_command      go to state 12
+    read_command     go to state 13
+    remove_command   go to state 14
+    secure_command   go to state 15
+    done_command     go to state 16
+    block            go to state 17
+    block_content    go to state 74
+    open_brace       go to state 33
+    exact_sel_count  go to state 18
+    low_sel_count    go to state 19
+    NUMBER           go to state 20
+
+
+State 40
+
+  134 block: low_sel_count TO . high_sel_count OF block_content
+
+    NUMBER_TOK  shift, and go to state 7
+
+    high_sel_count  go to state 75
+    NUMBER          go to state 76
+
+
+State 41
+
+   56 asset_designator: NAME . ASSET_IDENTIFIER_LIST
+   57                 | NAME . STAR
+
+    STAR            shift, and go to state 77
+    IDENTIFIER_TOK  shift, and go to state 78
+
+    ASSET_IDENTIFIER_LIST  go to state 79
+    ASSET_IDENTIFIER       go to state 80
+
+
+State 42
+
+   63 sst_asset_name: UID . ASSET_NUMBER_LIST
+   64               | UID . STAR
+
+    STAR        shift, and go to state 81
+    NUMBER_TOK  shift, and go to state 82
+
+    ASSET_NUMBER_LIST  go to state 83
+    ASSET_NUMBER       go to state 84
+
+
+State 43
+
+   16 set_command: SET SST sst_set_base_args . sst_set_extended_args
+
+    FLAG  shift, and go to state 85
+
+    $default  reduce using rule 32 (sst_set_extended_args)
+
+    sst_set_extended_args  go to state 86
+
+
+State 44
+
+   62 sst_asset_name: asset_designator .
+
+    $default  reduce using rule 62 (sst_asset_name)
+
+
+State 45
+
+   28 sst_set_base_args: sst_asset_name . literal_or_random_data
+   29                  | sst_asset_name .
+   30                  | sst_asset_name . VAR IDENTIFIER
+   31                  | sst_asset_name . DFNAME sst_asset_set_file_path
+
+    DATA    shift, and go to state 87
+    DFNAME  shift, and go to state 88
+    VAR     shift, and go to state 89
+
+    $default  reduce using rule 29 (sst_set_base_args)
+
+    literal_or_random_data  go to state 90
+
+
+State 46
+
+  127 key_set_args: asset_designator . key_set_sources
+  128             | asset_designator . FROM single_existing_asset POLICY IDENTIFIER
+  129             | asset_designator . key_data_or_not WITH policy_specs
+
+    POLICY  shift, and go to state 91
+    DATA    shift, and go to state 87
+    FROM    shift, and go to state 92
+
+    WITH      reduce using rule 125 (key_data_or_not)
+    $default  reduce using rule 121 (key_set_sources)
+
+    literal_or_random_data  go to state 93
+    key_set_sources         go to state 94
+    key_set_source          go to state 95
+    key_data_or_not         go to state 96
+
+
+State 47
+
+   17 set_command: SET KEY key_set_args .
+
+    $default  reduce using rule 17 (set_command)
+
+
+State 48
+
+  113 policy_asset_spec: NAME . ASSET_IDENTIFIER_LIST
+  114                  | NAME . STAR
+
+    STAR            shift, and go to state 97
+    IDENTIFIER_TOK  shift, and go to state 78
+
+    ASSET_IDENTIFIER_LIST  go to state 98
+    ASSET_IDENTIFIER       go to state 80
+
+
+State 49
+
+  119 policy_set_args: policy_asset_spec . policy_specs
+
+    ATTR  shift, and go to state 99
+    TYPE  shift, and go to state 100
+    ALG   shift, and go to state 101
+
+    $default  reduce using rule 107 (policy_specs)
+
+    policy_usage_list  go to state 102
+    policy_type        go to state 103
+    policy_algorithm   go to state 104
+    policy_specs       go to state 105
+    policy_spec        go to state 106
+
+
+State 50
+
+   18 set_command: SET POLICY policy_set_args .
+
+    $default  reduce using rule 18 (set_command)
+
+
+State 51
+
+   19 read_command: READ SST sst_read_args .
+
+    $default  reduce using rule 19 (read_command)
+
+
+State 52
+
+   45 sst_read_args: sst_asset_name . read_args sst_read_extended_args
+
+    DFNAME  shift, and go to state 107
+    CHECK   shift, and go to state 108
+    VAR     shift, and go to state 109
+    HASH    shift, and go to state 110
+    PRINT   shift, and go to state 111
+
+    read_args  go to state 112
+
+
+State 53
+
+  131 key_read_args: asset_designator . read_args
+
+    DFNAME  shift, and go to state 107
+    CHECK   shift, and go to state 108
+    VAR     shift, and go to state 109
+    HASH    shift, and go to state 110
+    PRINT   shift, and go to state 111
+
+    read_args  go to state 113
+
+
+State 54
+
+   20 read_command: READ KEY key_read_args .
+
+    $default  reduce using rule 20 (read_command)
+
+
+State 55
+
+  118 policy_asset_name: KEY . IDENTIFIER
+
+    IDENTIFIER_TOK  shift, and go to state 71
+
+    IDENTIFIER  go to state 114
+
+
+State 56
+
+  115 policy_asset_name: NAME . IDENTIFIER
+
+    IDENTIFIER_TOK  shift, and go to state 71
+
+    IDENTIFIER  go to state 115
+
+
+State 57
+
+  116 policy_asset_name: STAR . ACTIVE
+  117                  | STAR . DELETED
+
+    ACTIVE   shift, and go to state 116
+    DELETED  shift, and go to state 117
+
+
+State 58
+
+  120 policy_read_args: policy_asset_name . read_args
+
+    DFNAME  shift, and go to state 107
+    CHECK   shift, and go to state 108
+    VAR     shift, and go to state 109
+    HASH    shift, and go to state 110
+    PRINT   shift, and go to state 111
+
+    read_args  go to state 118
+
+
+State 59
+
+   21 read_command: READ POLICY policy_read_args .
+
+    $default  reduce using rule 21 (read_command)
+
+
+State 60
+
+   60 random_picked_asset: STAR . ACTIVE
+   61                    | STAR . DELETED
+
+    ACTIVE   shift, and go to state 119
+    DELETED  shift, and go to state 120
+
+
+State 61
+
+   22 remove_command: REMOVE SST sst_remove_args .
+
+    $default  reduce using rule 22 (remove_command)
+
+
+State 62
+
+   55 sst_remove_args: random_picked_asset .
+
+    $default  reduce using rule 55 (sst_remove_args)
+
+
+State 63
+
+   54 sst_remove_args: sst_asset_name .
+
+    $default  reduce using rule 54 (sst_remove_args)
+
+
+State 64
+
+  130 key_remove_args: asset_designator .
+
+    $default  reduce using rule 130 (key_remove_args)
+
+
+State 65
+
+   23 remove_command: REMOVE KEY key_remove_args .
+
+    $default  reduce using rule 23 (remove_command)
+
+
+State 66
+
+   24 secure_command: SECURE HASH NEQ . ASSET_IDENTIFIER_LIST
+
+    IDENTIFIER_TOK  shift, and go to state 78
+
+    ASSET_IDENTIFIER_LIST  go to state 121
+    ASSET_IDENTIFIER       go to state 80
+
+
+State 67
+
+  135 block_content: open_brace lines . close_brace
+
+    CLOSE_BRACE  shift, and go to state 122
+
+    close_brace  go to state 123
+
+
+State 68
+
+   12 expect: EXPECT PASS .
+
+    $default  reduce using rule 12 (expect)
+
+
+State 69
+
+   13 expect: EXPECT FAIL .
+
+    $default  reduce using rule 13 (expect)
+
+
+State 70
+
+   14 expect: EXPECT NOTHING .
+
+    $default  reduce using rule 14 (expect)
+
+
+State 71
+
+  147 IDENTIFIER: IDENTIFIER_TOK .
+
+    $default  reduce using rule 147 (IDENTIFIER)
+
+
+State 72
+
+   15 expect: EXPECT IDENTIFIER .
+
+    $default  reduce using rule 15 (expect)
+
+
+State 73
+
+    6 line: command expect SEMICOLON .
+
+    $default  reduce using rule 6 (line)
+
+
+State 74
+
+  133 block: exact_sel_count OF block_content .
+
+    $default  reduce using rule 133 (block)
+
+
+State 75
+
+  134 block: low_sel_count TO high_sel_count . OF block_content
+
+    OF  shift, and go to state 124
+
+
+State 76
+
+  151 high_sel_count: NUMBER .
+
+    $default  reduce using rule 151 (high_sel_count)
+
+
+State 77
+
+   57 asset_designator: NAME STAR .
+
+    $default  reduce using rule 57 (asset_designator)
+
+
+State 78
+
+  146 ASSET_IDENTIFIER: IDENTIFIER_TOK .
+
+    $default  reduce using rule 146 (ASSET_IDENTIFIER)
+
+
+State 79
+
+   56 asset_designator: NAME ASSET_IDENTIFIER_LIST .
+
+    $default  reduce using rule 56 (asset_designator)
+
+
+State 80
+
+  143 ASSET_IDENTIFIER_LIST: ASSET_IDENTIFIER . ASSET_IDENTIFIERS
+
+    IDENTIFIER_TOK  shift, and go to state 78
+
+    $default  reduce using rule 144 (ASSET_IDENTIFIERS)
+
+    ASSET_IDENTIFIERS  go to state 125
+    ASSET_IDENTIFIER   go to state 126
+
+
+State 81
+
+   64 sst_asset_name: UID STAR .
+
+    $default  reduce using rule 64 (sst_asset_name)
+
+
+State 82
+
+  142 ASSET_NUMBER: NUMBER_TOK .
+
+    $default  reduce using rule 142 (ASSET_NUMBER)
+
+
+State 83
+
+   63 sst_asset_name: UID ASSET_NUMBER_LIST .
+
+    $default  reduce using rule 63 (sst_asset_name)
+
+
+State 84
+
+  139 ASSET_NUMBER_LIST: ASSET_NUMBER . ASSET_NUMBERS
+
+    NUMBER_TOK  shift, and go to state 82
+
+    $default  reduce using rule 140 (ASSET_NUMBERS)
+
+    ASSET_NUMBERS  go to state 127
+    ASSET_NUMBER   go to state 128
+
+
+State 85
+
+   33 sst_set_extended_args: FLAG . sst_flags
+
+    NONE        shift, and go to state 129
+    WRITE_ONCE  shift, and go to state 130
+    NO_RP       shift, and go to state 131
+    NO_CONF     shift, and go to state 132
+
+    $default  reduce using rule 34 (sst_flags)
+
+    sst_flags   go to state 133
+    sst_flag    go to state 134
+    none        go to state 135
+    write_once  go to state 136
+    no_rp       go to state 137
+    no_conf     go to state 138
+
+
+State 86
+
+   16 set_command: SET SST sst_set_base_args sst_set_extended_args .
+
+    $default  reduce using rule 16 (set_command)
+
+
+State 87
+
+   26 literal_or_random_data: DATA . LITERAL
+   27                       | DATA . STAR
+
+    STAR         shift, and go to state 139
+    LITERAL_TOK  shift, and go to state 140
+    HEX_LIST     shift, and go to state 141
+
+    LITERAL  go to state 142
+
+
+State 88
+
+   31 sst_set_base_args: sst_asset_name DFNAME . sst_asset_set_file_path
+
+    FILE_PATH_TOK  shift, and go to state 143
+
+    sst_asset_set_file_path  go to state 144
+    FILE_PATH                go to state 145
+
+
+State 89
+
+   30 sst_set_base_args: sst_asset_name VAR . IDENTIFIER
+
+    IDENTIFIER_TOK  shift, and go to state 71
+
+    IDENTIFIER  go to state 146
+
+
+State 90
+
+   28 sst_set_base_args: sst_asset_name literal_or_random_data .
+
+    $default  reduce using rule 28 (sst_set_base_args)
+
+
+State 91
+
+  124 key_set_source: POLICY . IDENTIFIER
+
+    IDENTIFIER_TOK  shift, and go to state 71
+
+    IDENTIFIER  go to state 147
+
+
+State 92
+
+  128 key_set_args: asset_designator FROM . single_existing_asset POLICY IDENTIFIER
+
+    STAR            shift, and go to state 60
+    IDENTIFIER_TOK  shift, and go to state 71
+
+    single_existing_asset  go to state 148
+    random_picked_asset    go to state 149
+    IDENTIFIER             go to state 150
+
+
+State 93
+
+  123 key_set_source: literal_or_random_data .
+  126 key_data_or_not: literal_or_random_data .
+
+    WITH      reduce using rule 126 (key_data_or_not)
+    $default  reduce using rule 123 (key_set_source)
+
+
+State 94
+
+  127 key_set_args: asset_designator key_set_sources .
+
+    $default  reduce using rule 127 (key_set_args)
+
+
+State 95
+
+  122 key_set_sources: key_set_source . key_set_sources
+
+    POLICY  shift, and go to state 91
+    DATA    shift, and go to state 87
+
+    $default  reduce using rule 121 (key_set_sources)
+
+    literal_or_random_data  go to state 151
+    key_set_sources         go to state 152
+    key_set_source          go to state 95
+
+
+State 96
+
+  129 key_set_args: asset_designator key_data_or_not . WITH policy_specs
+
+    WITH  shift, and go to state 153
+
+
+State 97
+
+  114 policy_asset_spec: NAME STAR .
+
+    $default  reduce using rule 114 (policy_asset_spec)
+
+
+State 98
+
+  113 policy_asset_spec: NAME ASSET_IDENTIFIER_LIST .
+
+    $default  reduce using rule 113 (policy_asset_spec)
+
+
+State 99
+
+   69 policy_usage_list: ATTR . policy_usage policy_usages
+
+    NUMBER_TOK  shift, and go to state 154
+    EXPORT      shift, and go to state 155
+    COPY        shift, and go to state 156
+    ENCRYPT     shift, and go to state 157
+    DECRYPT     shift, and go to state 158
+    SIGN        shift, and go to state 159
+    VERIFY      shift, and go to state 160
+    DERIVE      shift, and go to state 161
+    NOEXPORT    shift, and go to state 162
+    NOCOPY      shift, and go to state 163
+    NOENCRYPT   shift, and go to state 164
+    NODECRYPT   shift, and go to state 165
+    NOSIGN      shift, and go to state 166
+    NOVERIFY    shift, and go to state 167
+    NODERIVE    shift, and go to state 168
+    PERSISTENT  shift, and go to state 169
+    VOLATILE    shift, and go to state 170
+
+    key_size      go to state 171
+    export        go to state 172
+    noexport      go to state 173
+    copy          go to state 174
+    nocopy        go to state 175
+    encrypt       go to state 176
+    noencrypt     go to state 177
+    decrypt       go to state 178
+    nodecrypt     go to state 179
+    sign          go to state 180
+    nosign        go to state 181
+    verify        go to state 182
+    noverify      go to state 183
+    derive        go to state 184
+    noderive      go to state 185
+    persistent    go to state 186
+    volatle       go to state 187
+    policy_usage  go to state 188
+
+
+State 100
+
+  105 policy_type: TYPE . IDENTIFIER
+
+    IDENTIFIER_TOK  shift, and go to state 71
+
+    IDENTIFIER  go to state 189
+
+
+State 101
+
+  106 policy_algorithm: ALG . IDENTIFIER
+
+    IDENTIFIER_TOK  shift, and go to state 71
+
+    IDENTIFIER  go to state 190
+
+
+State 102
+
+  109 policy_spec: policy_usage_list .
+
+    $default  reduce using rule 109 (policy_spec)
+
+
+State 103
+
+  110 policy_spec: policy_type .
+
+    $default  reduce using rule 110 (policy_spec)
+
+
+State 104
+
+  111 policy_spec: policy_algorithm .
+
+    $default  reduce using rule 111 (policy_spec)
+
+
+State 105
+
+  119 policy_set_args: policy_asset_spec policy_specs .
+
+    $default  reduce using rule 119 (policy_set_args)
+
+
+State 106
+
+  108 policy_specs: policy_spec . policy_specs
+
+    ATTR  shift, and go to state 99
+    TYPE  shift, and go to state 100
+    ALG   shift, and go to state 101
+
+    $default  reduce using rule 107 (policy_specs)
+
+    policy_usage_list  go to state 102
+    policy_type        go to state 103
+    policy_algorithm   go to state 104
+    policy_specs       go to state 191
+    policy_spec        go to state 106
+
+
+State 107
+
+   51 read_args: DFNAME . sst_asset_dump_file_path
+
+    FILE_PATH_TOK  shift, and go to state 143
+
+    sst_asset_dump_file_path  go to state 192
+    FILE_PATH                 go to state 193
+
+
+State 108
+
+   47 read_args: CHECK . read_args_var_name
+   48          | CHECK . LITERAL
+
+    IDENTIFIER_TOK  shift, and go to state 71
+    LITERAL_TOK     shift, and go to state 140
+    HEX_LIST        shift, and go to state 141
+
+    read_args_var_name  go to state 194
+    IDENTIFIER          go to state 195
+    LITERAL             go to state 196
+
+
+State 109
+
+   46 read_args: VAR . IDENTIFIER
+
+    IDENTIFIER_TOK  shift, and go to state 71
+
+    IDENTIFIER  go to state 197
+
+
+State 110
+
+   50 read_args: HASH .
+
+    $default  reduce using rule 50 (read_args)
+
+
+State 111
+
+   49 read_args: PRINT .
+
+    $default  reduce using rule 49 (read_args)
+
+
+State 112
+
+   45 sst_read_args: sst_asset_name read_args . sst_read_extended_args
+
+    OFFSET  shift, and go to state 198
+
+    $default  reduce using rule 52 (sst_read_extended_args)
+
+    sst_read_extended_args  go to state 199
+
+
+State 113
+
+  131 key_read_args: asset_designator read_args .
+
+    $default  reduce using rule 131 (key_read_args)
+
+
+State 114
+
+  118 policy_asset_name: KEY IDENTIFIER .
+
+    $default  reduce using rule 118 (policy_asset_name)
+
+
+State 115
+
+  115 policy_asset_name: NAME IDENTIFIER .
+
+    $default  reduce using rule 115 (policy_asset_name)
+
+
+State 116
+
+  116 policy_asset_name: STAR ACTIVE .
+
+    $default  reduce using rule 116 (policy_asset_name)
+
+
+State 117
+
+  117 policy_asset_name: STAR DELETED .
+
+    $default  reduce using rule 117 (policy_asset_name)
+
+
+State 118
+
+  120 policy_read_args: policy_asset_name read_args .
+
+    $default  reduce using rule 120 (policy_read_args)
+
+
+State 119
+
+   60 random_picked_asset: STAR ACTIVE .
+
+    $default  reduce using rule 60 (random_picked_asset)
+
+
+State 120
+
+   61 random_picked_asset: STAR DELETED .
+
+    $default  reduce using rule 61 (random_picked_asset)
+
+
+State 121
+
+   24 secure_command: SECURE HASH NEQ ASSET_IDENTIFIER_LIST .
+
+    $default  reduce using rule 24 (secure_command)
+
+
+State 122
+
+  138 close_brace: CLOSE_BRACE .
+
+    $default  reduce using rule 138 (close_brace)
+
+
+State 123
+
+  135 block_content: open_brace lines close_brace .
+
+    $default  reduce using rule 135 (block_content)
+
+
+State 124
+
+  134 block: low_sel_count TO high_sel_count OF . block_content
+
+    PURPOSE     shift, and go to state 1
+    SET         shift, and go to state 2
+    READ        shift, and go to state 3
+    REMOVE      shift, and go to state 4
+    SECURE      shift, and go to state 5
+    DONE        shift, and go to state 6
+    NUMBER_TOK  shift, and go to state 7
+    SHUFFLE     shift, and go to state 8
+    OPEN_BRACE  shift, and go to state 30
+
+    line             go to state 31
+    command          go to state 11
+    set_command      go to state 12
+    read_command     go to state 13
+    remove_command   go to state 14
+    secure_command   go to state 15
+    done_command     go to state 16
+    block            go to state 17
+    block_content    go to state 200
+    open_brace       go to state 33
+    exact_sel_count  go to state 18
+    low_sel_count    go to state 19
+    NUMBER           go to state 20
+
+
+State 125
+
+  143 ASSET_IDENTIFIER_LIST: ASSET_IDENTIFIER ASSET_IDENTIFIERS .
+
+    $default  reduce using rule 143 (ASSET_IDENTIFIER_LIST)
+
+
+State 126
+
+  145 ASSET_IDENTIFIERS: ASSET_IDENTIFIER . ASSET_IDENTIFIERS
+
+    IDENTIFIER_TOK  shift, and go to state 78
+
+    $default  reduce using rule 144 (ASSET_IDENTIFIERS)
+
+    ASSET_IDENTIFIERS  go to state 201
+    ASSET_IDENTIFIER   go to state 126
+
+
+State 127
+
+  139 ASSET_NUMBER_LIST: ASSET_NUMBER ASSET_NUMBERS .
+
+    $default  reduce using rule 139 (ASSET_NUMBER_LIST)
+
+
+State 128
+
+  141 ASSET_NUMBERS: ASSET_NUMBER . ASSET_NUMBERS
+
+    NUMBER_TOK  shift, and go to state 82
+
+    $default  reduce using rule 140 (ASSET_NUMBERS)
+
+    ASSET_NUMBERS  go to state 202
+    ASSET_NUMBER   go to state 128
+
+
+State 129
+
+   40 none: NONE .
+
+    $default  reduce using rule 40 (none)
+
+
+State 130
+
+   41 write_once: WRITE_ONCE .
+
+    $default  reduce using rule 41 (write_once)
+
+
+State 131
+
+   42 no_rp: NO_RP .
+
+    $default  reduce using rule 42 (no_rp)
+
+
+State 132
+
+   43 no_conf: NO_CONF .
+
+    $default  reduce using rule 43 (no_conf)
+
+
+State 133
+
+   33 sst_set_extended_args: FLAG sst_flags .
+
+    $default  reduce using rule 33 (sst_set_extended_args)
+
+
+State 134
+
+   35 sst_flags: sst_flag . sst_flags
+
+    NONE        shift, and go to state 129
+    WRITE_ONCE  shift, and go to state 130
+    NO_RP       shift, and go to state 131
+    NO_CONF     shift, and go to state 132
+
+    $default  reduce using rule 34 (sst_flags)
+
+    sst_flags   go to state 203
+    sst_flag    go to state 134
+    none        go to state 135
+    write_once  go to state 136
+    no_rp       go to state 137
+    no_conf     go to state 138
+
+
+State 135
+
+   36 sst_flag: none .
+
+    $default  reduce using rule 36 (sst_flag)
+
+
+State 136
+
+   37 sst_flag: write_once .
+
+    $default  reduce using rule 37 (sst_flag)
+
+
+State 137
+
+   38 sst_flag: no_rp .
+
+    $default  reduce using rule 38 (sst_flag)
+
+
+State 138
+
+   39 sst_flag: no_conf .
+
+    $default  reduce using rule 39 (sst_flag)
+
+
+State 139
+
+   27 literal_or_random_data: DATA STAR .
+
+    $default  reduce using rule 27 (literal_or_random_data)
+
+
+State 140
+
+  153 LITERAL: LITERAL_TOK .
+
+    $default  reduce using rule 153 (LITERAL)
+
+
+State 141
+
+  154 LITERAL: HEX_LIST .
+
+    $default  reduce using rule 154 (LITERAL)
+
+
+State 142
+
+   26 literal_or_random_data: DATA LITERAL .
+
+    $default  reduce using rule 26 (literal_or_random_data)
+
+
+State 143
+
+  148 FILE_PATH: FILE_PATH_TOK .
+
+    $default  reduce using rule 148 (FILE_PATH)
+
+
+State 144
+
+   31 sst_set_base_args: sst_asset_name DFNAME sst_asset_set_file_path .
+
+    $default  reduce using rule 31 (sst_set_base_args)
+
+
+State 145
+
+   65 sst_asset_set_file_path: FILE_PATH .
+
+    $default  reduce using rule 65 (sst_asset_set_file_path)
+
+
+State 146
+
+   30 sst_set_base_args: sst_asset_name VAR IDENTIFIER .
+
+    $default  reduce using rule 30 (sst_set_base_args)
+
+
+State 147
+
+  124 key_set_source: POLICY IDENTIFIER .
+
+    $default  reduce using rule 124 (key_set_source)
+
+
+State 148
+
+  128 key_set_args: asset_designator FROM single_existing_asset . POLICY IDENTIFIER
+
+    POLICY  shift, and go to state 204
+
+
+State 149
+
+   59 single_existing_asset: random_picked_asset .
+
+    $default  reduce using rule 59 (single_existing_asset)
+
+
+State 150
+
+   58 single_existing_asset: IDENTIFIER .
+
+    $default  reduce using rule 58 (single_existing_asset)
+
+
+State 151
+
+  123 key_set_source: literal_or_random_data .
+
+    $default  reduce using rule 123 (key_set_source)
+
+
+State 152
+
+  122 key_set_sources: key_set_source key_set_sources .
+
+    $default  reduce using rule 122 (key_set_sources)
+
+
+State 153
+
+  129 key_set_args: asset_designator key_data_or_not WITH . policy_specs
+
+    ATTR  shift, and go to state 99
+    TYPE  shift, and go to state 100
+    ALG   shift, and go to state 101
+
+    $default  reduce using rule 107 (policy_specs)
+
+    policy_usage_list  go to state 102
+    policy_type        go to state 103
+    policy_algorithm   go to state 104
+    policy_specs       go to state 205
+    policy_spec        go to state 106
+
+
+State 154
+
+   68 key_size: NUMBER_TOK .
+
+    $default  reduce using rule 68 (key_size)
+
+
+State 155
+
+   72 export: EXPORT .
+
+    $default  reduce using rule 72 (export)
+
+
+State 156
+
+   74 copy: COPY .
+
+    $default  reduce using rule 74 (copy)
+
+
+State 157
+
+   76 encrypt: ENCRYPT .
+
+    $default  reduce using rule 76 (encrypt)
+
+
+State 158
+
+   78 decrypt: DECRYPT .
+
+    $default  reduce using rule 78 (decrypt)
+
+
+State 159
+
+   80 sign: SIGN .
+
+    $default  reduce using rule 80 (sign)
+
+
+State 160
+
+   82 verify: VERIFY .
+
+    $default  reduce using rule 82 (verify)
+
+
+State 161
+
+   84 derive: DERIVE .
+
+    $default  reduce using rule 84 (derive)
+
+
+State 162
+
+   73 noexport: NOEXPORT .
+
+    $default  reduce using rule 73 (noexport)
+
+
+State 163
+
+   75 nocopy: NOCOPY .
+
+    $default  reduce using rule 75 (nocopy)
+
+
+State 164
+
+   77 noencrypt: NOENCRYPT .
+
+    $default  reduce using rule 77 (noencrypt)
+
+
+State 165
+
+   79 nodecrypt: NODECRYPT .
+
+    $default  reduce using rule 79 (nodecrypt)
+
+
+State 166
+
+   81 nosign: NOSIGN .
+
+    $default  reduce using rule 81 (nosign)
+
+
+State 167
+
+   83 noverify: NOVERIFY .
+
+    $default  reduce using rule 83 (noverify)
+
+
+State 168
+
+   85 noderive: NODERIVE .
+
+    $default  reduce using rule 85 (noderive)
+
+
+State 169
+
+   86 persistent: PERSISTENT .
+
+    $default  reduce using rule 86 (persistent)
+
+
+State 170
+
+   87 volatle: VOLATILE .
+
+    $default  reduce using rule 87 (volatle)
+
+
+State 171
+
+  104 policy_usage: key_size .
+
+    $default  reduce using rule 104 (policy_usage)
+
+
+State 172
+
+   88 policy_usage: export .
+
+    $default  reduce using rule 88 (policy_usage)
+
+
+State 173
+
+   95 policy_usage: noexport .
+
+    $default  reduce using rule 95 (policy_usage)
+
+
+State 174
+
+   89 policy_usage: copy .
+
+    $default  reduce using rule 89 (policy_usage)
+
+
+State 175
+
+   96 policy_usage: nocopy .
+
+    $default  reduce using rule 96 (policy_usage)
+
+
+State 176
+
+   90 policy_usage: encrypt .
+
+    $default  reduce using rule 90 (policy_usage)
+
+
+State 177
+
+   97 policy_usage: noencrypt .
+
+    $default  reduce using rule 97 (policy_usage)
+
+
+State 178
+
+   91 policy_usage: decrypt .
+
+    $default  reduce using rule 91 (policy_usage)
+
+
+State 179
+
+   98 policy_usage: nodecrypt .
+
+    $default  reduce using rule 98 (policy_usage)
+
+
+State 180
+
+   92 policy_usage: sign .
+
+    $default  reduce using rule 92 (policy_usage)
+
+
+State 181
+
+   99 policy_usage: nosign .
+
+    $default  reduce using rule 99 (policy_usage)
+
+
+State 182
+
+   93 policy_usage: verify .
+
+    $default  reduce using rule 93 (policy_usage)
+
+
+State 183
+
+  100 policy_usage: noverify .
+
+    $default  reduce using rule 100 (policy_usage)
+
+
+State 184
+
+   94 policy_usage: derive .
+
+    $default  reduce using rule 94 (policy_usage)
+
+
+State 185
+
+  101 policy_usage: noderive .
+
+    $default  reduce using rule 101 (policy_usage)
+
+
+State 186
+
+  102 policy_usage: persistent .
+
+    $default  reduce using rule 102 (policy_usage)
+
+
+State 187
+
+  103 policy_usage: volatle .
+
+    $default  reduce using rule 103 (policy_usage)
+
+
+State 188
+
+   69 policy_usage_list: ATTR policy_usage . policy_usages
+
+    NUMBER_TOK  shift, and go to state 154
+    EXPORT      shift, and go to state 155
+    COPY        shift, and go to state 156
+    ENCRYPT     shift, and go to state 157
+    DECRYPT     shift, and go to state 158
+    SIGN        shift, and go to state 159
+    VERIFY      shift, and go to state 160
+    DERIVE      shift, and go to state 161
+    NOEXPORT    shift, and go to state 162
+    NOCOPY      shift, and go to state 163
+    NOENCRYPT   shift, and go to state 164
+    NODECRYPT   shift, and go to state 165
+    NOSIGN      shift, and go to state 166
+    NOVERIFY    shift, and go to state 167
+    NODERIVE    shift, and go to state 168
+    PERSISTENT  shift, and go to state 169
+    VOLATILE    shift, and go to state 170
+
+    $default  reduce using rule 70 (policy_usages)
+
+    key_size       go to state 171
+    policy_usages  go to state 206
+    export         go to state 172
+    noexport       go to state 173
+    copy           go to state 174
+    nocopy         go to state 175
+    encrypt        go to state 176
+    noencrypt      go to state 177
+    decrypt        go to state 178
+    nodecrypt      go to state 179
+    sign           go to state 180
+    nosign         go to state 181
+    verify         go to state 182
+    noverify       go to state 183
+    derive         go to state 184
+    noderive       go to state 185
+    persistent     go to state 186
+    volatle        go to state 187
+    policy_usage   go to state 207
+
+
+State 189
+
+  105 policy_type: TYPE IDENTIFIER .
+
+    $default  reduce using rule 105 (policy_type)
+
+
+State 190
+
+  106 policy_algorithm: ALG IDENTIFIER .
+
+    $default  reduce using rule 106 (policy_algorithm)
+
+
+State 191
+
+  108 policy_specs: policy_spec policy_specs .
+
+    $default  reduce using rule 108 (policy_specs)
+
+
+State 192
+
+   51 read_args: DFNAME sst_asset_dump_file_path .
+
+    $default  reduce using rule 51 (read_args)
+
+
+State 193
+
+   67 sst_asset_dump_file_path: FILE_PATH .
+
+    $default  reduce using rule 67 (sst_asset_dump_file_path)
+
+
+State 194
+
+   47 read_args: CHECK read_args_var_name .
+
+    $default  reduce using rule 47 (read_args)
+
+
+State 195
+
+   66 read_args_var_name: IDENTIFIER .
+
+    $default  reduce using rule 66 (read_args_var_name)
+
+
+State 196
+
+   48 read_args: CHECK LITERAL .
+
+    $default  reduce using rule 48 (read_args)
+
+
+State 197
+
+   46 read_args: VAR IDENTIFIER .
+
+    $default  reduce using rule 46 (read_args)
+
+
+State 198
+
+   53 sst_read_extended_args: OFFSET . sst_offset_spec
+
+    NUMBER_TOK  shift, and go to state 208
+
+    sst_offset_spec  go to state 209
+
+
+State 199
+
+   45 sst_read_args: sst_asset_name read_args sst_read_extended_args .
+
+    $default  reduce using rule 45 (sst_read_args)
+
+
+State 200
+
+  134 block: low_sel_count TO high_sel_count OF block_content .
+
+    $default  reduce using rule 134 (block)
+
+
+State 201
+
+  145 ASSET_IDENTIFIERS: ASSET_IDENTIFIER ASSET_IDENTIFIERS .
+
+    $default  reduce using rule 145 (ASSET_IDENTIFIERS)
+
+
+State 202
+
+  141 ASSET_NUMBERS: ASSET_NUMBER ASSET_NUMBERS .
+
+    $default  reduce using rule 141 (ASSET_NUMBERS)
+
+
+State 203
+
+   35 sst_flags: sst_flag sst_flags .
+
+    $default  reduce using rule 35 (sst_flags)
+
+
+State 204
+
+  128 key_set_args: asset_designator FROM single_existing_asset POLICY . IDENTIFIER
+
+    IDENTIFIER_TOK  shift, and go to state 71
+
+    IDENTIFIER  go to state 210
+
+
+State 205
+
+  129 key_set_args: asset_designator key_data_or_not WITH policy_specs .
+
+    $default  reduce using rule 129 (key_set_args)
+
+
+State 206
+
+   69 policy_usage_list: ATTR policy_usage policy_usages .
+
+    $default  reduce using rule 69 (policy_usage_list)
+
+
+State 207
+
+   71 policy_usages: policy_usage . policy_usages
+
+    NUMBER_TOK  shift, and go to state 154
+    EXPORT      shift, and go to state 155
+    COPY        shift, and go to state 156
+    ENCRYPT     shift, and go to state 157
+    DECRYPT     shift, and go to state 158
+    SIGN        shift, and go to state 159
+    VERIFY      shift, and go to state 160
+    DERIVE      shift, and go to state 161
+    NOEXPORT    shift, and go to state 162
+    NOCOPY      shift, and go to state 163
+    NOENCRYPT   shift, and go to state 164
+    NODECRYPT   shift, and go to state 165
+    NOSIGN      shift, and go to state 166
+    NOVERIFY    shift, and go to state 167
+    NODERIVE    shift, and go to state 168
+    PERSISTENT  shift, and go to state 169
+    VOLATILE    shift, and go to state 170
+
+    $default  reduce using rule 70 (policy_usages)
+
+    key_size       go to state 171
+    policy_usages  go to state 211
+    export         go to state 172
+    noexport       go to state 173
+    copy           go to state 174
+    nocopy         go to state 175
+    encrypt        go to state 176
+    noencrypt      go to state 177
+    decrypt        go to state 178
+    nodecrypt      go to state 179
+    sign           go to state 180
+    nosign         go to state 181
+    verify         go to state 182
+    noverify       go to state 183
+    derive         go to state 184
+    noderive       go to state 185
+    persistent     go to state 186
+    volatle        go to state 187
+    policy_usage   go to state 207
+
+
+State 208
+
+   44 sst_offset_spec: NUMBER_TOK .
+
+    $default  reduce using rule 44 (sst_offset_spec)
+
+
+State 209
+
+   53 sst_read_extended_args: OFFSET sst_offset_spec .
+
+    $default  reduce using rule 53 (sst_read_extended_args)
+
+
+State 210
+
+  128 key_set_args: asset_designator FROM single_existing_asset POLICY IDENTIFIER .
+
+    $default  reduce using rule 128 (key_set_args)
+
+
+State 211
+
+   71 policy_usages: policy_usage policy_usages .
+
+    $default  reduce using rule 71 (policy_usages)
diff --git a/tf_fuzz/parser/tf_fuzz_grammar.tab.cpp b/tf_fuzz/parser/tf_fuzz_grammar.tab.cpp
new file mode 100644
index 0000000..6a1e852
--- /dev/null
+++ b/tf_fuzz/parser/tf_fuzz_grammar.tab.cpp
@@ -0,0 +1,3497 @@
+/* A Bison parser, made by GNU Bison 3.0.4.  */
+
+/* Bison implementation for Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+   simplifying the original so-called "semantic" parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Bison version.  */
+#define YYBISON_VERSION "3.0.4"
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 0
+
+/* Push parsers.  */
+#define YYPUSH 0
+
+/* Pull parsers.  */
+#define YYPULL 1
+
+
+
+
+/* Copy the first part of user declarations.  */
+#line 8 "parser/tf_fuzz_grammar.y" /* yacc.c:339  */
+
+#include <iostream>
+#include <vector>
+#include <set>
+
+#include "class_forwards.hpp"
+#include "data_blocks.hpp"
+#include "boilerplate.hpp"
+#include "gibberish.hpp"
+#include "compute.hpp"
+#include "string_ops.hpp"
+#include "psa_asset.hpp"
+#include "find_or_create_asset.hpp"
+#include "template_line.hpp"
+#include "tf_fuzz.hpp"
+#include "sst_asset.hpp"
+#include "crypto_asset.hpp"
+#include "psa_call.hpp"
+#include "crypto_call.hpp"
+#include "sst_call.hpp"
+#include "security_call.hpp"
+#include "secure_template_line.hpp"
+#include "sst_template_line.hpp"
+#include "crypto_template_line.hpp"
+
+/* These items are defined in tf_fuzz_grammar.l.  Note, however that, because
+   of "name mangling," defining them as extern "C" may or may not be ideal,
+   depending upon which compiler -- gcc vs. g++, compiles the output from lex.
+   So far, it seems best without the extern "C", including also compiling
+   under Visual Studio. */
+/* extern "C"
+{ */
+  extern int yylineno;
+  int yywrap() {return 1;}
+  extern char yytext[];
+  extern int yyleng;
+/* } */
+
+int yylex (void);
+void yyerror (tf_fuzz_info *, const char *);
+    /* Sends the yyparse() argument to yyerror(), probably, to print incorrect
+       text it parsed. */
+
+/* A few consts just to make code more comprehensible: */
+const bool yes_fill_in_template = true;
+const bool dont_fill_in_template = false;
+const bool yes_create_call = true;
+const bool dont_create_call = false;
+
+tf_fuzz_info *rsrc;
+
+/* These are object pointers used to parse the template and create the test.  Ac-
+   tually, probably only templateLin is used for now, but this is a good outline of
+   of the template_line class hierarchy. */
+template_line                   *templateLin = nullptr;
+  sst_template_line             *sstTemplateLin = nullptr;
+    set_sst_template_line       *setSstTemplateLin = nullptr;
+    read_sst_template_line      *reaSstTemplateLin = nullptr;
+    remove_sst_template_line    *remSstTemplateLin = nullptr;
+  policy_template_line          *polTemplateLin = nullptr;
+    set_policy_template_line    *setPolTemplateLin = nullptr;
+    read_policy_template_line   *reaPolTemplateLin = nullptr;
+  key_template_line             *keyTemplateLin = nullptr;
+    set_key_template_line       *setKeyTemplateLin = nullptr;
+    read_key_template_line      *reaKeyTemplateLin = nullptr;
+    remove_key_template_line    *remKeyTemplateLin = nullptr;
+  security_template_line        *secTemplateLin = nullptr;
+    security_hash_template_line *secHasTemplateLin = nullptr;
+/* Call and asset objects are presumably not immediately needed, because the objects
+   of these types are within the resource object, *rsrc, but even if only just to
+   show that class hierarchy: */
+psa_call                        *psaCal = nullptr;
+  sst_call                      *sstCal = nullptr;
+    sst_set_call                *sstSetCal = nullptr;
+    sst_get_call                *sstGetCal = nullptr;
+    sst_remove_call             *sstRemCal = nullptr;
+  crypto_call                   *cryCal = nullptr;
+    policy_call                 *polCal = nullptr;
+      init_policy_call          *iniPolCal = nullptr;
+      reset_policy_call         *resPolCal = nullptr;
+      add_policy_usage_call     *addPolUsaCal = nullptr;
+      set_policy_lifetime_call  *setPolLifCal = nullptr;
+      set_policy_type_call      *setPolTypCal = nullptr;
+      set_policy_algorithm_call *setPolAlgCal = nullptr;
+      set_policy_usage_call     *setPolUsaCal = nullptr;
+      get_policy_lifetime_call  *getPolLifCal = nullptr;
+      get_policy_type_call      *getPolTypCal = nullptr;
+      get_policy_algorithm_call *getPolAlgCal = nullptr;
+      get_policy_usage_call     *getPolUsaCal = nullptr;
+      get_policy_size_call      *getPolSizCal = nullptr;
+      get_key_policy_call       *getKeyPolCal = nullptr;
+    key_call                    *keyCal = nullptr;
+      generate_key_call         *genKeyCal = nullptr;
+      create_key_call           *creKeyCal = nullptr;
+      copy_key_call             *copKeyCal = nullptr;
+      read_key_data_call        *reaKeyDatCal = nullptr;
+      remove_key_call           *remKeyCal = nullptr;
+psa_asset                       *psaAst = nullptr;
+  sst_asset                     *sstAst = nullptr;
+  crypto_asset                  *cryAst = nullptr;
+    policy_asset                *polAst = nullptr;
+    key_asset                   *keyAst = nullptr;
+
+/* For generating random, but readable/memorable, data: */
+gibberish gib;
+char gib_buff[4096];  // spew gibberish into here
+int rand_data_length = 0;
+
+/* General-utility variables: */
+bool purpose_defined = false;
+psa_asset_usage random_asset = psa_asset_usage::all;
+    /* to pick what type of asset at random */
+bool random_name;  /* template didn't specify name, so it's generated randomly */
+string literal_data;  /* literal data for an asset value */
+
+/* Holders for state in read commands: */
+expect_info expect;  /* everything about expected results and data */
+set_data_info set_data;  /* everything about setting the value of PSA-asset data */
+asset_name_id_info parsed_asset;  /* everything about identifying assets */
+string target_barrier = "";  /* asset to set and search barrier when re-ordering PSA calls */
+key_policy_info policy_info;  /* everything about key policies */
+bool assign_data_var_specified = false;
+string assign_data_var;
+bool print_data = false;  /* true to just print asset data to the test log */
+bool hash_data = false;  /* true to just print asset data to the test log */
+bool literal_is_string = true;
+    /* if true, literal value is character-string;  if false, is list of hex values */
+
+/* The following are more tied to the template syntax than to the resulting PSA calls */
+string literal;  /* temporary holder for all string literals */
+string identifier;  /* temporary holder for strings representing identifiers */
+string var_name;  /* a variable name */
+string asset_name;  /* as parsed, not yet put into parsed_asset */
+string aid;  /* string-typed holder for an asset ID in a list thereof */
+int nid;  /* same idea as aid, but for asset ID# lists */
+size_t strFind1, strFind2;  /* for searching through strings */
+
+/* Because of the parsing order, psa_calls of the specific type have to be
+   push_back()ed onto rsrc->calls before their expected results are known.  Therefore,
+   must inject those results after parsing the expected results.  add_expect is a
+   loop index to track where to add results. */
+unsigned int add_expect = 0;
+
+/* Temporaries: */
+vector<psa_asset*>::iterator t_sst_asset;
+vector<psa_asset*>::iterator t_key_asset;
+vector<psa_asset*>::iterator t_policy_asset;
+sst_call *t_sst_call = nullptr;
+key_call *t_key_call = nullptr;
+policy_call *t_policy_call = nullptr;
+long number;  /* temporary holder for a number, e.g., sting form of UID */
+int i, j, k;
+
+/* Relating to template-statement blocks: */
+vector<template_line*> template_block_vector;  /* (must be *pointers to* templates) */
+vector<int> block_order;  /* "statisticalized" order of template lines in a block */
+int nesting_level = 0;
+    /* how many levels deep in { } nesting currently.  Initially only 0 or 1. */
+bool shuffle_not_pick;
+    /* true to shuffle statements in a block, rather than pick so-and-so
+       number of them at random. */
+int low_nmbr_lines = 1;  /* if picking so-and-so number of template lines from a ... */
+int high_nmbr_lines = 1; /*    ... block at random, these are fewest and most lines. */
+int exact_nmbr_lines = 1;
+
+using namespace std;
+
+
+void set_purp_str (
+    char *raw_purpose,  /* the purpose C string from parser */
+    tf_fuzz_info *rsrc  /* test resources containing the actual test-purpose string */
+) {
+    size_t l;  /* temporary of size_t type */
+    string purp_str = raw_purpose;
+    strFind1 = purp_str.find (" ");
+    purp_str = purp_str.substr (strFind1, purp_str.length());
+    purp_str.erase (0, 1);  // (extra space)
+    strFind1 = purp_str.rfind (";");
+    purp_str = purp_str.substr (0, strFind1);
+    l = 0;
+    do {  /* escape all " chars (if not already escaped) */
+        l = purp_str.find ("\"", l);
+        if (   l < purp_str.length()) {  /* did find a quote character */
+            if (   l == 0  /* it's the first character in the string*/
+                || purp_str[l-1] != '\\' /* or it's not already escaped */
+               ) {
+                purp_str.insert (l, "\\");  /* then escape the " char */
+                l++;  /* point l to the " again */
+            }
+            l++;  /* point l past the " */
+        }
+    } while (l < purp_str.length());
+    rsrc->test_purpose = purp_str;
+}
+
+/* randomize_template_lines() chooses a template-line order in cases where they are to
+   be randomized -- shuffled or random picked. */
+void randomize_template_lines (
+    bool shuffle_not_pick,  /* true to perform a shuffle operation rather than pick */
+    int &low_nmbr_lines, /* if picking so-and-so number of template lines from a ... */
+    int &high_nmbr_lines, /*    ... block at random, these are fewest and most lines. */
+    int &exact_nmbr_lines,
+    vector<template_line*> &template_block_vector,
+    vector<int> &block_order,
+    tf_fuzz_info *rsrc  /* test resources containing the actual test-purpose string */
+) {
+    set<int> template_used;  /* used for shuffle */
+    low_nmbr_lines = (low_nmbr_lines < 0)?  0 : low_nmbr_lines;
+    high_nmbr_lines = (high_nmbr_lines < 0)?  0 : high_nmbr_lines;
+    if (low_nmbr_lines > high_nmbr_lines) {
+        int swap = low_nmbr_lines;
+        low_nmbr_lines = high_nmbr_lines;
+        high_nmbr_lines = swap;
+    }
+    template_used.clear();
+    if (shuffle_not_pick) {
+        /* Choose a random order in which to generate all of the
+           template lines in the block: */
+        while (template_used.size() < template_block_vector.size()) {
+            i = rand() % template_block_vector.size();
+            if (template_used.find (i) == template_used.end()) {
+                /* This template not already shuffled in. */
+                block_order.push_back (i);
+                template_used.insert (i);
+            }
+        }
+        /* Done shuffling;  empty out the set: */
+    } else {
+        if (high_nmbr_lines == low_nmbr_lines) {
+            exact_nmbr_lines = low_nmbr_lines;
+                /* just in case the template says "3 to 3 of"... */
+        } else {
+            exact_nmbr_lines =   low_nmbr_lines
+                               + (rand() % (  high_nmbr_lines
+                                            - low_nmbr_lines + 1  )  );
+        }
+        for (int j = 0;  j < exact_nmbr_lines;  ++j) {
+            /* Repeatedly choose a random template line from the block: */
+            i = rand() % template_block_vector.size();
+            block_order.push_back (i);
+        }
+    }
+    IVM(cout << "Order of lines in block:  " << flush;
+        for (auto i : block_order) {
+            cout << i << "  ";
+        }
+        cout << endl;
+    )
+}
+
+/* interpret_template_line() fills in random data, locates PSA assets, (etc.) and
+   conditionally creates PSA calls for a given template line.  Note that there needs
+   to be a single place where all of this is done, so that statement blocks can be
+   randomized and then dispatched from a single point. */
+void interpret_template_line (
+    template_line *templateLin,  /* the template line to process */
+    tf_fuzz_info *rsrc,  /* program resources in general */
+    set_data_info &set_data, psa_asset_usage random_asset,
+    bool assign_data_var_specified, expect_info &expect, key_policy_info &policy_info,
+    bool print_data, bool hash_data, string asset_name, string assign_data_var,
+    asset_name_id_info &asset_info,  /* everything about the asset(s) involved */
+    bool create_call_bool,  /* true to create the PSA call at this time */
+    bool create_asset_bool,  /* true to create the PSA asset at this time */
+    bool fill_in_template,  /* true to back-fill info into template */
+    int instance
+        /* if further differentiation to the names or IDs is needed, make instance >0 */
+) {
+    const bool yes_fill_in_template = true;  /* just to improve readability */
+    vector<psa_asset*>::iterator t_psa_asset;
+
+    if (fill_in_template) {
+        /* Set basic parameters from the template line: */
+        templateLin->set_data = set_data;
+        templateLin->expect = expect;
+        templateLin->policy_info = policy_info;
+        templateLin->asset_info.id_n_not_name = asset_info.id_n_not_name;
+        templateLin->asset_info.set_name (asset_name);
+        /* Fill in state parsed from the template below: */
+        templateLin->assign_data_var_specified = assign_data_var_specified;
+        templateLin->assign_data_var.assign (assign_data_var);
+        templateLin->print_data = print_data;
+        templateLin->hash_data = hash_data;
+        templateLin->random_asset = random_asset;
+        if (   set_data.literal_data_not_file && !set_data.random_data
+            && set_data.string_specified) {
+            templateLin->set_data.set (literal_data);
+        }
+        /* Save names or IDs to the template-line tracker: */
+        for (auto id_no : asset_info.asset_id_n_vector) {
+             templateLin->asset_info.asset_id_n_vector.push_back (id_no);
+        }
+        asset_info.asset_id_n_vector.clear();
+        for (auto as_name : asset_info.asset_name_vector) {
+             templateLin->asset_info.asset_name_vector.push_back (as_name);
+        }
+        asset_info.asset_name_vector.clear();
+    }
+
+    /* Random asset choice (e.g., *active) case: */
+    if (templateLin->random_asset != psa_asset_usage::all) {
+        /* Just create the call tracker;  random name chosen in simulation stage: */
+        templateLin->setup_call (set_data, templateLin->set_data.random_data,
+                                 yes_fill_in_template, create_call_bool,
+                                 templateLin, rsrc   );
+    } else if (asset_info.id_n_not_name) {
+        /* Not random asset;  asset(s) by ID rather than name.  Go through all
+           specified asset IDs: */
+        uint64_t id_no;
+        for (auto id_n :  templateLin->asset_info.asset_id_n_vector) {
+            id_no = id_n + (uint64_t) instance * 10000UL;
+            templateLin->asset_info.set_id_n(id_no);  /* just a holder */
+            asset_name = templateLin->asset_info.make_id_n_based_name (id_no);
+            templateLin->asset_info.set_calc_name (asset_name);
+            templateLin->expect.data_var = var_name;
+            if (!set_data.literal_data_not_file) {
+                templateLin->set_data.set_file (set_data.file_path);
+            }
+            templateLin->setup_call (set_data, templateLin->set_data.random_data,
+                                     fill_in_template, create_call_bool,
+                                     templateLin, rsrc   );
+        }
+    } else {
+        /* Not random asset, asset(s) specified by name.  Go through all specified
+           asset names: */
+        for (auto as_name :  templateLin->asset_info.asset_name_vector) {
+            /* Also copy into template line object's local vector: */
+            if (instance > 0) {
+                templateLin->asset_info.set_name (as_name + "_" + to_string (instance));
+            } else {
+                templateLin->asset_info.set_name (as_name);
+            }
+            /* Give each occurrence a different random ID: */
+            templateLin->asset_info.set_id_n (100 + (rand() % 10000));
+                /* TODO:  unlikely, but this *could* alias! */
+            templateLin->setup_call (set_data, templateLin->set_data.random_data,
+                                     yes_fill_in_template, create_call_bool,
+                                     templateLin, rsrc   );
+        }
+    }
+}
+
+
+#line 409 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:339  */
+
+# ifndef YY_NULLPTR
+#  if defined __cplusplus && 201103L <= __cplusplus
+#   define YY_NULLPTR nullptr
+#  else
+#   define YY_NULLPTR 0
+#  endif
+# endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 1
+#endif
+
+/* In a future release of Bison, this section will be replaced
+   by #include "tf_fuzz_grammar.tab.hpp".  */
+#ifndef YY_YY_PARSER_TF_FUZZ_GRAMMAR_TAB_HPP_INCLUDED
+# define YY_YY_PARSER_TF_FUZZ_GRAMMAR_TAB_HPP_INCLUDED
+/* Debug traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
+
+/* Token type.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+  enum yytokentype
+  {
+    PURPOSE = 258,
+    RAW_TEXT = 259,
+    SET = 260,
+    READ = 261,
+    REMOVE = 262,
+    SECURE = 263,
+    DONE = 264,
+    SST = 265,
+    KEY = 266,
+    POLICY = 267,
+    NAME = 268,
+    UID = 269,
+    STAR = 270,
+    ACTIVE = 271,
+    DELETED = 272,
+    EQUAL = 273,
+    DATA = 274,
+    DFNAME = 275,
+    FLAG = 276,
+    NONE = 277,
+    WRITE_ONCE = 278,
+    NO_RP = 279,
+    NO_CONF = 280,
+    OFFSET = 281,
+    CHECK = 282,
+    VAR = 283,
+    HASH = 284,
+    NEQ = 285,
+    PRINT = 286,
+    EXPECT = 287,
+    PASS = 288,
+    FAIL = 289,
+    NOTHING = 290,
+    ERROR = 291,
+    IDENTIFIER_TOK = 292,
+    LITERAL_TOK = 293,
+    HEX_LIST = 294,
+    FILE_PATH_TOK = 295,
+    NUMBER_TOK = 296,
+    SEMICOLON = 297,
+    SHUFFLE = 298,
+    TO = 299,
+    OF = 300,
+    OPEN_BRACE = 301,
+    CLOSE_BRACE = 302,
+    ATTR = 303,
+    TYPE = 304,
+    ALG = 305,
+    EXPORT = 306,
+    COPY = 307,
+    ENCRYPT = 308,
+    DECRYPT = 309,
+    SIGN = 310,
+    VERIFY = 311,
+    DERIVE = 312,
+    NOEXPORT = 313,
+    NOCOPY = 314,
+    NOENCRYPT = 315,
+    NODECRYPT = 316,
+    NOSIGN = 317,
+    NOVERIFY = 318,
+    NODERIVE = 319,
+    PERSISTENT = 320,
+    VOLATILE = 321,
+    FROM = 322,
+    WITH = 323
+  };
+#endif
+
+/* Value type.  */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+
+union YYSTYPE
+{
+#line 353 "parser/tf_fuzz_grammar.y" /* yacc.c:355  */
+int valueN; int tokenN; char *str;
+
+#line 521 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:355  */
+};
+
+typedef union YYSTYPE YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+/* Location type.  */
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE YYLTYPE;
+struct YYLTYPE
+{
+  int first_line;
+  int first_column;
+  int last_line;
+  int last_column;
+};
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+extern YYSTYPE yylval;
+extern YYLTYPE yylloc;
+int yyparse (tf_fuzz_info *rsrc);
+
+#endif /* !YY_YY_PARSER_TF_FUZZ_GRAMMAR_TAB_HPP_INCLUDED  */
+
+/* Copy the second part of user declarations.  */
+
+#line 552 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:358  */
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#else
+typedef signed char yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+#  define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+#  define YYSIZE_T size_t
+# elif ! defined YYSIZE_T
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# else
+#  define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+#   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE
+# if (defined __GNUC__                                               \
+      && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)))  \
+     || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
+#  define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+# else
+#  define YY_ATTRIBUTE(Spec) /* empty */
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# define YY_ATTRIBUTE_PURE   YY_ATTRIBUTE ((__pure__))
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+#endif
+
+#if !defined _Noreturn \
+     && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
+# if defined _MSC_VER && 1200 <= _MSC_VER
+#  define _Noreturn __declspec (noreturn)
+# else
+#  define _Noreturn YY_ATTRIBUTE ((__noreturn__))
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E.  */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(E) ((void) (E))
+#else
+# define YYUSE(E) /* empty */
+#endif
+
+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized.  */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+    _Pragma ("GCC diagnostic push") \
+    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+    _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+    _Pragma ("GCC diagnostic pop")
+#else
+# define YY_INITIAL_VALUE(Value) Value
+#endif
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   elif defined __BUILTIN_VA_ARG_INCR
+#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+#   elif defined _AIX
+#    define YYSTACK_ALLOC __alloca
+#   elif defined _MSC_VER
+#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+#    define alloca _alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
+#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
+#     ifndef EXIT_SUCCESS
+#      define EXIT_SUCCESS 0
+#     endif
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's 'empty if-body' warning.  */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+    /* The OS might guarantee only one guard page at the bottom of the stack,
+       and a page size can be as small as 4096 bytes.  So we cannot safely
+       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
+       to allow for a few compiler-allocated temporary stack slots.  */
+#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+#  endif
+# else
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+#  endif
+#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
+       && ! ((defined YYMALLOC || defined malloc) \
+             && (defined YYFREE || defined free)))
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   ifndef EXIT_SUCCESS
+#    define EXIT_SUCCESS 0
+#   endif
+#  endif
+#  ifndef YYMALLOC
+#   define YYMALLOC malloc
+#   if ! defined malloc && ! defined EXIT_SUCCESS
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifndef YYFREE
+#   define YYFREE free
+#   if ! defined free && ! defined EXIT_SUCCESS
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+     && (! defined __cplusplus \
+         || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
+             && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  yytype_int16 yyss_alloc;
+  YYSTYPE yyvs_alloc;
+  YYLTYPE yyls_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+      + 2 * YYSTACK_GAP_MAXIMUM)
+
+# define YYCOPY_NEEDED 1
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \
+    do                                                                  \
+      {                                                                 \
+        YYSIZE_T yynewbytes;                                            \
+        YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
+        Stack = &yyptr->Stack_alloc;                                    \
+        yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+        yyptr += yynewbytes / sizeof (*yyptr);                          \
+      }                                                                 \
+    while (0)
+
+#endif
+
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(Dst, Src, Count) \
+      __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
+#  else
+#   define YYCOPY(Dst, Src, Count)              \
+      do                                        \
+        {                                       \
+          YYSIZE_T yyi;                         \
+          for (yyi = 0; yyi < (Count); yyi++)   \
+            (Dst)[yyi] = (Src)[yyi];            \
+        }                                       \
+      while (0)
+#  endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
+/* YYFINAL -- State number of the termination state.  */
+#define YYFINAL  34
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   159
+
+/* YYNTOKENS -- Number of terminals.  */
+#define YYNTOKENS  69
+/* YYNNTS -- Number of nonterminals.  */
+#define YYNNTS  82
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  155
+/* YYNSTATES -- Number of states.  */
+#define YYNSTATES  212
+
+/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
+   by yylex, with out-of-bounds checking.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   323
+
+#define YYTRANSLATE(YYX)                                                \
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+   as returned by yylex, without out-of-bounds checking.  */
+static const yytype_uint8 yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
+      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
+      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
+      65,    66,    67,    68
+};
+
+#if YYDEBUG
+  /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
+static const yytype_uint16 yyrline[] =
+{
+       0,   378,   378,   379,   390,   409,   451,   475,   501,   504,
+     507,   510,   513,   519,   524,   529,   534,   543,   555,   568,
+     583,   595,   607,   622,   634,   649,   679,   691,   701,   712,
+     713,   718,   726,   736,   737,   744,   745,   751,   751,   751,
+     751,   753,   760,   767,   775,   784,   793,   799,   807,   816,
+     826,   838,   851,   859,   860,   868,   868,   875,   883,   896,
+     904,   908,   914,   923,   924,   932,   944,   951,   959,   967,
+     974,   977,   978,   984,   990,   996,  1002,  1008,  1014,  1020,
+    1026,  1032,  1038,  1044,  1050,  1056,  1062,  1068,  1074,  1081,
+    1081,  1081,  1081,  1081,  1081,  1081,  1082,  1082,  1082,  1082,
+    1082,  1082,  1083,  1083,  1083,  1083,  1089,  1098,  1107,  1108,
+    1114,  1114,  1114,  1117,  1118,  1126,  1140,  1150,  1157,  1164,
+    1176,  1182,  1188,  1189,  1196,  1200,  1210,  1211,  1218,  1224,
+    1231,  1243,  1250,  1257,  1268,  1274,  1288,  1291,  1298,  1307,
+    1317,  1320,  1321,  1324,  1337,  1340,  1341,  1344,  1353,  1361,
+    1371,  1380,  1388,  1399,  1407,  1413
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || 1
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "PURPOSE", "RAW_TEXT", "SET", "READ",
+  "REMOVE", "SECURE", "DONE", "SST", "KEY", "POLICY", "NAME", "UID",
+  "STAR", "ACTIVE", "DELETED", "EQUAL", "DATA", "DFNAME", "FLAG", "NONE",
+  "WRITE_ONCE", "NO_RP", "NO_CONF", "OFFSET", "CHECK", "VAR", "HASH",
+  "NEQ", "PRINT", "EXPECT", "PASS", "FAIL", "NOTHING", "ERROR",
+  "IDENTIFIER_TOK", "LITERAL_TOK", "HEX_LIST", "FILE_PATH_TOK",
+  "NUMBER_TOK", "SEMICOLON", "SHUFFLE", "TO", "OF", "OPEN_BRACE",
+  "CLOSE_BRACE", "ATTR", "TYPE", "ALG", "EXPORT", "COPY", "ENCRYPT",
+  "DECRYPT", "SIGN", "VERIFY", "DERIVE", "NOEXPORT", "NOCOPY", "NOENCRYPT",
+  "NODECRYPT", "NOSIGN", "NOVERIFY", "NODERIVE", "PERSISTENT", "VOLATILE",
+  "FROM", "WITH", "$accept", "lines", "line", "command", "expect",
+  "set_command", "read_command", "remove_command", "secure_command",
+  "done_command", "literal_or_random_data", "sst_set_base_args",
+  "sst_set_extended_args", "sst_flags", "sst_flag", "none", "write_once",
+  "no_rp", "no_conf", "sst_offset_spec", "sst_read_args", "read_args",
+  "sst_read_extended_args", "sst_remove_args", "asset_designator",
+  "single_existing_asset", "random_picked_asset", "sst_asset_name",
+  "sst_asset_set_file_path", "read_args_var_name",
+  "sst_asset_dump_file_path", "key_size", "policy_usage_list",
+  "policy_usages", "export", "noexport", "copy", "nocopy", "encrypt",
+  "noencrypt", "decrypt", "nodecrypt", "sign", "nosign", "verify",
+  "noverify", "derive", "noderive", "persistent", "volatle",
+  "policy_usage", "policy_type", "policy_algorithm", "policy_specs",
+  "policy_spec", "policy_asset_spec", "policy_asset_name",
+  "policy_set_args", "policy_read_args", "key_set_sources",
+  "key_set_source", "key_data_or_not", "key_set_args", "key_remove_args",
+  "key_read_args", "block", "block_content", "open_brace", "close_brace",
+  "ASSET_NUMBER_LIST", "ASSET_NUMBERS", "ASSET_NUMBER",
+  "ASSET_IDENTIFIER_LIST", "ASSET_IDENTIFIERS", "ASSET_IDENTIFIER",
+  "IDENTIFIER", "FILE_PATH", "exact_sel_count", "low_sel_count",
+  "high_sel_count", "NUMBER", "LITERAL", YY_NULLPTR
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[NUM] -- (External) token number corresponding to the
+   (internal) symbol number NUM (which must be that of a token).  */
+static const yytype_uint16 yytoknum[] =
+{
+       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
+     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
+     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
+     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
+     295,   296,   297,   298,   299,   300,   301,   302,   303,   304,
+     305,   306,   307,   308,   309,   310,   311,   312,   313,   314,
+     315,   316,   317,   318,   319,   320,   321,   322,   323
+};
+# endif
+
+#define YYPACT_NINF -102
+
+#define yypact_value_is_default(Yystate) \
+  (!!((Yystate) == (-102)))
+
+#define YYTABLE_NINF -152
+
+#define yytable_value_is_error(Yytable_value) \
+  0
+
+  /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+     STATE-NUM.  */
+static const yytype_int16 yypact[] =
+{
+      35,  -102,    75,   104,    47,   -17,  -102,  -102,    20,    64,
+      35,   -23,  -102,  -102,  -102,  -102,  -102,  -102,    30,    39,
+      73,    37,    95,   112,    37,    95,     7,   106,    95,   103,
+    -102,  -102,  -102,    35,  -102,  -102,    72,  -102,    92,    20,
+      94,    32,    -2,   116,  -102,    -4,    -8,  -102,    33,    74,
+    -102,  -102,    53,    53,  -102,    99,    99,   113,    53,  -102,
+     115,  -102,  -102,  -102,  -102,  -102,   101,    93,  -102,  -102,
+    -102,  -102,  -102,  -102,  -102,    96,  -102,  -102,  -102,  -102,
+     101,  -102,  -102,  -102,    98,    88,  -102,    -7,   102,    99,
+    -102,    99,    34,    76,  -102,     2,    77,  -102,  -102,    38,
+      99,    99,  -102,  -102,  -102,  -102,    74,   102,    89,    99,
+    -102,  -102,   117,  -102,  -102,  -102,  -102,  -102,  -102,  -102,
+    -102,  -102,  -102,  -102,    20,  -102,   101,  -102,    98,  -102,
+    -102,  -102,  -102,  -102,    88,  -102,  -102,  -102,  -102,  -102,
+    -102,  -102,  -102,  -102,  -102,  -102,  -102,  -102,   134,  -102,
+    -102,  -102,  -102,    74,  -102,  -102,  -102,  -102,  -102,  -102,
+    -102,  -102,  -102,  -102,  -102,  -102,  -102,  -102,  -102,  -102,
+    -102,  -102,  -102,  -102,  -102,  -102,  -102,  -102,  -102,  -102,
+    -102,  -102,  -102,  -102,  -102,  -102,  -102,  -102,    38,  -102,
+    -102,  -102,  -102,  -102,  -102,  -102,  -102,  -102,   107,  -102,
+    -102,  -102,  -102,  -102,    99,  -102,  -102,    38,  -102,  -102,
+    -102,  -102
+};
+
+  /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+     Performed when YYTABLE does not specify something else to do.  Zero
+     means the default is an error.  */
+static const yytype_uint8 yydefact[] =
+{
+       2,     4,     0,     0,     0,     0,    26,   153,     0,     0,
+       2,     0,     8,    10,     9,    11,    12,     5,     0,     0,
+     150,     0,     0,   113,     0,     0,     0,     0,     0,     0,
+     138,   137,   133,     2,     1,     3,     0,     6,     0,     0,
+       0,     0,     0,    33,    63,    30,   122,    18,     0,   108,
+      19,    20,     0,     0,    21,     0,     0,     0,     0,    22,
+       0,    23,    56,    55,   131,    24,     0,     0,    13,    14,
+      15,   148,    16,     7,   134,     0,   152,    58,   147,    57,
+     145,    65,   143,    64,   141,    35,    17,     0,     0,     0,
+      29,     0,     0,   124,   128,   122,     0,   115,   114,     0,
+       0,     0,   110,   111,   112,   120,   108,     0,     0,     0,
+      51,    50,    53,   132,   119,   116,   117,   118,   121,    61,
+      62,    25,   139,   136,     0,   144,   145,   140,   141,    41,
+      42,    43,    44,    34,    35,    37,    38,    39,    40,    28,
+     154,   155,    27,   149,    32,    66,    31,   125,     0,    60,
+      59,   124,   123,   108,    69,    73,    75,    77,    79,    81,
+      83,    85,    74,    76,    78,    80,    82,    84,    86,    87,
+      88,   105,    89,    96,    90,    97,    91,    98,    92,    99,
+      93,   100,    94,   101,    95,   102,   103,   104,    71,   106,
+     107,   109,    52,    68,    48,    67,    49,    47,     0,    46,
+     135,   146,   142,    36,     0,   130,    70,    71,    45,    54,
+     129,    72
+};
+
+  /* YYPGOTO[NTERM-NUM].  */
+static const yytype_int8 yypgoto[] =
+{
+    -102,    -3,    -6,  -102,  -102,  -102,  -102,  -102,  -102,  -102,
+     -40,  -102,  -102,    13,  -102,  -102,  -102,  -102,  -102,  -102,
+    -102,    14,  -102,  -102,    40,  -102,    58,    50,  -102,  -102,
+    -102,  -102,  -102,   -56,  -102,  -102,  -102,  -102,  -102,  -102,
+    -102,  -102,  -102,  -102,  -102,  -102,  -102,  -102,  -102,  -102,
+      54,  -102,  -102,  -101,  -102,  -102,  -102,  -102,  -102,    57,
+    -102,  -102,  -102,  -102,  -102,  -102,   -36,  -102,  -102,  -102,
+      26,   114,   -31,    29,   -70,   -55,    51,  -102,  -102,  -102,
+     119,    49
+};
+
+  /* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int16 yydefgoto[] =
+{
+      -1,     9,    10,    11,    38,    12,    13,    14,    15,    16,
+      90,    43,    86,   133,   134,   135,   136,   137,   138,   209,
+      51,   112,   199,    61,    44,   148,    62,    45,   144,   194,
+     192,   171,   102,   206,   172,   173,   174,   175,   176,   177,
+     178,   179,   180,   181,   182,   183,   184,   185,   186,   187,
+     207,   103,   104,   105,   106,    49,    58,    50,    59,    94,
+      95,    96,    47,    65,    54,    17,    32,    33,   123,    83,
+     127,   128,    79,   125,    80,    72,   145,    18,    19,    75,
+      20,   142
+};
+
+  /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
+     positive, shift that token.  If negative, reduce the rule whose
+     number is the opposite.  If YYTABLE_NINF, syntax error.  */
+static const yytype_int16 yytable[] =
+{
+     114,   115,    31,    74,    91,   191,    93,    35,   139,    36,
+     126,    87,    29,    81,    91,    87,    88,    98,    55,    37,
+      56,    87,    57,     1,    89,     2,     3,     4,     5,     6,
+      67,   140,   141,    31,   146,   121,   147,   150,     1,    82,
+       2,     3,     4,     5,     6,   189,   190,    77,    97,    60,
+      41,    42,   205,   195,   197,   151,   126,    27,    28,    92,
+    -126,     7,    46,     8,    34,    53,    30,   113,    64,    78,
+      78,    71,   118,   107,    52,    39,     7,    63,     8,   154,
+     108,   109,   110,    40,   111,    21,    22,    23,   200,   155,
+     156,   157,   158,   159,   160,   161,   162,   163,   164,   165,
+     166,   167,   168,   169,   170,    68,    69,    70,    41,    71,
+     129,   130,   131,   132,    24,    25,    26,  -151,    31,    41,
+      42,    60,    99,   100,   101,    48,    71,   140,   141,   116,
+     117,   119,   120,    66,    73,     7,    71,    85,    78,    82,
+     122,   124,   143,   198,  -127,   153,   204,   203,   208,   210,
+     149,   211,   152,   188,   202,   201,    84,   196,   193,    76
+};
+
+static const yytype_uint8 yycheck[] =
+{
+      55,    56,     8,    39,    12,   106,    46,    10,    15,    32,
+      80,    19,    29,    15,    12,    19,    20,    48,    11,    42,
+      13,    19,    15,     3,    28,     5,     6,     7,     8,     9,
+      33,    38,    39,    39,    89,    66,    91,    92,     3,    41,
+       5,     6,     7,     8,     9,   100,   101,    15,    15,    15,
+      13,    14,   153,   108,   109,    95,   126,    10,    11,    67,
+      68,    41,    22,    43,     0,    25,    46,    53,    28,    37,
+      37,    37,    58,    20,    24,    45,    41,    27,    43,    41,
+      27,    28,    29,    44,    31,    10,    11,    12,   124,    51,
+      52,    53,    54,    55,    56,    57,    58,    59,    60,    61,
+      62,    63,    64,    65,    66,    33,    34,    35,    13,    37,
+      22,    23,    24,    25,    10,    11,    12,    44,   124,    13,
+      14,    15,    48,    49,    50,    13,    37,    38,    39,    16,
+      17,    16,    17,    30,    42,    41,    37,    21,    37,    41,
+      47,    45,    40,    26,    68,    68,    12,   134,    41,   204,
+      92,   207,    95,    99,   128,   126,    42,   108,   107,    40
+};
+
+  /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+     symbol of state STATE-NUM.  */
+static const yytype_uint8 yystos[] =
+{
+       0,     3,     5,     6,     7,     8,     9,    41,    43,    70,
+      71,    72,    74,    75,    76,    77,    78,   134,   146,   147,
+     149,    10,    11,    12,    10,    11,    12,    10,    11,    29,
+      46,    71,   135,   136,     0,    70,    32,    42,    73,    45,
+      44,    13,    14,    80,    93,    96,    93,   131,    13,   124,
+     126,    89,    96,    93,   133,    11,    13,    15,   125,   127,
+      15,    92,    95,    96,    93,   132,    30,    70,    33,    34,
+      35,    37,   144,    42,   135,   148,   149,    15,    37,   141,
+     143,    15,    41,   138,   140,    21,    81,    19,    20,    28,
+      79,    12,    67,    79,   128,   129,   130,    15,   141,    48,
+      49,    50,   101,   120,   121,   122,   123,    20,    27,    28,
+      29,    31,    90,    90,   144,   144,    16,    17,    90,    16,
+      17,   141,    47,   137,    45,   142,   143,   139,   140,    22,
+      23,    24,    25,    82,    83,    84,    85,    86,    87,    15,
+      38,    39,   150,    40,    97,   145,   144,   144,    94,    95,
+     144,    79,   128,    68,    41,    51,    52,    53,    54,    55,
+      56,    57,    58,    59,    60,    61,    62,    63,    64,    65,
+      66,   100,   103,   104,   105,   106,   107,   108,   109,   110,
+     111,   112,   113,   114,   115,   116,   117,   118,   119,   144,
+     144,   122,    99,   145,    98,   144,   150,   144,    26,    91,
+     135,   142,   139,    82,    12,   122,   102,   119,    41,    88,
+     144,   102
+};
+
+  /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint8 yyr1[] =
+{
+       0,    69,    70,    70,    71,    71,    71,    71,    72,    72,
+      72,    72,    72,    73,    73,    73,    73,    74,    74,    74,
+      75,    75,    75,    76,    76,    77,    78,    79,    79,    80,
+      80,    80,    80,    81,    81,    82,    82,    83,    83,    83,
+      83,    84,    85,    86,    87,    88,    89,    90,    90,    90,
+      90,    90,    90,    91,    91,    92,    92,    93,    93,    94,
+      94,    95,    95,    96,    96,    96,    97,    98,    99,   100,
+     101,   102,   102,   103,   104,   105,   106,   107,   108,   109,
+     110,   111,   112,   113,   114,   115,   116,   117,   118,   119,
+     119,   119,   119,   119,   119,   119,   119,   119,   119,   119,
+     119,   119,   119,   119,   119,   119,   120,   121,   122,   122,
+     123,   123,   123,   124,   124,   124,   125,   125,   125,   125,
+     126,   127,   128,   128,   129,   129,   130,   130,   131,   131,
+     131,   132,   133,   134,   134,   134,   135,   135,   136,   137,
+     138,   139,   139,   140,   141,   142,   142,   143,   144,   145,
+     146,   147,   148,   149,   150,   150
+};
+
+  /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
+static const yytype_uint8 yyr2[] =
+{
+       0,     2,     0,     2,     1,     1,     2,     3,     1,     1,
+       1,     1,     1,     2,     2,     2,     2,     4,     3,     3,
+       3,     3,     3,     3,     3,     4,     1,     2,     2,     2,
+       1,     3,     3,     0,     2,     0,     2,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     3,     2,     2,     2,
+       1,     1,     2,     0,     2,     1,     1,     2,     2,     1,
+       1,     2,     2,     1,     2,     2,     1,     1,     1,     1,
+       3,     0,     2,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     2,     2,     0,     2,
+       1,     1,     1,     0,     2,     2,     2,     2,     2,     2,
+       2,     2,     0,     2,     1,     2,     0,     1,     2,     5,
+       4,     1,     2,     2,     3,     5,     3,     1,     1,     1,
+       2,     0,     2,     1,     2,     0,     2,     1,     1,     1,
+       1,     1,     1,     1,     1,     1
+};
+
+
+#define yyerrok         (yyerrstatus = 0)
+#define yyclearin       (yychar = YYEMPTY)
+#define YYEMPTY         (-2)
+#define YYEOF           0
+
+#define YYACCEPT        goto yyacceptlab
+#define YYABORT         goto yyabortlab
+#define YYERROR         goto yyerrorlab
+
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)                                  \
+do                                                              \
+  if (yychar == YYEMPTY)                                        \
+    {                                                           \
+      yychar = (Token);                                         \
+      yylval = (Value);                                         \
+      YYPOPSTACK (yylen);                                       \
+      yystate = *yyssp;                                         \
+      goto yybackup;                                            \
+    }                                                           \
+  else                                                          \
+    {                                                           \
+      yyerror (rsrc, YY_("syntax error: cannot back up")); \
+      YYERROR;                                                  \
+    }                                                           \
+while (0)
+
+/* Error token number */
+#define YYTERROR        1
+#define YYERRCODE       256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)                                \
+    do                                                                  \
+      if (N)                                                            \
+        {                                                               \
+          (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
+          (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
+          (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
+          (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
+        }                                                               \
+      else                                                              \
+        {                                                               \
+          (Current).first_line   = (Current).last_line   =              \
+            YYRHSLOC (Rhs, 0).last_line;                                \
+          (Current).first_column = (Current).last_column =              \
+            YYRHSLOC (Rhs, 0).last_column;                              \
+        }                                                               \
+    while (0)
+#endif
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)                        \
+do {                                            \
+  if (yydebug)                                  \
+    YYFPRINTF Args;                             \
+} while (0)
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
+#ifndef YY_LOCATION_PRINT
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+
+/* Print *YYLOCP on YYO.  Private, do not rely on its existence. */
+
+YY_ATTRIBUTE_UNUSED
+static unsigned
+yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp)
+{
+  unsigned res = 0;
+  int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0;
+  if (0 <= yylocp->first_line)
+    {
+      res += YYFPRINTF (yyo, "%d", yylocp->first_line);
+      if (0 <= yylocp->first_column)
+        res += YYFPRINTF (yyo, ".%d", yylocp->first_column);
+    }
+  if (0 <= yylocp->last_line)
+    {
+      if (yylocp->first_line < yylocp->last_line)
+        {
+          res += YYFPRINTF (yyo, "-%d", yylocp->last_line);
+          if (0 <= end_col)
+            res += YYFPRINTF (yyo, ".%d", end_col);
+        }
+      else if (0 <= end_col && yylocp->first_column < end_col)
+        res += YYFPRINTF (yyo, "-%d", end_col);
+    }
+  return res;
+ }
+
+#  define YY_LOCATION_PRINT(File, Loc)          \
+  yy_location_print_ (File, &(Loc))
+
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                    \
+do {                                                                      \
+  if (yydebug)                                                            \
+    {                                                                     \
+      YYFPRINTF (stderr, "%s ", Title);                                   \
+      yy_symbol_print (stderr,                                            \
+                  Type, Value, Location, rsrc); \
+      YYFPRINTF (stderr, "\n");                                           \
+    }                                                                     \
+} while (0)
+
+
+/*----------------------------------------.
+| Print this symbol's value on YYOUTPUT.  |
+`----------------------------------------*/
+
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, tf_fuzz_info *rsrc)
+{
+  FILE *yyo = yyoutput;
+  YYUSE (yyo);
+  YYUSE (yylocationp);
+  YYUSE (rsrc);
+  if (!yyvaluep)
+    return;
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+  YYUSE (yytype);
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, tf_fuzz_info *rsrc)
+{
+  YYFPRINTF (yyoutput, "%s %s (",
+             yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
+
+  YY_LOCATION_PRINT (yyoutput, *yylocationp);
+  YYFPRINTF (yyoutput, ": ");
+  yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, rsrc);
+  YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (; yybottom <= yytop; yybottom++)
+    {
+      int yybot = *yybottom;
+      YYFPRINTF (stderr, " %d", yybot);
+    }
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)                            \
+do {                                                            \
+  if (yydebug)                                                  \
+    yy_stack_print ((Bottom), (Top));                           \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+static void
+yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, tf_fuzz_info *rsrc)
+{
+  unsigned long int yylno = yyrline[yyrule];
+  int yynrhs = yyr2[yyrule];
+  int yyi;
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+             yyrule - 1, yylno);
+  /* The symbols being reduced.  */
+  for (yyi = 0; yyi < yynrhs; yyi++)
+    {
+      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
+      yy_symbol_print (stderr,
+                       yystos[yyssp[yyi + 1 - yynrhs]],
+                       &(yyvsp[(yyi + 1) - (yynrhs)])
+                       , &(yylsp[(yyi + 1) - (yynrhs)])                       , rsrc);
+      YYFPRINTF (stderr, "\n");
+    }
+}
+
+# define YY_REDUCE_PRINT(Rule)          \
+do {                                    \
+  if (yydebug)                          \
+    yy_reduce_print (yyssp, yyvsp, yylsp, Rule, rsrc); \
+} while (0)
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined __GLIBC__ && defined _STRING_H
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+static YYSIZE_T
+yystrlen (const char *yystr)
+{
+  YYSIZE_T yylen;
+  for (yylen = 0; yystr[yylen]; yylen++)
+    continue;
+  return yylen;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+{
+  char *yyd = yydest;
+  const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+   quotes and backslashes, so that it's suitable for yyerror.  The
+   heuristic is that double-quoting is unnecessary unless the string
+   contains an apostrophe, a comma, or backslash (other than
+   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
+   null, do not copy; instead, return the length of what the result
+   would have been.  */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+  if (*yystr == '"')
+    {
+      YYSIZE_T yyn = 0;
+      char const *yyp = yystr;
+
+      for (;;)
+        switch (*++yyp)
+          {
+          case '\'':
+          case ',':
+            goto do_not_strip_quotes;
+
+          case '\\':
+            if (*++yyp != '\\')
+              goto do_not_strip_quotes;
+            /* Fall through.  */
+          default:
+            if (yyres)
+              yyres[yyn] = *yyp;
+            yyn++;
+            break;
+
+          case '"':
+            if (yyres)
+              yyres[yyn] = '\0';
+            return yyn;
+          }
+    do_not_strip_quotes: ;
+    }
+
+  if (! yyres)
+    return yystrlen (yystr);
+
+  return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+   about the unexpected token YYTOKEN for the state stack whose top is
+   YYSSP.
+
+   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
+   not large enough to hold the message.  In that case, also set
+   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
+   required number of bytes is too large to store.  */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+                yytype_int16 *yyssp, int yytoken)
+{
+  YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
+  YYSIZE_T yysize = yysize0;
+  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+  /* Internationalized format string. */
+  const char *yyformat = YY_NULLPTR;
+  /* Arguments of yyformat. */
+  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+  /* Number of reported tokens (one for the "unexpected", one per
+     "expected"). */
+  int yycount = 0;
+
+  /* There are many possibilities here to consider:
+     - If this state is a consistent state with a default action, then
+       the only way this function was invoked is if the default action
+       is an error action.  In that case, don't check for expected
+       tokens because there are none.
+     - The only way there can be no lookahead present (in yychar) is if
+       this state is a consistent state with a default action.  Thus,
+       detecting the absence of a lookahead is sufficient to determine
+       that there is no unexpected or expected token to report.  In that
+       case, just report a simple "syntax error".
+     - Don't assume there isn't a lookahead just because this state is a
+       consistent state with a default action.  There might have been a
+       previous inconsistent state, consistent state with a non-default
+       action, or user semantic action that manipulated yychar.
+     - Of course, the expected token list depends on states to have
+       correct lookahead information, and it depends on the parser not
+       to perform extra reductions after fetching a lookahead from the
+       scanner and before detecting a syntax error.  Thus, state merging
+       (from LALR or IELR) and default reductions corrupt the expected
+       token list.  However, the list is correct for canonical LR with
+       one exception: it will still contain any token that will not be
+       accepted due to an error action in a later state.
+  */
+  if (yytoken != YYEMPTY)
+    {
+      int yyn = yypact[*yyssp];
+      yyarg[yycount++] = yytname[yytoken];
+      if (!yypact_value_is_default (yyn))
+        {
+          /* Start YYX at -YYN if negative to avoid negative indexes in
+             YYCHECK.  In other words, skip the first -YYN actions for
+             this state because they are default actions.  */
+          int yyxbegin = yyn < 0 ? -yyn : 0;
+          /* Stay within bounds of both yycheck and yytname.  */
+          int yychecklim = YYLAST - yyn + 1;
+          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+          int yyx;
+
+          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+                && !yytable_value_is_error (yytable[yyx + yyn]))
+              {
+                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+                  {
+                    yycount = 1;
+                    yysize = yysize0;
+                    break;
+                  }
+                yyarg[yycount++] = yytname[yyx];
+                {
+                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
+                  if (! (yysize <= yysize1
+                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+                    return 2;
+                  yysize = yysize1;
+                }
+              }
+        }
+    }
+
+  switch (yycount)
+    {
+# define YYCASE_(N, S)                      \
+      case N:                               \
+        yyformat = S;                       \
+      break
+      YYCASE_(0, YY_("syntax error"));
+      YYCASE_(1, YY_("syntax error, unexpected %s"));
+      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+    }
+
+  {
+    YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+      return 2;
+    yysize = yysize1;
+  }
+
+  if (*yymsg_alloc < yysize)
+    {
+      *yymsg_alloc = 2 * yysize;
+      if (! (yysize <= *yymsg_alloc
+             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+      return 1;
+    }
+
+  /* Avoid sprintf, as that infringes on the user's name space.
+     Don't have undefined behavior even if the translation
+     produced a string with the wrong number of "%s"s.  */
+  {
+    char *yyp = *yymsg;
+    int yyi = 0;
+    while ((*yyp = *yyformat) != '\0')
+      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+        {
+          yyp += yytnamerr (yyp, yyarg[yyi++]);
+          yyformat += 2;
+        }
+      else
+        {
+          yyp++;
+          yyformat++;
+        }
+  }
+  return 0;
+}
+#endif /* YYERROR_VERBOSE */
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, tf_fuzz_info *rsrc)
+{
+  YYUSE (yyvaluep);
+  YYUSE (yylocationp);
+  YYUSE (rsrc);
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+  YYUSE (yytype);
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+
+
+
+/* The lookahead symbol.  */
+int yychar;
+
+/* The semantic value of the lookahead symbol.  */
+YYSTYPE yylval;
+/* Location data for the lookahead symbol.  */
+YYLTYPE yylloc
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+  = { 1, 1, 1, 1 }
+# endif
+;
+/* Number of syntax errors so far.  */
+int yynerrs;
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
+int
+yyparse (tf_fuzz_info *rsrc)
+{
+    int yystate;
+    /* Number of tokens to shift before error messages enabled.  */
+    int yyerrstatus;
+
+    /* The stacks and their tools:
+       'yyss': related to states.
+       'yyvs': related to semantic values.
+       'yyls': related to locations.
+
+       Refer to the stacks through separate pointers, to allow yyoverflow
+       to reallocate them elsewhere.  */
+
+    /* The state stack.  */
+    yytype_int16 yyssa[YYINITDEPTH];
+    yytype_int16 *yyss;
+    yytype_int16 *yyssp;
+
+    /* The semantic value stack.  */
+    YYSTYPE yyvsa[YYINITDEPTH];
+    YYSTYPE *yyvs;
+    YYSTYPE *yyvsp;
+
+    /* The location stack.  */
+    YYLTYPE yylsa[YYINITDEPTH];
+    YYLTYPE *yyls;
+    YYLTYPE *yylsp;
+
+    /* The locations where the error started and ended.  */
+    YYLTYPE yyerror_range[3];
+
+    YYSIZE_T yystacksize;
+
+  int yyn;
+  int yyresult;
+  /* Lookahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+  YYLTYPE yyloc;
+
+#if YYERROR_VERBOSE
+  /* Buffer for error messages, and its allocated size.  */
+  char yymsgbuf[128];
+  char *yymsg = yymsgbuf;
+  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
+
+  /* The number of symbols on the RHS of the reduced rule.
+     Keep to zero when no symbol should be popped.  */
+  int yylen = 0;
+
+  yyssp = yyss = yyssa;
+  yyvsp = yyvs = yyvsa;
+  yylsp = yyls = yylsa;
+  yystacksize = YYINITDEPTH;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY; /* Cause a token to be read.  */
+  yylsp[0] = yylloc;
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed.  So pushing a state here evens the stacks.  */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+        /* Give user a chance to reallocate the stack.  Use copies of
+           these so that the &'s don't force the real ones into
+           memory.  */
+        YYSTYPE *yyvs1 = yyvs;
+        yytype_int16 *yyss1 = yyss;
+        YYLTYPE *yyls1 = yyls;
+
+        /* Each stack pointer address is followed by the size of the
+           data in use in that stack, in bytes.  This used to be a
+           conditional around just the two extra args, but that might
+           be undefined if yyoverflow is a macro.  */
+        yyoverflow (YY_("memory exhausted"),
+                    &yyss1, yysize * sizeof (*yyssp),
+                    &yyvs1, yysize * sizeof (*yyvsp),
+                    &yyls1, yysize * sizeof (*yylsp),
+                    &yystacksize);
+
+        yyls = yyls1;
+        yyss = yyss1;
+        yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyexhaustedlab;
+# else
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH <= yystacksize)
+        goto yyexhaustedlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH < yystacksize)
+        yystacksize = YYMAXDEPTH;
+
+      {
+        yytype_int16 *yyss1 = yyss;
+        union yyalloc *yyptr =
+          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+        if (! yyptr)
+          goto yyexhaustedlab;
+        YYSTACK_RELOCATE (yyss_alloc, yyss);
+        YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+        YYSTACK_RELOCATE (yyls_alloc, yyls);
+#  undef YYSTACK_RELOCATE
+        if (yyss1 != yyssa)
+          YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+      yylsp = yyls + yysize - 1;
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+                  (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 <= yyssp)
+        YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  if (yystate == YYFINAL)
+    YYACCEPT;
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+  /* Do appropriate processing given the current state.  Read a
+     lookahead token if we need one and don't already have one.  */
+
+  /* First try to decide what to do without reference to lookahead token.  */
+  yyn = yypact[yystate];
+  if (yypact_value_is_default (yyn))
+    goto yydefault;
+
+  /* Not known => get a lookahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = yylex ();
+    }
+
+  if (yychar <= YYEOF)
+    {
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yytable_value_is_error (yyn))
+        goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  /* Shift the lookahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+  /* Discard the shifted token.  */
+  yychar = YYEMPTY;
+
+  yystate = yyn;
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+  *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
+  *++yylsp = yylloc;
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     '$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+  /* Default location.  */
+  YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 3:
+#line 379 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Lines:  Line number " << dec << yylineno << "." << endl;)
+            /* Re-randomize objects we parse into: */
+            expect = expect_info();
+            set_data = set_data_info();
+            parsed_asset = asset_name_id_info();
+            policy_info = key_policy_info();
+        }
+#line 1917 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 4:
+#line 390 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Purpose line:  " << flush;)
+            set_purp_str (yytext, rsrc);
+            IVM(cout << rsrc->test_purpose << endl;)
+            /* TODO:  Is there much/any value in turning this back on?  The
+                      constructor clear()s them out, and run-time errors observed
+                      under Visual Studio...
+               Just a precaution to make sure that these vectors start out empty.
+               Should inherently be, but purpose is typically specified first:
+            parsed_asset.asset_id_n_vector.clear();
+            parsed_asset.asset_name_vector.clear(); */
+            /* Re-randomize or re-initialize objects we parse into: */
+            purpose_defined = true;
+            expect = expect_info();
+            set_data = set_data_info();
+            parsed_asset = asset_name_id_info();
+            policy_info = key_policy_info();
+            target_barrier = "";
+        }
+#line 1941 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 5:
+#line 409 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            /* TODO:  This code may not won't work with "secure hash neq ..." */
+            IVM(cout << "Block of lines." << endl;)
+            /* "Statisticalize" :-) the vector of template lines, then crank
+               the selected lines in order here. */
+            randomize_template_lines (shuffle_not_pick,
+                low_nmbr_lines, high_nmbr_lines, exact_nmbr_lines,
+                template_block_vector, block_order, rsrc
+            );
+            /* Vector block_order contains the sequence of template lines to be
+               realized, in order.  Pop the indicated template line off the
+               vector and generate code from it: */
+            k = 0;  /* ID adder to at least help ensure uniqueness */
+            for (int i : block_order) {
+                templateLin = template_block_vector[i];
+                /* Note that temLin will have its fields filled in already. */
+                interpret_template_line (
+                    templateLin, rsrc, set_data, random_asset,
+                    assign_data_var_specified, expect, policy_info,
+                    print_data, hash_data, asset_name, assign_data_var, parsed_asset,
+                    yes_create_call,  /* did not create call nor asset earlier */
+                    yes_create_asset,
+                    dont_fill_in_template,  /* but did fill it all in before */
+                    0
+                );
+                k++;
+                for (add_expect = 0;  add_expect < rsrc->calls.size();  ++add_expect) {
+                    if (!(rsrc->calls[add_expect]->exp_data.expected_results_saved)) {
+                        templateLin->expect.copy_expect_to_call (rsrc->calls[add_expect]);
+                        templateLin->expect.expected_results_saved = true;
+                    }
+                }
+            }
+            templateLin->asset_info.asset_id_n_vector.clear();
+            templateLin->asset_info.asset_name_vector.clear();
+            /* Done.  Empty out the "statisticalization" vector: */
+            block_order.clear();
+            /* Empty out the vector of template lines; no longer needed. */
+            template_block_vector.clear();
+            --nesting_level;
+            IVM(cout << "Finished coding block of lines." << endl;)
+        }
+#line 1988 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 6:
+#line 451 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Command with no expect:  \"" << flush;)
+            if (!purpose_defined) {
+                cerr << endl << endl
+                     << "Error:  Please begin your test with the \"purpose\" "
+                     << "directive.  \n        For example, "
+                     << "\"purpose to exercise crypto and SST...\"" << endl;
+                exit (1024);
+            }
+            if (nesting_level == 0) {  /* if laying down the code now... */
+                for (add_expect = 0;  add_expect < rsrc->calls.size();  ++add_expect) {
+                    if (!(rsrc->calls[add_expect]->exp_data.expected_results_saved)) {
+                        templateLin->expect.copy_expect_to_call (rsrc->calls[add_expect]);
+                        templateLin->expect.expected_results_saved = true;
+                    }
+                }
+                delete templateLin;  /* done with this template line */
+            } else {
+                /* The template line is now fully decoded, so stuff it onto
+                   vector of lines to be "statisticalized": */
+                template_block_vector.push_back (templateLin);
+            }
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2017 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 7:
+#line 475 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            /* (This is the same as for command SEMICOLON, other than the IVM.) */
+            IVM(cout << "Command with expect:  \"" << flush;)
+            if (!purpose_defined) {
+                cerr << endl << endl
+                     << "Error:  Please begin your test with the \"purpose\" "
+                     << "directive.  \n        For example, "
+                     << "\"purpose to exercise crypto and SST...\"" << endl;
+                exit (1024);
+            }
+            if (nesting_level == 0) {
+                for (add_expect = 0;  add_expect < rsrc->calls.size();  ++add_expect) {
+                    if (!(rsrc->calls[add_expect]->exp_data.expected_results_saved)) {
+                        templateLin->expect.copy_expect_to_call (rsrc->calls[add_expect]);
+                        templateLin->expect.expected_results_saved = true;
+                    }
+                }
+                delete templateLin;
+            } else {
+                template_block_vector.push_back (templateLin);
+            }
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2045 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 8:
+#line 501 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Set command:  \"" << yytext << "\"" << endl;)
+        }
+#line 2053 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 9:
+#line 504 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Remove command:  \"" << yytext << "\"" << endl;)
+        }
+#line 2061 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 10:
+#line 507 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Read command:  \"" << yytext << "\"" << endl;)
+        }
+#line 2069 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 11:
+#line 510 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Security command:  \"" << yytext << "\"" << endl;)
+        }
+#line 2077 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 12:
+#line 513 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Done command:  \"" << yytext << "\"" << endl;)
+        }
+#line 2085 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 13:
+#line 519 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Expect pass clause:  \"" << flush;)
+            templateLin->expect.set_pf_pass();
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2095 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 14:
+#line 524 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Expect fail clause:  \"" << flush;)
+            templateLin->expect.set_pf_fail();
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2105 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 15:
+#line 529 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Expect nothing clause:  \"" << flush;)
+            templateLin->expect.set_pf_nothing();
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2115 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 16:
+#line 534 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Expect error clause:  \"" << flush;)
+            templateLin->expect.set_pf_error (identifier);
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2125 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 17:
+#line 543 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Set SST command:  \"" << yytext << "\"" << endl;)
+            templateLin = new set_sst_template_line (rsrc);
+            interpret_template_line (
+                templateLin, rsrc, set_data, random_asset,
+                assign_data_var_specified, expect, policy_info,
+                print_data, hash_data, asset_name, assign_data_var, parsed_asset,
+                nesting_level == 0 /* create call unless inside {} */,
+                nesting_level == 0 /* similarly, create asset unless inside {} */,
+                yes_fill_in_template, 0
+            );
+        }
+#line 2142 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 18:
+#line 555 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Set key command:  \"" << yytext << "\"" << endl;)
+            templateLin = new set_key_template_line (rsrc);
+            target_barrier = policy_info.asset_2_name;  /* policy */
+            interpret_template_line (
+                templateLin, rsrc, set_data, random_asset,
+                assign_data_var_specified, expect, policy_info,
+                print_data, hash_data, asset_name, assign_data_var, parsed_asset,
+                nesting_level == 0 /* create call unless inside {} */,
+                nesting_level == 0 /* similarly, create asset unless inside {} */,
+                yes_fill_in_template, 0
+            );
+        }
+#line 2160 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 19:
+#line 568 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Set policy command:  \"" << yytext << "\"" << endl;;)
+            templateLin = new set_policy_template_line (rsrc);
+            interpret_template_line (
+                templateLin, rsrc, set_data, random_asset,
+                assign_data_var_specified, expect, policy_info,
+                print_data, hash_data, asset_name, assign_data_var, parsed_asset,
+                nesting_level == 0 /* create call unless inside {} */,
+                nesting_level == 0 /* similarly, create asset unless inside {} */,
+                yes_fill_in_template, 0
+            );
+        }
+#line 2177 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 20:
+#line 583 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Read SST command:  \"" << yytext << "\"" << endl;;)
+            templateLin = new read_sst_template_line (rsrc);
+            interpret_template_line (
+                templateLin, rsrc, set_data, random_asset,
+                assign_data_var_specified, expect, policy_info,
+                print_data, hash_data, asset_name, assign_data_var, parsed_asset,
+                nesting_level == 0 /* create call unless inside {} */,
+                dont_create_asset /* if no such asset exists, fail the call */,
+                yes_fill_in_template, 0
+            );
+        }
+#line 2194 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 21:
+#line 595 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Read key command:  \"" << yytext << "\"" << endl;;)
+            templateLin = new read_key_template_line (rsrc);
+            interpret_template_line (
+                templateLin, rsrc, set_data, random_asset,
+                assign_data_var_specified, expect, policy_info,
+                print_data, hash_data, asset_name, assign_data_var, parsed_asset,
+                nesting_level == 0 /* create call unless inside {} */,
+                dont_create_asset /* if no such asset exists, fail the call */,
+                yes_fill_in_template, 0
+            );
+        }
+#line 2211 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 22:
+#line 607 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Read policy command:  \"" << yytext << "\"" << endl;;)
+            templateLin = new read_policy_template_line (rsrc);
+            interpret_template_line (
+                templateLin, rsrc, set_data, random_asset,
+                assign_data_var_specified, expect, policy_info,
+                print_data, hash_data, asset_name, assign_data_var, parsed_asset,
+                nesting_level == 0 /* create call unless inside {} */,
+                dont_create_asset /* if no such asset exists, fail the call */,
+                yes_fill_in_template, 0
+            );
+        }
+#line 2228 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 23:
+#line 622 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Remove SST command:  \"" << yytext << "\"" << endl;;)
+            templateLin = new remove_sst_template_line (rsrc);
+            interpret_template_line (
+                templateLin, rsrc, set_data, random_asset,
+                assign_data_var_specified, expect, policy_info,
+                print_data, hash_data, asset_name, assign_data_var, parsed_asset,
+                nesting_level == 0 /* create call unless inside {} */,
+                dont_create_asset /* don't create an asset being deleted */,
+                yes_fill_in_template, 0
+            );
+        }
+#line 2245 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 24:
+#line 634 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Remove key command:  \"" << yytext << "\"" << endl;;)
+            templateLin = new remove_key_template_line (rsrc);
+            templateLin->asset_info.set_name (asset_name);  // set in key_asset_name, below
+            interpret_template_line (
+                templateLin, rsrc, set_data, random_asset,
+                assign_data_var_specified, expect, policy_info,
+                print_data, hash_data, asset_name, assign_data_var, parsed_asset,
+                nesting_level == 0 /* create call unless inside {} */,
+                dont_create_asset /* don't create an asset being deleted */,
+                yes_fill_in_template, 0
+            );
+        }
+#line 2263 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 25:
+#line 649 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+  /* TODO:  This needs to allow not only SST assets, but mix and match with others
+             (keys especially) as well. */
+            IVM(cout << "Secure hash command:  \"" << yytext << "\"" << endl;)
+            templateLin = new security_hash_template_line (rsrc);
+            templateLin->asset_info.set_name (asset_name);
+            templateLin->assign_data_var_specified = assign_data_var_specified;
+            templateLin->assign_data_var.assign (assign_data_var);
+            templateLin->expect = expect;
+            templateLin->print_data = print_data;
+            templateLin->hash_data = hash_data;
+            templateLin->random_asset = random_asset;
+            /* Hash checks are different from the rest in that there's a single
+               "call" -- not a PSA call though -- for all of the assets cited in the
+               template line.  In *other* cases, create a single call for *each*
+               asset cited by the template line, but not in this case. */
+            for (auto as_name : parsed_asset.asset_name_vector) {
+                /* Also copy into template line object's local vector: */
+                 templateLin->asset_info.asset_name_vector.push_back (as_name);
+            }
+            /* Don't need to locate the assets, so no searches required. */
+            templateLin->expect.data_var = var_name;
+            templateLin->setup_call (set_data, set_data.random_data, yes_fill_in_template,
+                                     nesting_level == 0, templateLin, rsrc   );
+            parsed_asset.asset_name_vector.clear();
+
+
+        }
+#line 2296 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 26:
+#line 679 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            if (nesting_level != 0) {
+                cerr << "\n\"done\" only available at outer-most { } nesting level."
+                     << endl;
+                exit (702);
+            } else {
+                YYACCEPT;
+            }
+        }
+#line 2310 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 27:
+#line 691 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Create from literal data:  \"" << flush;)
+            set_data.random_data = false;
+            set_data.string_specified = true;
+            set_data.literal_data_not_file = true;
+            literal.erase(0,1);  // zap the ""s
+            literal.erase(literal.length()-1,1);
+            literal_data.assign (literal);
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2325 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 28:
+#line 701 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {  /* TF-Fuzz supplies random data */
+            IVM(cout << "Create from random data" << endl;)
+            set_data.randomize();
+            literal.assign (set_data.get());  /* just in case something uses literal */
+            set_data.random_data = true;
+            set_data.string_specified = false;
+        }
+#line 2337 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 30:
+#line 713 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "SST-create from random data (no 'data *')" << endl;)
+            set_data.randomize();
+            literal.assign (set_data.get());  /* just in case something uses literal */
+        }
+#line 2347 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 31:
+#line 718 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {  /* set from variable */
+            IVM(cout << "SST-set set from variable:  \"" << flush;)
+            assign_data_var.assign (identifier);
+            assign_data_var_specified = true;
+            expect.data_specified = false;
+            expect.data_var_specified = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2360 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 32:
+#line 726 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            set_data.literal_data_not_file = set_data.random_data = false;
+            IVM(cout << "SST-create from file:  " << yytext << "\"" << endl;)
+            /* TODO:  Need to decide whether the concept of using files to set SST
+                       asset values has meaning, and if so, write code to write code to
+                       set data appropriately from the file. */
+        }
+#line 2372 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 34:
+#line 737 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "SST creation flags" << endl;)
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2381 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 36:
+#line 745 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "SST creation flag" << endl;)
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2390 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 41:
+#line 753 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            set_data.flags_string = "PSA_STORAGE_FLAG_NONE";
+                /* TODO:  grab from boilerplate */
+            IVM(cout << "SST no storage flag:  " << yytext << "\"" << endl;)
+        }
+#line 2400 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 42:
+#line 760 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            set_data.flags_string = "PSA_STORAGE_FLAG_WRITE_ONCE";
+                /* TODO:  grab from boilerplate */
+            IVM(cout << "SST write-once flag:  " << yytext << "\"" << endl;)
+        }
+#line 2410 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 43:
+#line 767 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            set_data.flags_string = "PSA_STORAGE_FLAG_NO_REPLAY_PROTECTION";
+                /* TODO:  grab from boilerplate */
+            IVM(cout << "SST no-replay-protection flag:  "
+                     << yytext << "\"" << endl;)
+        }
+#line 2421 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 44:
+#line 775 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            set_data.flags_string = "PSA_STORAGE_FLAG_NO_CONFIDENTIALITY";
+                /* TODO:  grab from boilerplate */
+            IVM(cout << "SST no-confidentiality flag:  " << yytext
+                     << "\"" << endl;)
+        }
+#line 2432 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 45:
+#line 784 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "SST-data offset:  \"" << flush;)
+            set_data.data_offset = atol(yytext);
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2442 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 46:
+#line 793 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "SST-read arguments:  " << yytext << "\"" << endl;)
+        }
+#line 2450 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 47:
+#line 799 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {  /* dump to variable */
+            IVM(cout << "Read dump to variable:  \"" << flush;)
+            assign_data_var.assign (identifier);
+            assign_data_var_specified = true;
+            expect.data_specified = false;
+            expect.data_var_specified = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2463 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 48:
+#line 807 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {  /* check against variable */
+            IVM(cout << "Read check against variable:  \""
+                     << yytext << "\"" << endl;)
+            set_data.set (literal);
+            assign_data_var_specified = false;
+            expect.data_specified = false;
+            expect.data_var_specified = true;
+            expect.data_var = identifier;
+        }
+#line 2477 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 49:
+#line 816 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {  /* check against literal */
+            IVM(cout << "Read check against literal:  " << flush;)
+            expect.data.assign (literal);
+            expect.data.erase(0,1);    // zap the ""s
+            expect.data.erase(expect.data.length()-1,1);
+            assign_data_var_specified = false;  /* don't read variable */
+            expect.data_specified = true;  /* check against literal data */
+            expect.data_var_specified = false;  /* don't check against variable */
+            IVM(cout << yytext << endl;)
+        }
+#line 2492 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 50:
+#line 826 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {  /* print out content in test log */
+            IVM(cout << "Read log to test log:  \"" << flush;)
+            /* TODO:  set_data content probably doesn't need to be set here;
+                       constructor probably sets it fine. */
+            set_data.random_data = false;
+            set_data.literal_data_not_file = true;
+            assign_data_var_specified = false;
+            expect.data_specified = false;
+            expect.data_var_specified = false;
+            print_data = true;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2509 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 51:
+#line 838 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {  /* hash the data and save for later comparison */
+            IVM(cout << "Read hash for future data-leak detection:  \"" << flush;)
+            /* TODO:  set_data content probably doesn't need to be set here;
+                       constructor probably sets it fine. */
+            set_data.random_data = false;
+            set_data.literal_data_not_file = true;
+            assign_data_var_specified = false;
+            expect.data_specified = false;
+            expect.data_var_specified = false;
+            hash_data = true;
+            rsrc->include_hashing_code = true;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2527 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 52:
+#line 851 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {  /* dump to file */
+            IVM(cout << "Read dump to file:  \""
+                     << yytext << "\"" << endl;)
+            set_data.literal_data_not_file = set_data.random_data = false;
+        }
+#line 2537 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 54:
+#line 860 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "SST data offset" << endl;)
+            set_data.data_offset = atol(yytext);
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2547 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 56:
+#line 868 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "SST-remove arguments:  \""
+                     << yytext << "\"" << endl;)
+        }
+#line 2556 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 57:
+#line 875 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Asset identifier list:  \"" << flush;)
+            random_name = false;
+            asset_name.assign (identifier);  /* TODO:  Not sure this ultimately has any effect... */
+            random_asset = psa_asset_usage::all;  /* don't randomly choose existing asset */
+            parsed_asset.id_n_not_name = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2569 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 58:
+#line 883 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Asset random identifier:  \"" << flush;)
+            random_name = true;
+            rand_data_length = 4 + (rand() % 5);
+            gib.word (false, gib_buff, gib_buff + rand_data_length - 1);
+            aid.assign (gib_buff);
+            parsed_asset.asset_name_vector.push_back (aid);
+            random_asset = psa_asset_usage::all;  /* don't randomly choose existing asset */
+            parsed_asset.id_n_not_name = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2585 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 59:
+#line 896 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Single existing asset by name:  \"" << flush;)
+            random_name = false;
+            policy_info.asset_3_name.assign (identifier);
+            random_asset = psa_asset_usage::all;  /* don't randomly choose existing asset */
+            parsed_asset.id_n_not_name = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2598 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 61:
+#line 908 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Asset random active:  \"" << flush;)
+            random_asset = psa_asset_usage::active;
+            parsed_asset.id_n_not_name = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2609 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 62:
+#line 914 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Asset random deleted:  \"" << flush;)
+            random_asset = psa_asset_usage::deleted;
+            parsed_asset.id_n_not_name = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2620 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 64:
+#line 924 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "SST-asset UID list:  \"" << flush;)
+            random_name = false;
+            random_asset = psa_asset_usage::all;  /* don't randomly choose existing asset */
+            parsed_asset.id_n_not_name = true;
+            parsed_asset.id_n_specified = true;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2633 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 65:
+#line 932 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "SST-asset random UID:  \"" << flush;)
+            parsed_asset.id_n_not_name = true;
+            random_name = false;
+            nid = 100 + (rand() % 10000);
+            parsed_asset.asset_id_n_vector.push_back (nid);
+            random_asset = psa_asset_usage::all;  /* don't randomly choose existing asset */
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2647 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 66:
+#line 944 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "SST-asset-create file path:  \"" << flush;)
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2656 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 67:
+#line 951 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Read-arguments variable name:  \"" << flush;)
+            var_name = yytext;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2666 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 68:
+#line 959 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "SST-asset dump-file path:  \"" << flush;)
+            set_data.file_path = yytext;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2676 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 69:
+#line 967 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Key size:  \"" << flush;)
+            policy_info.n_bits = atol(yytext);
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2686 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 72:
+#line 978 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Key-policy usages at line number " << dec << yylineno
+                     << "." << endl;)
+        }
+#line 2695 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 73:
+#line 984 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            policy_info.exportable = true;
+            IVM(cout << "Exportable key true:  " << yytext << "\"" << endl;)
+        }
+#line 2704 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 74:
+#line 990 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            policy_info.exportable = false;
+            IVM(cout << "Non-exportable key:  " << yytext << "\"" << endl;)
+        }
+#line 2713 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 75:
+#line 996 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            policy_info.copyable = true;
+            IVM(cout << "Copyable key true:  " << yytext << "\"" << endl;)
+        }
+#line 2722 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 76:
+#line 1002 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            policy_info.copyable = false;
+            IVM(cout << "Non-copyable key:  " << yytext << "\"" << endl;)
+        }
+#line 2731 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 77:
+#line 1008 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            policy_info.can_encrypt = true;
+            IVM(cout << "Encryption key true:  " << yytext << "\"" << endl;)
+        }
+#line 2740 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 78:
+#line 1014 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            policy_info.can_encrypt = false;
+            IVM(cout << "Non-encryption key:  " << yytext << "\"" << endl;)
+        }
+#line 2749 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 79:
+#line 1020 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            policy_info.can_decrypt = true;
+            IVM(cout << "Decryption key true:  " << yytext << "\"" << endl;)
+        }
+#line 2758 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 80:
+#line 1026 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            policy_info.can_decrypt = false;
+            IVM(cout << "Non-decryption key:  " << yytext << "\"" << endl;)
+        }
+#line 2767 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 81:
+#line 1032 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            policy_info.can_sign = true;
+            IVM(cout << "Signing key true:  " << yytext << "\"" << endl;)
+        }
+#line 2776 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 82:
+#line 1038 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            policy_info.can_sign = false;
+            IVM(cout << "Non-signing key:  " << yytext << "\"" << endl;)
+        }
+#line 2785 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 83:
+#line 1044 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            policy_info.can_verify = true;
+            IVM(cout << "Verify key true:  " << yytext << "\"" << endl;)
+        }
+#line 2794 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 84:
+#line 1050 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            policy_info.can_verify = false;
+            IVM(cout << "Non-verify key:  " << yytext << "\"" << endl;)
+        }
+#line 2803 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 85:
+#line 1056 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            policy_info.derivable = true;
+            IVM(cout << "Derivable key true:  " << yytext << "\"" << endl;)
+        }
+#line 2812 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 86:
+#line 1062 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            policy_info.derivable = false;
+            IVM(cout << "Non-derivable key:  " << yytext << "\"" << endl;)
+        }
+#line 2821 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 87:
+#line 1068 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            policy_info.persistent = true;
+            IVM(cout << "Persistent key:  " << yytext << "\"" << endl;)
+        }
+#line 2830 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 88:
+#line 1074 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            policy_info.persistent = false;
+            IVM(cout << "Volatile key:  " << yytext << "\"" << endl;)
+        }
+#line 2839 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 105:
+#line 1083 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Policy usage:  " << yytext << "\"" << endl;)
+        }
+#line 2847 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 106:
+#line 1089 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            // Change type identifier, e.g., from "raw_data" to PSA_KEY_TYPE_RAW_DATA:
+            identifier = formalize (identifier, "PSA_KEY_TYPE_");
+            policy_info.key_type = identifier;
+            IVM(cout << "Policy type:  \""
+                     << policy_info.key_type << "\"" << endl;)
+      }
+#line 2859 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 107:
+#line 1098 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            // Change type identifier, e.g., from "sha_256" to PSA_ALG_SHA_256:
+            identifier = formalize (identifier, "PSA_ALG_");
+            policy_info.key_algorithm = identifier;
+            IVM(cout << "Policy algorithm:  \""
+                     << policy_info.key_algorithm << "\"" << endl;)
+      }
+#line 2871 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 109:
+#line 1108 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Key-policy specs at line number " << dec << yylineno
+                     << "." << endl;)
+        }
+#line 2880 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 114:
+#line 1118 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "policy-asset identifier list:  \"" << flush;)
+            random_name = false;
+            asset_name.assign (identifier);  /* TODO:  Not sure this ultimately has any effect... */
+            random_asset = psa_asset_usage::all;  /* don't randomly choose existing asset */
+            parsed_asset.id_n_not_name = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2893 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 115:
+#line 1126 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "policy-asset random identifier:  \"" << flush;)
+            random_name = true;
+            rand_data_length = 2 + (rand() % 10);
+            gib.word (false, gib_buff, gib_buff + rand_data_length - 1);
+            aid.assign (gib_buff);
+            parsed_asset.asset_name_vector.push_back (aid);
+            random_asset = psa_asset_usage::all;  /* don't randomly choose existing asset */
+            parsed_asset.id_n_not_name = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2909 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 116:
+#line 1140 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "policy-asset identifier list:  \"" << flush;)
+            random_name = false;
+            policy_info.get_policy_from_key = false;
+            asset_name.assign (identifier);  /* TODO:  Not sure this ultimately has any effect... */
+            parsed_asset.asset_name_vector.push_back (identifier);
+            random_asset = psa_asset_usage::all;  /* don't randomly choose existing asset */
+            parsed_asset.id_n_not_name = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2924 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 117:
+#line 1150 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "policy-asset random active:  \"" << flush;)
+            policy_info.get_policy_from_key = false;
+            random_asset = psa_asset_usage::active;
+            parsed_asset.id_n_not_name = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2936 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 118:
+#line 1157 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "policy-asset random deleted:  \"" << flush;)
+            policy_info.get_policy_from_key = false;
+            random_asset = psa_asset_usage::deleted;
+            parsed_asset.id_n_not_name = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2948 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 119:
+#line 1164 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "policy-asset specified by key:  \"" << flush;)
+            policy_info.get_policy_from_key = true;
+            random_name = false;
+            asset_name.assign (identifier);  /* ask this key what it's policy is */
+            random_asset = psa_asset_usage::all;  /* don't randomly choose existing asset */
+            parsed_asset.id_n_not_name = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 2962 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 120:
+#line 1176 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Policy-create arguments:  \"" << yytext << "\"" << endl;)
+        }
+#line 2970 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 121:
+#line 1182 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Policy-read arguments:  " << yytext << "\"" << endl;)
+        }
+#line 2978 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 123:
+#line 1189 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Key-set sources at Line number "
+                     << yytext << "\"" << endl;)
+        }
+#line 2987 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 124:
+#line 1196 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Key-set sources, literal or random data:  "
+                     << yytext << "\"" << endl;)
+        }
+#line 2996 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 125:
+#line 1200 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Key-set sources, explicitly-specified policy name:  "
+                     << flush;)
+            policy_info.asset_2_name = identifier;  /* policy */
+            /* Make note that key data (key material) was not specified: */
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 3008 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 127:
+#line 1211 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Key data, literal or random data:  "
+                     << yytext << "\"" << endl;)
+        }
+#line 3017 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 128:
+#line 1218 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Key-create from data, policy, or nothing (default):  \""
+                     << yytext << "\"" << endl;)
+            policy_info.copy_key = false;
+            policy_info.implicit_policy = false;
+        }
+#line 3028 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 129:
+#line 1224 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Key-copy from other key:  \"" << flush;)
+            policy_info.asset_2_name = identifier;  /* policy */
+            policy_info.copy_key = true;
+            policy_info.implicit_policy = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 3040 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 130:
+#line 1231 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Key-create directly specifying policy attributes (implicit policy):  \""
+                     << yytext << "\"" << endl;)
+            policy_info.copy_key = false;
+            policy_info.implicit_policy = true;
+            cerr << "\nError:  Defining keys with implicit policies is not yet implemented."
+                 << endl;
+            exit (772);
+        }
+#line 3054 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 131:
+#line 1243 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Key-remove arguments:  \""
+                     << yytext << "\"" << endl;)
+        }
+#line 3063 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 132:
+#line 1250 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Key dump:  \"" << yytext << "\"" << endl;)
+        }
+#line 3071 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 133:
+#line 1257 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Shuffled block:  \"" << flush;)
+            if (nesting_level > 1) {
+                cerr << "\nError:  Sorry, currently only one level of { } "
+                     << "nesting is allowed." << endl;
+                exit (500);
+            }
+            shuffle_not_pick = true;
+            low_nmbr_lines = high_nmbr_lines = 0;  /* not used, but... */
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 3087 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 134:
+#line 1268 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Fixed number of lines from block:  \"" << flush;)
+            shuffle_not_pick = false;
+            /* low_nmbr_lines and high_nmbr_lines are set below. */
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 3098 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 135:
+#line 1274 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Range number of lines from block:  \"" << flush;)
+            if (nesting_level > 1) {
+                cerr << "\nError:  Sorry, currently only one level of { } "
+                     << "nesting is allowed." << endl;
+                exit (502);
+            }
+            shuffle_not_pick = false;
+            /* low_nmbr_lines and high_nmbr_lines are set below. */
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 3114 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 136:
+#line 1288 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Block content:  \"" << yytext << "\"" << endl;)
+        }
+#line 3122 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 137:
+#line 1291 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Single-line would-be-block content:  \"" << flush;)
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 3131 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 138:
+#line 1298 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Open brace:  \"" << flush;)
+            template_block_vector.clear();  // clean slate of template lines
+            nesting_level = 1;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 3142 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 139:
+#line 1307 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Close brace:  " << flush;)
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 3151 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 143:
+#line 1324 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "ASSET_NUMBER:  \"" << flush;)
+            nid = atol(yytext);
+            parsed_asset.asset_id_n_vector.push_back (nid);
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 3162 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 147:
+#line 1344 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "ASSET_IDENTIFIER:  \"" << flush;)
+            aid = identifier = yytext;
+            parsed_asset.asset_name_vector.push_back (aid);
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 3173 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 148:
+#line 1353 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "IDENTIFIER:  \"" << flush;)
+            identifier = yytext;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 3183 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 149:
+#line 1361 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "FILE_PATH:  \"" << flush;)
+            set_data.file_path = yytext;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 3193 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 150:
+#line 1371 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Exact number of random template lines:  \"" << flush;)
+            low_nmbr_lines = high_nmbr_lines = exact_nmbr_lines = number;
+            ++nesting_level;
+            IVM(cout << number << "\"" << endl;)
+        }
+#line 3204 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 151:
+#line 1380 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Least number of random template lines:  \"" << flush;)
+            low_nmbr_lines = number;
+            IVM(cout << number << "\"" << endl;)
+        }
+#line 3214 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 152:
+#line 1388 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "Most number of random template lines:  \"" << flush;)
+            high_nmbr_lines = number;
+            ++nesting_level;
+            IVM(cout << number << "\"" << endl;)
+        }
+#line 3225 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 153:
+#line 1399 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+            IVM(cout << "NUMBER:  \"" << flush;)
+            number = atol(yytext);
+            IVM(cout << yytext << "\"" << endl;)
+        }
+#line 3235 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 154:
+#line 1407 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+          IVM(cout << "LITERAL string:  " << flush;)
+          literal = yytext;
+          literal_is_string = true;
+          IVM(cout << yytext << endl;)
+        }
+#line 3246 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+  case 155:
+#line 1413 "parser/tf_fuzz_grammar.y" /* yacc.c:1646  */
+    {
+          IVM(cout << "LITERAL hex-value list:  " << flush;)
+          literal = yytext;
+          literal_is_string = false;
+          IVM(cout << yytext << endl;)
+        }
+#line 3257 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+    break;
+
+
+#line 3261 "parser/tf_fuzz_grammar.tab.cpp" /* yacc.c:1646  */
+      default: break;
+    }
+  /* User semantic actions sometimes alter yychar, and that requires
+     that yytoken be updated with the new translation.  We take the
+     approach of translating immediately before every use of yytoken.
+     One alternative is translating here after every semantic action,
+     but that translation would be missed if the semantic action invokes
+     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
+     incorrect destructor might then be invoked immediately.  In the
+     case of YYERROR or YYBACKUP, subsequent parser actions might lead
+     to an incorrect destructor call or verbose syntax error message
+     before the lookahead is translated.  */
+  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+  *++yylsp = yyloc;
+
+  /* Now 'shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*--------------------------------------.
+| yyerrlab -- here on detecting error.  |
+`--------------------------------------*/
+yyerrlab:
+  /* Make sure we have latest lookahead translation.  See comments at
+     user semantic actions for why this is necessary.  */
+  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if ! YYERROR_VERBOSE
+      yyerror (rsrc, YY_("syntax error"));
+#else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+                                        yyssp, yytoken)
+      {
+        char const *yymsgp = YY_("syntax error");
+        int yysyntax_error_status;
+        yysyntax_error_status = YYSYNTAX_ERROR;
+        if (yysyntax_error_status == 0)
+          yymsgp = yymsg;
+        else if (yysyntax_error_status == 1)
+          {
+            if (yymsg != yymsgbuf)
+              YYSTACK_FREE (yymsg);
+            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+            if (!yymsg)
+              {
+                yymsg = yymsgbuf;
+                yymsg_alloc = sizeof yymsgbuf;
+                yysyntax_error_status = 2;
+              }
+            else
+              {
+                yysyntax_error_status = YYSYNTAX_ERROR;
+                yymsgp = yymsg;
+              }
+          }
+        yyerror (rsrc, yymsgp);
+        if (yysyntax_error_status == 2)
+          goto yyexhaustedlab;
+      }
+# undef YYSYNTAX_ERROR
+#endif
+    }
+
+  yyerror_range[1] = yylloc;
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse lookahead token after an
+         error, discard it.  */
+
+      if (yychar <= YYEOF)
+        {
+          /* Return failure if at end of input.  */
+          if (yychar == YYEOF)
+            YYABORT;
+        }
+      else
+        {
+          yydestruct ("Error: discarding",
+                      yytoken, &yylval, &yylloc, rsrc);
+          yychar = YYEMPTY;
+        }
+    }
+
+  /* Else will try to reuse lookahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
+
+  /* Pacify compilers like GCC when the user code never invokes
+     YYERROR and the label yyerrorlab therefore never appears in user
+     code.  */
+  if (/*CONSTCOND*/ 0)
+     goto yyerrorlab;
+
+  yyerror_range[1] = yylsp[1-yylen];
+  /* Do not reclaim the symbols of the rule whose action triggered
+     this YYERROR.  */
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+  yystate = *yyssp;
+  goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;      /* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (!yypact_value_is_default (yyn))
+        {
+          yyn += YYTERROR;
+          if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+            {
+              yyn = yytable[yyn];
+              if (0 < yyn)
+                break;
+            }
+        }
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+        YYABORT;
+
+      yyerror_range[1] = *yylsp;
+      yydestruct ("Error: popping",
+                  yystos[yystate], yyvsp, yylsp, rsrc);
+      YYPOPSTACK (1);
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+  *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+  yyerror_range[2] = yylloc;
+  /* Using YYLLOC is tempting, but would change the location of
+     the lookahead.  YYLOC is available though.  */
+  YYLLOC_DEFAULT (yyloc, yyerror_range, 2);
+  *++yylsp = yyloc;
+
+  /* Shift the error token.  */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#if !defined yyoverflow || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here.  |
+`-------------------------------------------------*/
+yyexhaustedlab:
+  yyerror (rsrc, YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEMPTY)
+    {
+      /* Make sure we have latest lookahead translation.  See comments at
+         user semantic actions for why this is necessary.  */
+      yytoken = YYTRANSLATE (yychar);
+      yydestruct ("Cleanup: discarding lookahead",
+                  yytoken, &yylval, &yylloc, rsrc);
+    }
+  /* Do not reclaim the symbols of the rule whose action triggered
+     this YYABORT or YYACCEPT.  */
+  YYPOPSTACK (yylen);
+  YY_STACK_PRINT (yyss, yyssp);
+  while (yyssp != yyss)
+    {
+      yydestruct ("Cleanup: popping",
+                  yystos[*yyssp], yyvsp, yylsp, rsrc);
+      YYPOPSTACK (1);
+    }
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+  if (yymsg != yymsgbuf)
+    YYSTACK_FREE (yymsg);
+#endif
+  return yyresult;
+}
+#line 1422 "parser/tf_fuzz_grammar.y" /* yacc.c:1906  */
+
+
diff --git a/tf_fuzz/parser/tf_fuzz_grammar.tab.hpp b/tf_fuzz/parser/tf_fuzz_grammar.tab.hpp
new file mode 100644
index 0000000..a9a9488
--- /dev/null
+++ b/tf_fuzz/parser/tf_fuzz_grammar.tab.hpp
@@ -0,0 +1,152 @@
+/* A Bison parser, made by GNU Bison 3.0.4.  */
+
+/* Bison interface for Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+#ifndef YY_YY_PARSER_TF_FUZZ_GRAMMAR_TAB_HPP_INCLUDED
+# define YY_YY_PARSER_TF_FUZZ_GRAMMAR_TAB_HPP_INCLUDED
+/* Debug traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
+
+/* Token type.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+  enum yytokentype
+  {
+    PURPOSE = 258,
+    RAW_TEXT = 259,
+    SET = 260,
+    READ = 261,
+    REMOVE = 262,
+    SECURE = 263,
+    DONE = 264,
+    SST = 265,
+    KEY = 266,
+    POLICY = 267,
+    NAME = 268,
+    UID = 269,
+    STAR = 270,
+    ACTIVE = 271,
+    DELETED = 272,
+    EQUAL = 273,
+    DATA = 274,
+    DFNAME = 275,
+    FLAG = 276,
+    NONE = 277,
+    WRITE_ONCE = 278,
+    NO_RP = 279,
+    NO_CONF = 280,
+    OFFSET = 281,
+    CHECK = 282,
+    VAR = 283,
+    HASH = 284,
+    NEQ = 285,
+    PRINT = 286,
+    EXPECT = 287,
+    PASS = 288,
+    FAIL = 289,
+    NOTHING = 290,
+    ERROR = 291,
+    IDENTIFIER_TOK = 292,
+    LITERAL_TOK = 293,
+    HEX_LIST = 294,
+    FILE_PATH_TOK = 295,
+    NUMBER_TOK = 296,
+    SEMICOLON = 297,
+    SHUFFLE = 298,
+    TO = 299,
+    OF = 300,
+    OPEN_BRACE = 301,
+    CLOSE_BRACE = 302,
+    ATTR = 303,
+    TYPE = 304,
+    ALG = 305,
+    EXPORT = 306,
+    COPY = 307,
+    ENCRYPT = 308,
+    DECRYPT = 309,
+    SIGN = 310,
+    VERIFY = 311,
+    DERIVE = 312,
+    NOEXPORT = 313,
+    NOCOPY = 314,
+    NOENCRYPT = 315,
+    NODECRYPT = 316,
+    NOSIGN = 317,
+    NOVERIFY = 318,
+    NODERIVE = 319,
+    PERSISTENT = 320,
+    VOLATILE = 321,
+    FROM = 322,
+    WITH = 323
+  };
+#endif
+
+/* Value type.  */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+
+union YYSTYPE
+{
+#line 353 "parser/tf_fuzz_grammar.y" /* yacc.c:1909  */
+int valueN; int tokenN; char *str;
+
+#line 126 "parser/tf_fuzz_grammar.tab.hpp" /* yacc.c:1909  */
+};
+
+typedef union YYSTYPE YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+/* Location type.  */
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE YYLTYPE;
+struct YYLTYPE
+{
+  int first_line;
+  int first_column;
+  int last_line;
+  int last_column;
+};
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+extern YYSTYPE yylval;
+extern YYLTYPE yylloc;
+int yyparse (tf_fuzz_info *rsrc);
+
+#endif /* !YY_YY_PARSER_TF_FUZZ_GRAMMAR_TAB_HPP_INCLUDED  */
diff --git a/tf_fuzz/parser/tf_fuzz_grammar.tab.o b/tf_fuzz/parser/tf_fuzz_grammar.tab.o
new file mode 100644
index 0000000..5954ef6
--- /dev/null
+++ b/tf_fuzz/parser/tf_fuzz_grammar.tab.o
Binary files differ
diff --git a/tf_fuzz/parser/tf_fuzz_grammar.y b/tf_fuzz/parser/tf_fuzz_grammar.y
new file mode 100644
index 0000000..17c31b4
--- /dev/null
+++ b/tf_fuzz/parser/tf_fuzz_grammar.y
@@ -0,0 +1,1423 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+%{
+#include <iostream>
+#include <vector>
+#include <set>
+
+#include "class_forwards.hpp"
+#include "data_blocks.hpp"
+#include "boilerplate.hpp"
+#include "gibberish.hpp"
+#include "compute.hpp"
+#include "string_ops.hpp"
+#include "psa_asset.hpp"
+#include "find_or_create_asset.hpp"
+#include "template_line.hpp"
+#include "tf_fuzz.hpp"
+#include "sst_asset.hpp"
+#include "crypto_asset.hpp"
+#include "psa_call.hpp"
+#include "crypto_call.hpp"
+#include "sst_call.hpp"
+#include "security_call.hpp"
+#include "secure_template_line.hpp"
+#include "sst_template_line.hpp"
+#include "crypto_template_line.hpp"
+
+/* These items are defined in tf_fuzz_grammar.l.  Note, however that, because
+   of "name mangling," defining them as extern "C" may or may not be ideal,
+   depending upon which compiler -- gcc vs. g++, compiles the output from lex.
+   So far, it seems best without the extern "C", including also compiling
+   under Visual Studio. */
+/* extern "C"
+{ */
+  extern int yylineno;
+  int yywrap() {return 1;}
+  extern char yytext[];
+  extern int yyleng;
+/* } */
+
+int yylex (void);
+void yyerror (tf_fuzz_info *, const char *);
+    /* Sends the yyparse() argument to yyerror(), probably, to print incorrect
+       text it parsed. */
+
+/* A few consts just to make code more comprehensible: */
+const bool yes_fill_in_template = true;
+const bool dont_fill_in_template = false;
+const bool yes_create_call = true;
+const bool dont_create_call = false;
+
+tf_fuzz_info *rsrc;
+
+/* These are object pointers used to parse the template and create the test.  Ac-
+   tually, probably only templateLin is used for now, but this is a good outline of
+   of the template_line class hierarchy. */
+template_line                   *templateLin = nullptr;
+  sst_template_line             *sstTemplateLin = nullptr;
+    set_sst_template_line       *setSstTemplateLin = nullptr;
+    read_sst_template_line      *reaSstTemplateLin = nullptr;
+    remove_sst_template_line    *remSstTemplateLin = nullptr;
+  policy_template_line          *polTemplateLin = nullptr;
+    set_policy_template_line    *setPolTemplateLin = nullptr;
+    read_policy_template_line   *reaPolTemplateLin = nullptr;
+  key_template_line             *keyTemplateLin = nullptr;
+    set_key_template_line       *setKeyTemplateLin = nullptr;
+    read_key_template_line      *reaKeyTemplateLin = nullptr;
+    remove_key_template_line    *remKeyTemplateLin = nullptr;
+  security_template_line        *secTemplateLin = nullptr;
+    security_hash_template_line *secHasTemplateLin = nullptr;
+/* Call and asset objects are presumably not immediately needed, because the objects
+   of these types are within the resource object, *rsrc, but even if only just to
+   show that class hierarchy: */
+psa_call                        *psaCal = nullptr;
+  sst_call                      *sstCal = nullptr;
+    sst_set_call                *sstSetCal = nullptr;
+    sst_get_call                *sstGetCal = nullptr;
+    sst_remove_call             *sstRemCal = nullptr;
+  crypto_call                   *cryCal = nullptr;
+    policy_call                 *polCal = nullptr;
+      init_policy_call          *iniPolCal = nullptr;
+      reset_policy_call         *resPolCal = nullptr;
+      add_policy_usage_call     *addPolUsaCal = nullptr;
+      set_policy_lifetime_call  *setPolLifCal = nullptr;
+      set_policy_type_call      *setPolTypCal = nullptr;
+      set_policy_algorithm_call *setPolAlgCal = nullptr;
+      set_policy_usage_call     *setPolUsaCal = nullptr;
+      get_policy_lifetime_call  *getPolLifCal = nullptr;
+      get_policy_type_call      *getPolTypCal = nullptr;
+      get_policy_algorithm_call *getPolAlgCal = nullptr;
+      get_policy_usage_call     *getPolUsaCal = nullptr;
+      get_policy_size_call      *getPolSizCal = nullptr;
+      get_key_policy_call       *getKeyPolCal = nullptr;
+    key_call                    *keyCal = nullptr;
+      generate_key_call         *genKeyCal = nullptr;
+      create_key_call           *creKeyCal = nullptr;
+      copy_key_call             *copKeyCal = nullptr;
+      read_key_data_call        *reaKeyDatCal = nullptr;
+      remove_key_call           *remKeyCal = nullptr;
+psa_asset                       *psaAst = nullptr;
+  sst_asset                     *sstAst = nullptr;
+  crypto_asset                  *cryAst = nullptr;
+    policy_asset                *polAst = nullptr;
+    key_asset                   *keyAst = nullptr;
+
+/* For generating random, but readable/memorable, data: */
+gibberish gib;
+char gib_buff[4096];  // spew gibberish into here
+int rand_data_length = 0;
+
+/* General-utility variables: */
+bool purpose_defined = false;
+psa_asset_usage random_asset = psa_asset_usage::all;
+    /* to pick what type of asset at random */
+bool random_name;  /* template didn't specify name, so it's generated randomly */
+string literal_data;  /* literal data for an asset value */
+
+/* Holders for state in read commands: */
+expect_info expect;  /* everything about expected results and data */
+set_data_info set_data;  /* everything about setting the value of PSA-asset data */
+asset_name_id_info parsed_asset;  /* everything about identifying assets */
+string target_barrier = "";  /* asset to set and search barrier when re-ordering PSA calls */
+key_policy_info policy_info;  /* everything about key policies */
+bool assign_data_var_specified = false;
+string assign_data_var;
+bool print_data = false;  /* true to just print asset data to the test log */
+bool hash_data = false;  /* true to just print asset data to the test log */
+bool literal_is_string = true;
+    /* if true, literal value is character-string;  if false, is list of hex values */
+
+/* The following are more tied to the template syntax than to the resulting PSA calls */
+string literal;  /* temporary holder for all string literals */
+string identifier;  /* temporary holder for strings representing identifiers */
+string var_name;  /* a variable name */
+string asset_name;  /* as parsed, not yet put into parsed_asset */
+string aid;  /* string-typed holder for an asset ID in a list thereof */
+int nid;  /* same idea as aid, but for asset ID# lists */
+size_t strFind1, strFind2;  /* for searching through strings */
+
+/* Because of the parsing order, psa_calls of the specific type have to be
+   push_back()ed onto rsrc->calls before their expected results are known.  Therefore,
+   must inject those results after parsing the expected results.  add_expect is a
+   loop index to track where to add results. */
+unsigned int add_expect = 0;
+
+/* Temporaries: */
+vector<psa_asset*>::iterator t_sst_asset;
+vector<psa_asset*>::iterator t_key_asset;
+vector<psa_asset*>::iterator t_policy_asset;
+sst_call *t_sst_call = nullptr;
+key_call *t_key_call = nullptr;
+policy_call *t_policy_call = nullptr;
+long number;  /* temporary holder for a number, e.g., sting form of UID */
+int i, j, k;
+
+/* Relating to template-statement blocks: */
+vector<template_line*> template_block_vector;  /* (must be *pointers to* templates) */
+vector<int> block_order;  /* "statisticalized" order of template lines in a block */
+int nesting_level = 0;
+    /* how many levels deep in { } nesting currently.  Initially only 0 or 1. */
+bool shuffle_not_pick;
+    /* true to shuffle statements in a block, rather than pick so-and-so
+       number of them at random. */
+int low_nmbr_lines = 1;  /* if picking so-and-so number of template lines from a ... */
+int high_nmbr_lines = 1; /*    ... block at random, these are fewest and most lines. */
+int exact_nmbr_lines = 1;
+
+using namespace std;
+
+
+void set_purp_str (
+    char *raw_purpose,  /* the purpose C string from parser */
+    tf_fuzz_info *rsrc  /* test resources containing the actual test-purpose string */
+) {
+    size_t l;  /* temporary of size_t type */
+    string purp_str = raw_purpose;
+    strFind1 = purp_str.find (" ");
+    purp_str = purp_str.substr (strFind1, purp_str.length());
+    purp_str.erase (0, 1);  // (extra space)
+    strFind1 = purp_str.rfind (";");
+    purp_str = purp_str.substr (0, strFind1);
+    l = 0;
+    do {  /* escape all " chars (if not already escaped) */
+        l = purp_str.find ("\"", l);
+        if (   l < purp_str.length()) {  /* did find a quote character */
+            if (   l == 0  /* it's the first character in the string*/
+                || purp_str[l-1] != '\\' /* or it's not already escaped */
+               ) {
+                purp_str.insert (l, "\\");  /* then escape the " char */
+                l++;  /* point l to the " again */
+            }
+            l++;  /* point l past the " */
+        }
+    } while (l < purp_str.length());
+    rsrc->test_purpose = purp_str;
+}
+
+/* randomize_template_lines() chooses a template-line order in cases where they are to
+   be randomized -- shuffled or random picked. */
+void randomize_template_lines (
+    bool shuffle_not_pick,  /* true to perform a shuffle operation rather than pick */
+    int &low_nmbr_lines, /* if picking so-and-so number of template lines from a ... */
+    int &high_nmbr_lines, /*    ... block at random, these are fewest and most lines. */
+    int &exact_nmbr_lines,
+    vector<template_line*> &template_block_vector,
+    vector<int> &block_order,
+    tf_fuzz_info *rsrc  /* test resources containing the actual test-purpose string */
+) {
+    set<int> template_used;  /* used for shuffle */
+    low_nmbr_lines = (low_nmbr_lines < 0)?  0 : low_nmbr_lines;
+    high_nmbr_lines = (high_nmbr_lines < 0)?  0 : high_nmbr_lines;
+    if (low_nmbr_lines > high_nmbr_lines) {
+        int swap = low_nmbr_lines;
+        low_nmbr_lines = high_nmbr_lines;
+        high_nmbr_lines = swap;
+    }
+    template_used.clear();
+    if (shuffle_not_pick) {
+        /* Choose a random order in which to generate all of the
+           template lines in the block: */
+        while (template_used.size() < template_block_vector.size()) {
+            i = rand() % template_block_vector.size();
+            if (template_used.find (i) == template_used.end()) {
+                /* This template not already shuffled in. */
+                block_order.push_back (i);
+                template_used.insert (i);
+            }
+        }
+        /* Done shuffling;  empty out the set: */
+    } else {
+        if (high_nmbr_lines == low_nmbr_lines) {
+            exact_nmbr_lines = low_nmbr_lines;
+                /* just in case the template says "3 to 3 of"... */
+        } else {
+            exact_nmbr_lines =   low_nmbr_lines
+                               + (rand() % (  high_nmbr_lines
+                                            - low_nmbr_lines + 1  )  );
+        }
+        for (int j = 0;  j < exact_nmbr_lines;  ++j) {
+            /* Repeatedly choose a random template line from the block: */
+            i = rand() % template_block_vector.size();
+            block_order.push_back (i);
+        }
+    }
+    IVM(cout << "Order of lines in block:  " << flush;
+        for (auto i : block_order) {
+            cout << i << "  ";
+        }
+        cout << endl;
+    )
+}
+
+/* interpret_template_line() fills in random data, locates PSA assets, (etc.) and
+   conditionally creates PSA calls for a given template line.  Note that there needs
+   to be a single place where all of this is done, so that statement blocks can be
+   randomized and then dispatched from a single point. */
+void interpret_template_line (
+    template_line *templateLin,  /* the template line to process */
+    tf_fuzz_info *rsrc,  /* program resources in general */
+    set_data_info &set_data, psa_asset_usage random_asset,
+    bool assign_data_var_specified, expect_info &expect, key_policy_info &policy_info,
+    bool print_data, bool hash_data, string asset_name, string assign_data_var,
+    asset_name_id_info &asset_info,  /* everything about the asset(s) involved */
+    bool create_call_bool,  /* true to create the PSA call at this time */
+    bool create_asset_bool,  /* true to create the PSA asset at this time */
+    bool fill_in_template,  /* true to back-fill info into template */
+    int instance
+        /* if further differentiation to the names or IDs is needed, make instance >0 */
+) {
+    const bool yes_fill_in_template = true;  /* just to improve readability */
+    vector<psa_asset*>::iterator t_psa_asset;
+
+    if (fill_in_template) {
+        /* Set basic parameters from the template line: */
+        templateLin->set_data = set_data;
+        templateLin->expect = expect;
+        templateLin->policy_info = policy_info;
+        templateLin->asset_info.id_n_not_name = asset_info.id_n_not_name;
+        templateLin->asset_info.set_name (asset_name);
+        /* Fill in state parsed from the template below: */
+        templateLin->assign_data_var_specified = assign_data_var_specified;
+        templateLin->assign_data_var.assign (assign_data_var);
+        templateLin->print_data = print_data;
+        templateLin->hash_data = hash_data;
+        templateLin->random_asset = random_asset;
+        if (   set_data.literal_data_not_file && !set_data.random_data
+            && set_data.string_specified) {
+            templateLin->set_data.set (literal_data);
+        }
+        /* Save names or IDs to the template-line tracker: */
+        for (auto id_no : asset_info.asset_id_n_vector) {
+             templateLin->asset_info.asset_id_n_vector.push_back (id_no);
+        }
+        asset_info.asset_id_n_vector.clear();
+        for (auto as_name : asset_info.asset_name_vector) {
+             templateLin->asset_info.asset_name_vector.push_back (as_name);
+        }
+        asset_info.asset_name_vector.clear();
+    }
+
+    /* Random asset choice (e.g., *active) case: */
+    if (templateLin->random_asset != psa_asset_usage::all) {
+        /* Just create the call tracker;  random name chosen in simulation stage: */
+        templateLin->setup_call (set_data, templateLin->set_data.random_data,
+                                 yes_fill_in_template, create_call_bool,
+                                 templateLin, rsrc   );
+    } else if (asset_info.id_n_not_name) {
+        /* Not random asset;  asset(s) by ID rather than name.  Go through all
+           specified asset IDs: */
+        uint64_t id_no;
+        for (auto id_n :  templateLin->asset_info.asset_id_n_vector) {
+            id_no = id_n + (uint64_t) instance * 10000UL;
+            templateLin->asset_info.set_id_n(id_no);  /* just a holder */
+            asset_name = templateLin->asset_info.make_id_n_based_name (id_no);
+            templateLin->asset_info.set_calc_name (asset_name);
+            templateLin->expect.data_var = var_name;
+            if (!set_data.literal_data_not_file) {
+                templateLin->set_data.set_file (set_data.file_path);
+            }
+            templateLin->setup_call (set_data, templateLin->set_data.random_data,
+                                     fill_in_template, create_call_bool,
+                                     templateLin, rsrc   );
+        }
+    } else {
+        /* Not random asset, asset(s) specified by name.  Go through all specified
+           asset names: */
+        for (auto as_name :  templateLin->asset_info.asset_name_vector) {
+            /* Also copy into template line object's local vector: */
+            if (instance > 0) {
+                templateLin->asset_info.set_name (as_name + "_" + to_string (instance));
+            } else {
+                templateLin->asset_info.set_name (as_name);
+            }
+            /* Give each occurrence a different random ID: */
+            templateLin->asset_info.set_id_n (100 + (rand() % 10000));
+                /* TODO:  unlikely, but this *could* alias! */
+            templateLin->setup_call (set_data, templateLin->set_data.random_data,
+                                     yes_fill_in_template, create_call_bool,
+                                     templateLin, rsrc   );
+        }
+    }
+}
+
+%}
+
+%start lines
+
+%union {int valueN; int tokenN; char *str;}
+%token <tokenN> PURPOSE RAW_TEXT
+%token <tokenN> SET READ REMOVE SECURE DONE  /* root commands */
+%token <tokenN> SST KEY POLICY NAME UID STAR ACTIVE DELETED EQUAL DATA DFNAME
+%token <tokenN> FLAG NONE WRITE_ONCE NO_RP NO_CONF  /* SST creation flag keywords */
+%token <tokenN> OFFSET  /* offset into an SST asset */
+%token <tokenN> CHECK VAR HASH NEQ PRINT EXPECT PASS FAIL NOTHING ERROR  /* expected results */
+%token <str> IDENTIFIER_TOK LITERAL_TOK HEX_LIST FILE_PATH_TOK  /* variables and content */
+%token <valueN> NUMBER_TOK  /* variables and content */
+%token <tokenN> SEMICOLON SHUFFLE TO OF OPEN_BRACE CLOSE_BRACE  /* block structure */
+%token <tokenN> ATTR TYPE ALG  /* "set policy" line portions */
+%token <tokenN> EXPORT COPY ENCRYPT DECRYPT SIGN VERIFY DERIVE  /* key-usage keywords */
+%token <tokenN> NOEXPORT NOCOPY NOENCRYPT NODECRYPT NOSIGN NOVERIFY NODERIVE
+%token <tokenN> PERSISTENT VOLATILE  /* key lifetime keywords */
+%token <tokenN> FROM  /* for copying a key "from" another */
+%token <tokenN> WITH  /* for specifying a key without explicitly defining a policy */
+
+%define parse.error verbose
+%locations
+%parse-param {tf_fuzz_info *rsrc}
+
+%%
+
+  /* Top-level syntax: */
+lines:
+        %empty  /* nothing */
+      | line lines {
+            IVM(cout << "Lines:  Line number " << dec << yylineno << "." << endl;)
+            /* Re-randomize objects we parse into: */
+            expect = expect_info();
+            set_data = set_data_info();
+            parsed_asset = asset_name_id_info();
+            policy_info = key_policy_info();
+        }
+      ;
+
+line:
+        PURPOSE {
+            IVM(cout << "Purpose line:  " << flush;)
+            set_purp_str (yytext, rsrc);
+            IVM(cout << rsrc->test_purpose << endl;)
+            /* TODO:  Is there much/any value in turning this back on?  The
+                      constructor clear()s them out, and run-time errors observed
+                      under Visual Studio...
+               Just a precaution to make sure that these vectors start out empty.
+               Should inherently be, but purpose is typically specified first:
+            parsed_asset.asset_id_n_vector.clear();
+            parsed_asset.asset_name_vector.clear(); */
+            /* Re-randomize or re-initialize objects we parse into: */
+            purpose_defined = true;
+            expect = expect_info();
+            set_data = set_data_info();
+            parsed_asset = asset_name_id_info();
+            policy_info = key_policy_info();
+            target_barrier = "";
+        }
+      | block {
+            /* TODO:  This code may not won't work with "secure hash neq ..." */
+            IVM(cout << "Block of lines." << endl;)
+            /* "Statisticalize" :-) the vector of template lines, then crank
+               the selected lines in order here. */
+            randomize_template_lines (shuffle_not_pick,
+                low_nmbr_lines, high_nmbr_lines, exact_nmbr_lines,
+                template_block_vector, block_order, rsrc
+            );
+            /* Vector block_order contains the sequence of template lines to be
+               realized, in order.  Pop the indicated template line off the
+               vector and generate code from it: */
+            k = 0;  /* ID adder to at least help ensure uniqueness */
+            for (int i : block_order) {
+                templateLin = template_block_vector[i];
+                /* Note that temLin will have its fields filled in already. */
+                interpret_template_line (
+                    templateLin, rsrc, set_data, random_asset,
+                    assign_data_var_specified, expect, policy_info,
+                    print_data, hash_data, asset_name, assign_data_var, parsed_asset,
+                    yes_create_call,  /* did not create call nor asset earlier */
+                    yes_create_asset,
+                    dont_fill_in_template,  /* but did fill it all in before */
+                    0
+                );
+                k++;
+                for (add_expect = 0;  add_expect < rsrc->calls.size();  ++add_expect) {
+                    if (!(rsrc->calls[add_expect]->exp_data.expected_results_saved)) {
+                        templateLin->expect.copy_expect_to_call (rsrc->calls[add_expect]);
+                        templateLin->expect.expected_results_saved = true;
+                    }
+                }
+            }
+            templateLin->asset_info.asset_id_n_vector.clear();
+            templateLin->asset_info.asset_name_vector.clear();
+            /* Done.  Empty out the "statisticalization" vector: */
+            block_order.clear();
+            /* Empty out the vector of template lines; no longer needed. */
+            template_block_vector.clear();
+            --nesting_level;
+            IVM(cout << "Finished coding block of lines." << endl;)
+        }
+      | command SEMICOLON {
+            IVM(cout << "Command with no expect:  \"" << flush;)
+            if (!purpose_defined) {
+                cerr << endl << endl
+                     << "Error:  Please begin your test with the \"purpose\" "
+                     << "directive.  \n        For example, "
+                     << "\"purpose to exercise crypto and SST...\"" << endl;
+                exit (1024);
+            }
+            if (nesting_level == 0) {  /* if laying down the code now... */
+                for (add_expect = 0;  add_expect < rsrc->calls.size();  ++add_expect) {
+                    if (!(rsrc->calls[add_expect]->exp_data.expected_results_saved)) {
+                        templateLin->expect.copy_expect_to_call (rsrc->calls[add_expect]);
+                        templateLin->expect.expected_results_saved = true;
+                    }
+                }
+                delete templateLin;  /* done with this template line */
+            } else {
+                /* The template line is now fully decoded, so stuff it onto
+                   vector of lines to be "statisticalized": */
+                template_block_vector.push_back (templateLin);
+            }
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      | command expect SEMICOLON {
+            /* (This is the same as for command SEMICOLON, other than the IVM.) */
+            IVM(cout << "Command with expect:  \"" << flush;)
+            if (!purpose_defined) {
+                cerr << endl << endl
+                     << "Error:  Please begin your test with the \"purpose\" "
+                     << "directive.  \n        For example, "
+                     << "\"purpose to exercise crypto and SST...\"" << endl;
+                exit (1024);
+            }
+            if (nesting_level == 0) {
+                for (add_expect = 0;  add_expect < rsrc->calls.size();  ++add_expect) {
+                    if (!(rsrc->calls[add_expect]->exp_data.expected_results_saved)) {
+                        templateLin->expect.copy_expect_to_call (rsrc->calls[add_expect]);
+                        templateLin->expect.expected_results_saved = true;
+                    }
+                }
+                delete templateLin;
+            } else {
+                template_block_vector.push_back (templateLin);
+            }
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+command:
+        set_command {
+            IVM(cout << "Set command:  \"" << yytext << "\"" << endl;)
+        }
+      | remove_command {
+            IVM(cout << "Remove command:  \"" << yytext << "\"" << endl;)
+        }
+      | read_command {
+            IVM(cout << "Read command:  \"" << yytext << "\"" << endl;)
+        }
+      | secure_command {
+            IVM(cout << "Security command:  \"" << yytext << "\"" << endl;)
+        }
+      | done_command {
+            IVM(cout << "Done command:  \"" << yytext << "\"" << endl;)
+        }
+      ;
+
+expect:
+        EXPECT PASS  {
+            IVM(cout << "Expect pass clause:  \"" << flush;)
+            templateLin->expect.set_pf_pass();
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      | EXPECT FAIL {
+            IVM(cout << "Expect fail clause:  \"" << flush;)
+            templateLin->expect.set_pf_fail();
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      | EXPECT NOTHING {
+            IVM(cout << "Expect nothing clause:  \"" << flush;)
+            templateLin->expect.set_pf_nothing();
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      | EXPECT IDENTIFIER {
+            IVM(cout << "Expect error clause:  \"" << flush;)
+            templateLin->expect.set_pf_error (identifier);
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+  /* Root commands: */
+set_command:
+        SET SST sst_set_base_args sst_set_extended_args {
+            IVM(cout << "Set SST command:  \"" << yytext << "\"" << endl;)
+            templateLin = new set_sst_template_line (rsrc);
+            interpret_template_line (
+                templateLin, rsrc, set_data, random_asset,
+                assign_data_var_specified, expect, policy_info,
+                print_data, hash_data, asset_name, assign_data_var, parsed_asset,
+                nesting_level == 0 /* create call unless inside {} */,
+                nesting_level == 0 /* similarly, create asset unless inside {} */,
+                yes_fill_in_template, 0
+            );
+        }
+      | SET KEY key_set_args {
+            IVM(cout << "Set key command:  \"" << yytext << "\"" << endl;)
+            templateLin = new set_key_template_line (rsrc);
+            target_barrier = policy_info.asset_2_name;  /* policy */
+            interpret_template_line (
+                templateLin, rsrc, set_data, random_asset,
+                assign_data_var_specified, expect, policy_info,
+                print_data, hash_data, asset_name, assign_data_var, parsed_asset,
+                nesting_level == 0 /* create call unless inside {} */,
+                nesting_level == 0 /* similarly, create asset unless inside {} */,
+                yes_fill_in_template, 0
+            );
+        }
+      | SET POLICY policy_set_args {
+            IVM(cout << "Set policy command:  \"" << yytext << "\"" << endl;;)
+            templateLin = new set_policy_template_line (rsrc);
+            interpret_template_line (
+                templateLin, rsrc, set_data, random_asset,
+                assign_data_var_specified, expect, policy_info,
+                print_data, hash_data, asset_name, assign_data_var, parsed_asset,
+                nesting_level == 0 /* create call unless inside {} */,
+                nesting_level == 0 /* similarly, create asset unless inside {} */,
+                yes_fill_in_template, 0
+            );
+        }
+      ;
+
+read_command:
+        READ SST sst_read_args {
+            IVM(cout << "Read SST command:  \"" << yytext << "\"" << endl;;)
+            templateLin = new read_sst_template_line (rsrc);
+            interpret_template_line (
+                templateLin, rsrc, set_data, random_asset,
+                assign_data_var_specified, expect, policy_info,
+                print_data, hash_data, asset_name, assign_data_var, parsed_asset,
+                nesting_level == 0 /* create call unless inside {} */,
+                dont_create_asset /* if no such asset exists, fail the call */,
+                yes_fill_in_template, 0
+            );
+        }
+      | READ KEY key_read_args {
+            IVM(cout << "Read key command:  \"" << yytext << "\"" << endl;;)
+            templateLin = new read_key_template_line (rsrc);
+            interpret_template_line (
+                templateLin, rsrc, set_data, random_asset,
+                assign_data_var_specified, expect, policy_info,
+                print_data, hash_data, asset_name, assign_data_var, parsed_asset,
+                nesting_level == 0 /* create call unless inside {} */,
+                dont_create_asset /* if no such asset exists, fail the call */,
+                yes_fill_in_template, 0
+            );
+        }
+      | READ POLICY policy_read_args {
+            IVM(cout << "Read policy command:  \"" << yytext << "\"" << endl;;)
+            templateLin = new read_policy_template_line (rsrc);
+            interpret_template_line (
+                templateLin, rsrc, set_data, random_asset,
+                assign_data_var_specified, expect, policy_info,
+                print_data, hash_data, asset_name, assign_data_var, parsed_asset,
+                nesting_level == 0 /* create call unless inside {} */,
+                dont_create_asset /* if no such asset exists, fail the call */,
+                yes_fill_in_template, 0
+            );
+        }
+      ;
+
+remove_command:
+        REMOVE SST sst_remove_args {
+            IVM(cout << "Remove SST command:  \"" << yytext << "\"" << endl;;)
+            templateLin = new remove_sst_template_line (rsrc);
+            interpret_template_line (
+                templateLin, rsrc, set_data, random_asset,
+                assign_data_var_specified, expect, policy_info,
+                print_data, hash_data, asset_name, assign_data_var, parsed_asset,
+                nesting_level == 0 /* create call unless inside {} */,
+                dont_create_asset /* don't create an asset being deleted */,
+                yes_fill_in_template, 0
+            );
+        }
+      | REMOVE KEY key_remove_args {
+            IVM(cout << "Remove key command:  \"" << yytext << "\"" << endl;;)
+            templateLin = new remove_key_template_line (rsrc);
+            templateLin->asset_info.set_name (asset_name);  // set in key_asset_name, below
+            interpret_template_line (
+                templateLin, rsrc, set_data, random_asset,
+                assign_data_var_specified, expect, policy_info,
+                print_data, hash_data, asset_name, assign_data_var, parsed_asset,
+                nesting_level == 0 /* create call unless inside {} */,
+                dont_create_asset /* don't create an asset being deleted */,
+                yes_fill_in_template, 0
+            );
+        }
+      ;
+
+secure_command: SECURE HASH NEQ ASSET_IDENTIFIER_LIST {
+  /* TODO:  This needs to allow not only SST assets, but mix and match with others
+             (keys especially) as well. */
+            IVM(cout << "Secure hash command:  \"" << yytext << "\"" << endl;)
+            templateLin = new security_hash_template_line (rsrc);
+            templateLin->asset_info.set_name (asset_name);
+            templateLin->assign_data_var_specified = assign_data_var_specified;
+            templateLin->assign_data_var.assign (assign_data_var);
+            templateLin->expect = expect;
+            templateLin->print_data = print_data;
+            templateLin->hash_data = hash_data;
+            templateLin->random_asset = random_asset;
+            /* Hash checks are different from the rest in that there's a single
+               "call" -- not a PSA call though -- for all of the assets cited in the
+               template line.  In *other* cases, create a single call for *each*
+               asset cited by the template line, but not in this case. */
+            for (auto as_name : parsed_asset.asset_name_vector) {
+                /* Also copy into template line object's local vector: */
+                 templateLin->asset_info.asset_name_vector.push_back (as_name);
+            }
+            /* Don't need to locate the assets, so no searches required. */
+            templateLin->expect.data_var = var_name;
+            templateLin->setup_call (set_data, set_data.random_data, yes_fill_in_template,
+                                     nesting_level == 0, templateLin, rsrc   );
+            parsed_asset.asset_name_vector.clear();
+
+
+        }
+      ;
+
+done_command: DONE {
+            if (nesting_level != 0) {
+                cerr << "\n\"done\" only available at outer-most { } nesting level."
+                     << endl;
+                exit (702);
+            } else {
+                YYACCEPT;
+            }
+        }
+      ;
+
+literal_or_random_data:
+        DATA LITERAL {
+            IVM(cout << "Create from literal data:  \"" << flush;)
+            set_data.random_data = false;
+            set_data.string_specified = true;
+            set_data.literal_data_not_file = true;
+            literal.erase(0,1);  // zap the ""s
+            literal.erase(literal.length()-1,1);
+            literal_data.assign (literal);
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      | DATA STAR {  /* TF-Fuzz supplies random data */
+            IVM(cout << "Create from random data" << endl;)
+            set_data.randomize();
+            literal.assign (set_data.get());  /* just in case something uses literal */
+            set_data.random_data = true;
+            set_data.string_specified = false;
+        }
+      ;
+
+  /* Root-command parameters: */
+sst_set_base_args:
+        sst_asset_name literal_or_random_data
+      | sst_asset_name {
+            IVM(cout << "SST-create from random data (no 'data *')" << endl;)
+            set_data.randomize();
+            literal.assign (set_data.get());  /* just in case something uses literal */
+        }
+      | sst_asset_name VAR IDENTIFIER {  /* set from variable */
+            IVM(cout << "SST-set set from variable:  \"" << flush;)
+            assign_data_var.assign (identifier);
+            assign_data_var_specified = true;
+            expect.data_specified = false;
+            expect.data_var_specified = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      | sst_asset_name DFNAME sst_asset_set_file_path {
+            set_data.literal_data_not_file = set_data.random_data = false;
+            IVM(cout << "SST-create from file:  " << yytext << "\"" << endl;)
+            /* TODO:  Need to decide whether the concept of using files to set SST
+                       asset values has meaning, and if so, write code to write code to
+                       set data appropriately from the file. */
+        }
+      ;
+
+sst_set_extended_args:
+        %empty /* nothing */
+      | FLAG sst_flags {
+            IVM(cout << "SST creation flags" << endl;)
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+sst_flags:
+        %empty /* nothing */
+      | sst_flag sst_flags {
+            IVM(cout << "SST creation flag" << endl;)
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+sst_flag:  none | write_once | no_rp | no_conf;
+
+none : NONE {
+            set_data.flags_string = "PSA_STORAGE_FLAG_NONE";
+                /* TODO:  grab from boilerplate */
+            IVM(cout << "SST no storage flag:  " << yytext << "\"" << endl;)
+        }
+      ;
+
+write_once : WRITE_ONCE {
+            set_data.flags_string = "PSA_STORAGE_FLAG_WRITE_ONCE";
+                /* TODO:  grab from boilerplate */
+            IVM(cout << "SST write-once flag:  " << yytext << "\"" << endl;)
+        }
+      ;
+
+no_rp : NO_RP {
+            set_data.flags_string = "PSA_STORAGE_FLAG_NO_REPLAY_PROTECTION";
+                /* TODO:  grab from boilerplate */
+            IVM(cout << "SST no-replay-protection flag:  "
+                     << yytext << "\"" << endl;)
+        }
+      ;
+
+no_conf : NO_CONF {
+            set_data.flags_string = "PSA_STORAGE_FLAG_NO_CONFIDENTIALITY";
+                /* TODO:  grab from boilerplate */
+            IVM(cout << "SST no-confidentiality flag:  " << yytext
+                     << "\"" << endl;)
+        }
+      ;
+
+sst_offset_spec:
+        NUMBER_TOK {
+            IVM(cout << "SST-data offset:  \"" << flush;)
+            set_data.data_offset = atol(yytext);
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+
+sst_read_args:
+        sst_asset_name read_args sst_read_extended_args {
+            IVM(cout << "SST-read arguments:  " << yytext << "\"" << endl;)
+        }
+      ;
+
+read_args:
+        VAR IDENTIFIER {  /* dump to variable */
+            IVM(cout << "Read dump to variable:  \"" << flush;)
+            assign_data_var.assign (identifier);
+            assign_data_var_specified = true;
+            expect.data_specified = false;
+            expect.data_var_specified = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      | CHECK read_args_var_name {  /* check against variable */
+            IVM(cout << "Read check against variable:  \""
+                     << yytext << "\"" << endl;)
+            set_data.set (literal);
+            assign_data_var_specified = false;
+            expect.data_specified = false;
+            expect.data_var_specified = true;
+            expect.data_var = identifier;
+        }
+      | CHECK LITERAL {  /* check against literal */
+            IVM(cout << "Read check against literal:  " << flush;)
+            expect.data.assign (literal);
+            expect.data.erase(0,1);    // zap the ""s
+            expect.data.erase(expect.data.length()-1,1);
+            assign_data_var_specified = false;  /* don't read variable */
+            expect.data_specified = true;  /* check against literal data */
+            expect.data_var_specified = false;  /* don't check against variable */
+            IVM(cout << yytext << endl;)
+        }
+      | PRINT {  /* print out content in test log */
+            IVM(cout << "Read log to test log:  \"" << flush;)
+            /* TODO:  set_data content probably doesn't need to be set here;
+                       constructor probably sets it fine. */
+            set_data.random_data = false;
+            set_data.literal_data_not_file = true;
+            assign_data_var_specified = false;
+            expect.data_specified = false;
+            expect.data_var_specified = false;
+            print_data = true;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      | HASH {  /* hash the data and save for later comparison */
+            IVM(cout << "Read hash for future data-leak detection:  \"" << flush;)
+            /* TODO:  set_data content probably doesn't need to be set here;
+                       constructor probably sets it fine. */
+            set_data.random_data = false;
+            set_data.literal_data_not_file = true;
+            assign_data_var_specified = false;
+            expect.data_specified = false;
+            expect.data_var_specified = false;
+            hash_data = true;
+            rsrc->include_hashing_code = true;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      | DFNAME sst_asset_dump_file_path {  /* dump to file */
+            IVM(cout << "Read dump to file:  \""
+                     << yytext << "\"" << endl;)
+            set_data.literal_data_not_file = set_data.random_data = false;
+        }
+      ;
+
+sst_read_extended_args:
+        %empty /* nothing */
+      | OFFSET sst_offset_spec {
+            IVM(cout << "SST data offset" << endl;)
+            set_data.data_offset = atol(yytext);
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+sst_remove_args:
+        sst_asset_name | random_picked_asset {
+            IVM(cout << "SST-remove arguments:  \""
+                     << yytext << "\"" << endl;)
+        }
+      ;
+
+asset_designator:
+        NAME ASSET_IDENTIFIER_LIST {
+            IVM(cout << "Asset identifier list:  \"" << flush;)
+            random_name = false;
+            asset_name.assign (identifier);  /* TODO:  Not sure this ultimately has any effect... */
+            random_asset = psa_asset_usage::all;  /* don't randomly choose existing asset */
+            parsed_asset.id_n_not_name = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      | NAME STAR {
+            IVM(cout << "Asset random identifier:  \"" << flush;)
+            random_name = true;
+            rand_data_length = 4 + (rand() % 5);
+            gib.word (false, gib_buff, gib_buff + rand_data_length - 1);
+            aid.assign (gib_buff);
+            parsed_asset.asset_name_vector.push_back (aid);
+            random_asset = psa_asset_usage::all;  /* don't randomly choose existing asset */
+            parsed_asset.id_n_not_name = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+single_existing_asset:
+        IDENTIFIER {
+            IVM(cout << "Single existing asset by name:  \"" << flush;)
+            random_name = false;
+            policy_info.asset_3_name.assign (identifier);
+            random_asset = psa_asset_usage::all;  /* don't randomly choose existing asset */
+            parsed_asset.id_n_not_name = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      | random_picked_asset
+      ;
+
+random_picked_asset:
+        STAR ACTIVE {
+            IVM(cout << "Asset random active:  \"" << flush;)
+            random_asset = psa_asset_usage::active;
+            parsed_asset.id_n_not_name = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      | STAR DELETED {
+            IVM(cout << "Asset random deleted:  \"" << flush;)
+            random_asset = psa_asset_usage::deleted;
+            parsed_asset.id_n_not_name = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+sst_asset_name:
+        asset_designator
+      | UID ASSET_NUMBER_LIST {
+            IVM(cout << "SST-asset UID list:  \"" << flush;)
+            random_name = false;
+            random_asset = psa_asset_usage::all;  /* don't randomly choose existing asset */
+            parsed_asset.id_n_not_name = true;
+            parsed_asset.id_n_specified = true;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      | UID STAR {
+            IVM(cout << "SST-asset random UID:  \"" << flush;)
+            parsed_asset.id_n_not_name = true;
+            random_name = false;
+            nid = 100 + (rand() % 10000);
+            parsed_asset.asset_id_n_vector.push_back (nid);
+            random_asset = psa_asset_usage::all;  /* don't randomly choose existing asset */
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+sst_asset_set_file_path:
+        FILE_PATH {
+            IVM(cout << "SST-asset-create file path:  \"" << flush;)
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+read_args_var_name:
+        IDENTIFIER {
+            IVM(cout << "Read-arguments variable name:  \"" << flush;)
+            var_name = yytext;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+sst_asset_dump_file_path:
+        FILE_PATH {
+            IVM(cout << "SST-asset dump-file path:  \"" << flush;)
+            set_data.file_path = yytext;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+key_size:
+        NUMBER_TOK {
+            IVM(cout << "Key size:  \"" << flush;)
+            policy_info.n_bits = atol(yytext);
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+policy_usage_list:  ATTR policy_usage policy_usages;  /* at least one usage */
+
+policy_usages:
+        %empty  /* nothing */
+      | policy_usage policy_usages {
+            IVM(cout << "Key-policy usages at line number " << dec << yylineno
+                     << "." << endl;)
+        }
+      ;
+
+export : EXPORT {
+            policy_info.exportable = true;
+            IVM(cout << "Exportable key true:  " << yytext << "\"" << endl;)
+        }
+      ;
+
+noexport : NOEXPORT {
+            policy_info.exportable = false;
+            IVM(cout << "Non-exportable key:  " << yytext << "\"" << endl;)
+        }
+      ;
+
+copy : COPY {
+            policy_info.copyable = true;
+            IVM(cout << "Copyable key true:  " << yytext << "\"" << endl;)
+        }
+      ;
+
+nocopy : NOCOPY {
+            policy_info.copyable = false;
+            IVM(cout << "Non-copyable key:  " << yytext << "\"" << endl;)
+        }
+      ;
+
+encrypt : ENCRYPT {
+            policy_info.can_encrypt = true;
+            IVM(cout << "Encryption key true:  " << yytext << "\"" << endl;)
+        }
+      ;
+
+noencrypt : NOENCRYPT {
+            policy_info.can_encrypt = false;
+            IVM(cout << "Non-encryption key:  " << yytext << "\"" << endl;)
+        }
+      ;
+
+decrypt : DECRYPT {
+            policy_info.can_decrypt = true;
+            IVM(cout << "Decryption key true:  " << yytext << "\"" << endl;)
+        }
+      ;
+
+nodecrypt : NODECRYPT {
+            policy_info.can_decrypt = false;
+            IVM(cout << "Non-decryption key:  " << yytext << "\"" << endl;)
+        }
+      ;
+
+sign : SIGN {
+            policy_info.can_sign = true;
+            IVM(cout << "Signing key true:  " << yytext << "\"" << endl;)
+        }
+      ;
+
+nosign : NOSIGN {
+            policy_info.can_sign = false;
+            IVM(cout << "Non-signing key:  " << yytext << "\"" << endl;)
+        }
+      ;
+
+verify : VERIFY {
+            policy_info.can_verify = true;
+            IVM(cout << "Verify key true:  " << yytext << "\"" << endl;)
+        }
+      ;
+
+noverify : NOVERIFY {
+            policy_info.can_verify = false;
+            IVM(cout << "Non-verify key:  " << yytext << "\"" << endl;)
+        }
+      ;
+
+derive : DERIVE {
+            policy_info.derivable = true;
+            IVM(cout << "Derivable key true:  " << yytext << "\"" << endl;)
+        }
+      ;
+
+noderive : NODERIVE {
+            policy_info.derivable = false;
+            IVM(cout << "Non-derivable key:  " << yytext << "\"" << endl;)
+        }
+      ;
+
+persistent : PERSISTENT {
+            policy_info.persistent = true;
+            IVM(cout << "Persistent key:  " << yytext << "\"" << endl;)
+        }
+      ;
+
+volatle : VOLATILE {
+            policy_info.persistent = false;
+            IVM(cout << "Volatile key:  " << yytext << "\"" << endl;)
+        }
+      ;
+
+policy_usage:
+        export | copy | encrypt | decrypt | sign | verify | derive
+      | noexport | nocopy | noencrypt | nodecrypt | nosign | noverify
+      | noderive | persistent | volatle | key_size {
+            IVM(cout << "Policy usage:  " << yytext << "\"" << endl;)
+        }
+      ;
+
+policy_type:
+      TYPE IDENTIFIER {
+            // Change type identifier, e.g., from "raw_data" to PSA_KEY_TYPE_RAW_DATA:
+            identifier = formalize (identifier, "PSA_KEY_TYPE_");
+            policy_info.key_type = identifier;
+            IVM(cout << "Policy type:  \""
+                     << policy_info.key_type << "\"" << endl;)
+      }
+
+policy_algorithm:
+      ALG IDENTIFIER {
+            // Change type identifier, e.g., from "sha_256" to PSA_ALG_SHA_256:
+            identifier = formalize (identifier, "PSA_ALG_");
+            policy_info.key_algorithm = identifier;
+            IVM(cout << "Policy algorithm:  \""
+                     << policy_info.key_algorithm << "\"" << endl;)
+      }
+
+policy_specs:
+        %empty  /* nothing */
+      | policy_spec policy_specs {
+            IVM(cout << "Key-policy specs at line number " << dec << yylineno
+                     << "." << endl;)
+        }
+      ;
+
+policy_spec:  policy_usage_list | policy_type | policy_algorithm;
+
+policy_asset_spec:
+        %empty  /* nothing */
+      | NAME ASSET_IDENTIFIER_LIST {
+            IVM(cout << "policy-asset identifier list:  \"" << flush;)
+            random_name = false;
+            asset_name.assign (identifier);  /* TODO:  Not sure this ultimately has any effect... */
+            random_asset = psa_asset_usage::all;  /* don't randomly choose existing asset */
+            parsed_asset.id_n_not_name = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      | NAME STAR {
+            IVM(cout << "policy-asset random identifier:  \"" << flush;)
+            random_name = true;
+            rand_data_length = 2 + (rand() % 10);
+            gib.word (false, gib_buff, gib_buff + rand_data_length - 1);
+            aid.assign (gib_buff);
+            parsed_asset.asset_name_vector.push_back (aid);
+            random_asset = psa_asset_usage::all;  /* don't randomly choose existing asset */
+            parsed_asset.id_n_not_name = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+policy_asset_name:
+        NAME IDENTIFIER {
+            IVM(cout << "policy-asset identifier list:  \"" << flush;)
+            random_name = false;
+            policy_info.get_policy_from_key = false;
+            asset_name.assign (identifier);  /* TODO:  Not sure this ultimately has any effect... */
+            parsed_asset.asset_name_vector.push_back (identifier);
+            random_asset = psa_asset_usage::all;  /* don't randomly choose existing asset */
+            parsed_asset.id_n_not_name = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      | STAR ACTIVE {
+            IVM(cout << "policy-asset random active:  \"" << flush;)
+            policy_info.get_policy_from_key = false;
+            random_asset = psa_asset_usage::active;
+            parsed_asset.id_n_not_name = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      | STAR DELETED {
+            IVM(cout << "policy-asset random deleted:  \"" << flush;)
+            policy_info.get_policy_from_key = false;
+            random_asset = psa_asset_usage::deleted;
+            parsed_asset.id_n_not_name = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      | KEY IDENTIFIER {
+            IVM(cout << "policy-asset specified by key:  \"" << flush;)
+            policy_info.get_policy_from_key = true;
+            random_name = false;
+            asset_name.assign (identifier);  /* ask this key what it's policy is */
+            random_asset = psa_asset_usage::all;  /* don't randomly choose existing asset */
+            parsed_asset.id_n_not_name = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+policy_set_args:
+        policy_asset_spec policy_specs {
+            IVM(cout << "Policy-create arguments:  \"" << yytext << "\"" << endl;)
+        }
+      ;
+
+policy_read_args:
+        policy_asset_name read_args {
+            IVM(cout << "Policy-read arguments:  " << yytext << "\"" << endl;)
+        }
+      ;
+
+key_set_sources:
+        %empty  /* nothing */
+      | key_set_source key_set_sources {
+            IVM(cout << "Key-set sources at Line number "
+                     << yytext << "\"" << endl;)
+        }
+      ;
+
+key_set_source:
+        literal_or_random_data {
+            IVM(cout << "Key-set sources, literal or random data:  "
+                     << yytext << "\"" << endl;)
+        }
+      | POLICY IDENTIFIER {
+            IVM(cout << "Key-set sources, explicitly-specified policy name:  "
+                     << flush;)
+            policy_info.asset_2_name = identifier;  /* policy */
+            /* Make note that key data (key material) was not specified: */
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+key_data_or_not:
+        %empty  /* nothing */
+      | literal_or_random_data {
+            IVM(cout << "Key data, literal or random data:  "
+                     << yytext << "\"" << endl;)
+        }
+      ;
+
+key_set_args:
+        asset_designator key_set_sources {
+            IVM(cout << "Key-create from data, policy, or nothing (default):  \""
+                     << yytext << "\"" << endl;)
+            policy_info.copy_key = false;
+            policy_info.implicit_policy = false;
+        }
+      | asset_designator FROM single_existing_asset POLICY IDENTIFIER {
+            IVM(cout << "Key-copy from other key:  \"" << flush;)
+            policy_info.asset_2_name = identifier;  /* policy */
+            policy_info.copy_key = true;
+            policy_info.implicit_policy = false;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      | asset_designator key_data_or_not WITH policy_specs {
+            IVM(cout << "Key-create directly specifying policy attributes (implicit policy):  \""
+                     << yytext << "\"" << endl;)
+            policy_info.copy_key = false;
+            policy_info.implicit_policy = true;
+            cerr << "\nError:  Defining keys with implicit policies is not yet implemented."
+                 << endl;
+            exit (772);
+        }
+      ;
+
+key_remove_args:
+        asset_designator {
+            IVM(cout << "Key-remove arguments:  \""
+                     << yytext << "\"" << endl;)
+        }
+      ;
+
+key_read_args:
+        asset_designator read_args {
+            IVM(cout << "Key dump:  \"" << yytext << "\"" << endl;)
+        }
+      ;
+
+/* Code structuring: */
+block:
+        SHUFFLE block_content {
+            IVM(cout << "Shuffled block:  \"" << flush;)
+            if (nesting_level > 1) {
+                cerr << "\nError:  Sorry, currently only one level of { } "
+                     << "nesting is allowed." << endl;
+                exit (500);
+            }
+            shuffle_not_pick = true;
+            low_nmbr_lines = high_nmbr_lines = 0;  /* not used, but... */
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      | exact_sel_count OF block_content {
+            IVM(cout << "Fixed number of lines from block:  \"" << flush;)
+            shuffle_not_pick = false;
+            /* low_nmbr_lines and high_nmbr_lines are set below. */
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      | low_sel_count TO high_sel_count OF block_content {
+            IVM(cout << "Range number of lines from block:  \"" << flush;)
+            if (nesting_level > 1) {
+                cerr << "\nError:  Sorry, currently only one level of { } "
+                     << "nesting is allowed." << endl;
+                exit (502);
+            }
+            shuffle_not_pick = false;
+            /* low_nmbr_lines and high_nmbr_lines are set below. */
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+block_content:
+        open_brace lines close_brace {
+            IVM(cout << "Block content:  \"" << yytext << "\"" << endl;)
+        }
+      | line {
+            IVM(cout << "Single-line would-be-block content:  \"" << flush;)
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+open_brace:
+        OPEN_BRACE {
+            IVM(cout << "Open brace:  \"" << flush;)
+            template_block_vector.clear();  // clean slate of template lines
+            nesting_level = 1;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+close_brace:
+        CLOSE_BRACE {
+            IVM(cout << "Close brace:  " << flush;)
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+  /* Low-level structures: */
+
+  /* Please see comment before ASSET_IDENTIFIER_LIST, below. */
+ASSET_NUMBER_LIST:
+        ASSET_NUMBER ASSET_NUMBERS;  /* at least one number */
+
+ASSET_NUMBERS:
+        %empty  /* nothing */
+      | ASSET_NUMBER ASSET_NUMBERS;
+
+ASSET_NUMBER:
+        NUMBER_TOK {
+            IVM(cout << "ASSET_NUMBER:  \"" << flush;)
+            nid = atol(yytext);
+            parsed_asset.asset_id_n_vector.push_back (nid);
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+  /* ASSET_IDENTIFIER are used specifically for lists of assets within a singletemplate
+     line.  That, as opposed to list of identifers in general.  The difference is the
+     need to queue ASSET_IDENTIFIERS up into parsed_asset.asset_name_vector, and have to
+     do so here before they "vanish." */
+ASSET_IDENTIFIER_LIST:
+        ASSET_IDENTIFIER ASSET_IDENTIFIERS;  /* (at least one) */
+
+ASSET_IDENTIFIERS:
+        %empty  /* nothing */
+      | ASSET_IDENTIFIER ASSET_IDENTIFIERS;
+
+ASSET_IDENTIFIER:
+        IDENTIFIER_TOK {
+            IVM(cout << "ASSET_IDENTIFIER:  \"" << flush;)
+            aid = identifier = yytext;
+            parsed_asset.asset_name_vector.push_back (aid);
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+IDENTIFIER:
+        IDENTIFIER_TOK {
+            IVM(cout << "IDENTIFIER:  \"" << flush;)
+            identifier = yytext;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+FILE_PATH:
+        FILE_PATH_TOK {
+            IVM(cout << "FILE_PATH:  \"" << flush;)
+            set_data.file_path = yytext;
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+  /* These are related to randomized blocks of template lines: */
+
+exact_sel_count:
+        NUMBER {
+            IVM(cout << "Exact number of random template lines:  \"" << flush;)
+            low_nmbr_lines = high_nmbr_lines = exact_nmbr_lines = number;
+            ++nesting_level;
+            IVM(cout << number << "\"" << endl;)
+        }
+      ;
+
+low_sel_count:
+        NUMBER {
+            IVM(cout << "Least number of random template lines:  \"" << flush;)
+            low_nmbr_lines = number;
+            IVM(cout << number << "\"" << endl;)
+        }
+      ;
+
+high_sel_count:
+        NUMBER {
+            IVM(cout << "Most number of random template lines:  \"" << flush;)
+            high_nmbr_lines = number;
+            ++nesting_level;
+            IVM(cout << number << "\"" << endl;)
+        }
+      ;
+
+
+  /* These are general-case numbers, literals and such: */
+
+NUMBER: NUMBER_TOK {
+            IVM(cout << "NUMBER:  \"" << flush;)
+            number = atol(yytext);
+            IVM(cout << yytext << "\"" << endl;)
+        }
+      ;
+
+LITERAL:
+        LITERAL_TOK {
+          IVM(cout << "LITERAL string:  " << flush;)
+          literal = yytext;
+          literal_is_string = true;
+          IVM(cout << yytext << endl;)
+        }
+      | HEX_LIST {
+          IVM(cout << "LITERAL hex-value list:  " << flush;)
+          literal = yytext;
+          literal_is_string = false;
+          IVM(cout << yytext << endl;)
+        }
+      ;
+
+
+%%
+
diff --git a/tf_fuzz/regression/000001_set_sst_uid_data_expect_pass/check.py b/tf_fuzz/regression/000001_set_sst_uid_data_expect_pass/check.py
new file mode 100644
index 0000000..1bc5cbe
--- /dev/null
+++ b/tf_fuzz/regression/000001_set_sst_uid_data_expect_pass/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000001_set_sst_uid_data_expect_pass/exp_stdout_stderr b/tf_fuzz/regression/000001_set_sst_uid_data_expect_pass/exp_stdout_stderr
new file mode 100644
index 0000000..1976f7b
--- /dev/null
+++ b/tf_fuzz/regression/000001_set_sst_uid_data_expect_pass/exp_stdout_stderr
@@ -0,0 +1,24 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to create an SST asset
+ASSET_NUMBER:  "104"
+SST-asset UID list:  "data"
+LITERAL string:  "Very simple test"
+Create from literal data:  ""Very simple test""
+Set SST command:  "expect"
+Appended to end of call sequence:  SST-set call.
+Set command:  "expect"
+Expect pass clause:  "pass"
+Command with expect:  ";"
+Lines:  Line number 3.
+Lines:  Line number 3.
+Call sequence generated.
+Simulating call sequence...
+Call sequence:
+    SST-set call for asset SST_ID_104
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/000001_set_sst_uid_data_expect_pass/exp_test.c b/tf_fuzz/regression/000001_set_sst_uid_data_expect_pass/exp_test.c
new file mode 100644
index 0000000..04b84e9
--- /dev/null
+++ b/tf_fuzz/regression/000001_set_sst_uid_data_expect_pass/exp_test.c
@@ -0,0 +1,61 @@
+/*
+ * Test purpose:
+ *     to create an SST asset
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t SST_ID_104_set_data[] = "Very simple test";
+    static uint32_t SST_ID_104_set_length = 16;
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to create an SST asset");
+
+
+    /* PSA calls to test: */
+    /\* Creating SST asset UID = 104 with data "Very simpl...". \*/
+    sst_status = psa_ps_set(104, SST_ID_104_set_length, SST_ID_104_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+
+
+    /* Removing assets left over from testing: */
+    psa_ps_remove(104);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/000001_set_sst_uid_data_expect_pass/template b/tf_fuzz/regression/000001_set_sst_uid_data_expect_pass/template
new file mode 100644
index 0000000..7b84f11
--- /dev/null
+++ b/tf_fuzz/regression/000001_set_sst_uid_data_expect_pass/template
@@ -0,0 +1,2 @@
+purpose to create an SST asset;
+set sst uid 104 data "Very simple test" expect pass;
diff --git a/tf_fuzz/regression/000002_set_sst_name_data_expect_nothing/check.py b/tf_fuzz/regression/000002_set_sst_name_data_expect_nothing/check.py
new file mode 100644
index 0000000..1bc5cbe
--- /dev/null
+++ b/tf_fuzz/regression/000002_set_sst_name_data_expect_nothing/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000002_set_sst_name_data_expect_nothing/exp_stdout_stderr b/tf_fuzz/regression/000002_set_sst_name_data_expect_nothing/exp_stdout_stderr
new file mode 100644
index 0000000..97c20e8
--- /dev/null
+++ b/tf_fuzz/regression/000002_set_sst_name_data_expect_nothing/exp_stdout_stderr
@@ -0,0 +1,24 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to give assets a human name
+ASSET_IDENTIFIER:  "forecast"
+Asset identifier list:  "data"
+LITERAL string:  "sunny with a 30% chance of weather!"
+Create from literal data:  ""sunny with a 30% chance of weather!""
+Set SST command:  "expect"
+Appended to end of call sequence:  SST-set call.
+Set command:  "expect"
+Expect nothing clause:  "nothing"
+Command with expect:  ";"
+Lines:  Line number 3.
+Lines:  Line number 3.
+Call sequence generated.
+Simulating call sequence...
+Call sequence:
+    SST-set call for asset forecast
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/000002_set_sst_name_data_expect_nothing/exp_test.c b/tf_fuzz/regression/000002_set_sst_name_data_expect_nothing/exp_test.c
new file mode 100644
index 0000000..e792c9b
--- /dev/null
+++ b/tf_fuzz/regression/000002_set_sst_name_data_expect_nothing/exp_test.c
@@ -0,0 +1,58 @@
+/*
+ * Test purpose:
+ *     to give assets a human name
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t forecast_set_data[] = "sunny with a 30% chance of weather!";
+    static uint32_t forecast_set_length = 35;
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to give assets a human name");
+
+
+    /* PSA calls to test: */
+    /\* Creating SST asset "forecast," with data "sunny with...". \*/
+    sst_status = psa_ps_set\(@@@001@@@, forecast_set_length, forecast_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    /* (No checks for this PSA call.) */
+
+
+    /* Removing assets left over from testing: */
+    psa_ps_remove\(@@@001@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/000002_set_sst_name_data_expect_nothing/template b/tf_fuzz/regression/000002_set_sst_name_data_expect_nothing/template
new file mode 100644
index 0000000..7292031
--- /dev/null
+++ b/tf_fuzz/regression/000002_set_sst_name_data_expect_nothing/template
@@ -0,0 +1,2 @@
+purpose to give assets a human name;
+set sst name forecast data "sunny with a 30% chance of weather!" expect nothing;
diff --git a/tf_fuzz/regression/000003_set_sst_name_data/check.py b/tf_fuzz/regression/000003_set_sst_name_data/check.py
new file mode 100644
index 0000000..1bc5cbe
--- /dev/null
+++ b/tf_fuzz/regression/000003_set_sst_name_data/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000003_set_sst_name_data/exp_stdout_stderr b/tf_fuzz/regression/000003_set_sst_name_data/exp_stdout_stderr
new file mode 100644
index 0000000..19a9bdb
--- /dev/null
+++ b/tf_fuzz/regression/000003_set_sst_name_data/exp_stdout_stderr
@@ -0,0 +1,23 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to show that TF-Fuzz can \"infer\" \"results\"
+ASSET_IDENTIFIER:  "jonathan"
+Asset identifier list:  "data"
+LITERAL string:  "I am the man"
+Create from literal data:  ""I am the man""
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+Lines:  Line number 3.
+Lines:  Line number 3.
+Call sequence generated.
+Simulating call sequence...
+Call sequence:
+    SST-set call for asset jonathan
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/000003_set_sst_name_data/exp_test.c b/tf_fuzz/regression/000003_set_sst_name_data/exp_test.c
new file mode 100644
index 0000000..9dc4d24
--- /dev/null
+++ b/tf_fuzz/regression/000003_set_sst_name_data/exp_test.c
@@ -0,0 +1,61 @@
+/*
+ * Test purpose:
+ *     to show that TF-Fuzz can \"infer\" \"results\"
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t jonathan_set_data[] = "I am the man";
+    static uint32_t jonathan_set_length = 12;
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to show that TF-Fuzz can \"infer\" \"results\"");
+
+
+    /* PSA calls to test: */
+    /\* Creating SST asset "jonathan," with data "I am the m...". \*/
+    sst_status = psa_ps_set\(@@@001@@@, jonathan_set_length, jonathan_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+
+
+    /* Removing assets left over from testing: */
+    psa_ps_remove\(@@@001@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/000003_set_sst_name_data/template b/tf_fuzz/regression/000003_set_sst_name_data/template
new file mode 100644
index 0000000..820e3ab
--- /dev/null
+++ b/tf_fuzz/regression/000003_set_sst_name_data/template
@@ -0,0 +1,2 @@
+purpose to show that TF-Fuzz can "infer" \"results\";
+set sst name jonathan data "I am the man";
diff --git a/tf_fuzz/regression/000004_set_sst_name_rand_data/check.py b/tf_fuzz/regression/000004_set_sst_name_rand_data/check.py
new file mode 100644
index 0000000..1bc5cbe
--- /dev/null
+++ b/tf_fuzz/regression/000004_set_sst_name_rand_data/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000004_set_sst_name_rand_data/exp_stdout_stderr b/tf_fuzz/regression/000004_set_sst_name_rand_data/exp_stdout_stderr
new file mode 100644
index 0000000..916f354
--- /dev/null
+++ b/tf_fuzz/regression/000004_set_sst_name_rand_data/exp_stdout_stderr
@@ -0,0 +1,22 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to show how to randomize data
+ASSET_IDENTIFIER:  "gibberish"
+Asset identifier list:  "data"
+Create from random data
+Set SST command:  "*"
+Appended to end of call sequence:  SST-set call.
+Set command:  "*"
+Command with no expect:  ";"
+Lines:  Line number 3.
+Lines:  Line number 3.
+Call sequence generated.
+Simulating call sequence...
+Call sequence:
+    SST-set call for asset gibberish
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/000004_set_sst_name_rand_data/exp_test.c b/tf_fuzz/regression/000004_set_sst_name_rand_data/exp_test.c
new file mode 100644
index 0000000..2f56e4e
--- /dev/null
+++ b/tf_fuzz/regression/000004_set_sst_name_rand_data/exp_test.c
@@ -0,0 +1,61 @@
+/*
+ * Test purpose:
+ *     to show how to randomize data
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t gibberish_set_data\[\] = "@@002@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t gibberish_set_length = \d+;
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to show how to randomize data");
+
+
+    /* PSA calls to test: */
+    /\* Creating SST asset "gibberish," with data "@@002@10@@...". \*/
+    sst_status = psa_ps_set\(@@@001@@@, gibberish_set_length, gibberish_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+
+
+    /* Removing assets left over from testing: */
+    psa_ps_remove\(@@@001@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/000004_set_sst_name_rand_data/template b/tf_fuzz/regression/000004_set_sst_name_rand_data/template
new file mode 100644
index 0000000..912c23a
--- /dev/null
+++ b/tf_fuzz/regression/000004_set_sst_name_rand_data/template
@@ -0,0 +1,2 @@
+purpose to show how to randomize data;
+set sst name gibberish data *;
diff --git a/tf_fuzz/regression/000005_set_sst_rand_name_rand_data/check.py b/tf_fuzz/regression/000005_set_sst_rand_name_rand_data/check.py
new file mode 100644
index 0000000..1bc5cbe
--- /dev/null
+++ b/tf_fuzz/regression/000005_set_sst_rand_name_rand_data/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000005_set_sst_rand_name_rand_data/exp_stdout_stderr b/tf_fuzz/regression/000005_set_sst_rand_name_rand_data/exp_stdout_stderr
new file mode 100644
index 0000000..5ead6c6
--- /dev/null
+++ b/tf_fuzz/regression/000005_set_sst_rand_name_rand_data/exp_stdout_stderr
@@ -0,0 +1,21 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to show how to randomize name and data
+Asset random identifier:  "*"
+Create from random data
+Set SST command:  "*"
+Appended to end of call sequence:  SST-set call.
+Set command:  "*"
+Command with no expect:  ";"
+Lines:  Line number 3.
+Lines:  Line number 3.
+Call sequence generated.
+Simulating call sequence...
+Call sequence:
+    SST-set call for asset [a-z]+
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/000005_set_sst_rand_name_rand_data/exp_test.c b/tf_fuzz/regression/000005_set_sst_rand_name_rand_data/exp_test.c
new file mode 100644
index 0000000..288cb19
--- /dev/null
+++ b/tf_fuzz/regression/000005_set_sst_rand_name_rand_data/exp_test.c
@@ -0,0 +1,61 @@
+/*
+ * Test purpose:
+ *     to show how to randomize name and data
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t @@@003@@@_set_data\[\] = "@@002@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t @@@003@@@_set_length = \d+;
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to show how to randomize name and data");
+
+
+    /* PSA calls to test: */
+    /\* Creating SST asset "@@@003@@@," with data "@@002@10@@...". \*/
+    sst_status = psa_ps_set\(@@@001@@@, @@@003@@@_set_length, @@@003@@@_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+
+
+    /* Removing assets left over from testing: */
+    psa_ps_remove\(@@@001@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/000005_set_sst_rand_name_rand_data/template b/tf_fuzz/regression/000005_set_sst_rand_name_rand_data/template
new file mode 100644
index 0000000..5290f27
--- /dev/null
+++ b/tf_fuzz/regression/000005_set_sst_rand_name_rand_data/template
@@ -0,0 +1,2 @@
+purpose to show how to randomize name and data;
+set sst name * data *;
diff --git a/tf_fuzz/regression/000006_set_sst_multi_name_rand_data/check.py b/tf_fuzz/regression/000006_set_sst_multi_name_rand_data/check.py
new file mode 100644
index 0000000..1bc5cbe
--- /dev/null
+++ b/tf_fuzz/regression/000006_set_sst_multi_name_rand_data/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000006_set_sst_multi_name_rand_data/exp_stdout_stderr b/tf_fuzz/regression/000006_set_sst_multi_name_rand_data/exp_stdout_stderr
new file mode 100644
index 0000000..4e76308
--- /dev/null
+++ b/tf_fuzz/regression/000006_set_sst_multi_name_rand_data/exp_stdout_stderr
@@ -0,0 +1,34 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to show a nice party trick
+ASSET_IDENTIFIER:  "john"
+ASSET_IDENTIFIER:  "paul"
+ASSET_IDENTIFIER:  "george"
+ASSET_IDENTIFIER:  "and"
+ASSET_IDENTIFIER:  "ringo"
+Asset identifier list:  "data"
+Create from random data
+Set SST command:  "*"
+Appended to end of call sequence:  SST-set call.
+Appended to end of call sequence:  SST-set call.
+Appended to end of call sequence:  SST-set call.
+Appended to end of call sequence:  SST-set call.
+Appended to end of call sequence:  SST-set call.
+Set command:  "*"
+Command with no expect:  ";"
+Lines:  Line number 3.
+Lines:  Line number 3.
+Call sequence generated.
+Simulating call sequence...
+Call sequence:
+    SST-set call for asset john
+    SST-set call for asset paul
+    SST-set call for asset george
+    SST-set call for asset and
+    SST-set call for asset ringo
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/000006_set_sst_multi_name_rand_data/exp_test.c b/tf_fuzz/regression/000006_set_sst_multi_name_rand_data/exp_test.c
new file mode 100644
index 0000000..84026ac
--- /dev/null
+++ b/tf_fuzz/regression/000006_set_sst_multi_name_rand_data/exp_test.c
@@ -0,0 +1,117 @@
+/*
+ * Test purpose:
+ *     to show a nice party trick
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t john_set_data\[\] = "@@012@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t john_set_length = \d+;
+    static uint8_t paul_set_data\[\] = "@@013@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t paul_set_length = \d+;
+    static uint8_t george_set_data\[\] = "@@014@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t george_set_length = \d+;
+    static uint8_t and_set_data\[\] = "@@015@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t and_set_length = \d+;
+    static uint8_t ringo_set_data\[\] = "@@016@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t ringo_set_length = \d+;
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to show a nice party trick");
+
+
+    /* PSA calls to test: */
+    /\* Creating SST asset "john," with data "@@012@10@@...". \*/
+    sst_status = psa_ps_set\(@@@001@@@, john_set_length, john_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    /\* Creating SST asset "paul," with data "@@013@10@@...". \*/
+    sst_status = psa_ps_set\(@@@002@@@, paul_set_length, paul_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    /\* Creating SST asset "george," with data "@@014@10@@...". \*/
+    sst_status = psa_ps_set\(@@@003@@@, george_set_length, george_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    /\* Creating SST asset "and," with data "@@015@10@@...". \*/
+    sst_status = psa_ps_set\(@@@004@@@, and_set_length, and_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    /\* Creating SST asset "ringo," with data "@@016@10@@...". \*/
+    sst_status = psa_ps_set\(@@@005@@@, ringo_set_length, ringo_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+
+
+    /* Removing assets left over from testing: */
+    psa_ps_remove\(@@@001@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+    psa_ps_remove\(@@@002@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+    psa_ps_remove\(@@@003@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+    psa_ps_remove\(@@@004@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+    psa_ps_remove\(@@@005@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/000006_set_sst_multi_name_rand_data/template b/tf_fuzz/regression/000006_set_sst_multi_name_rand_data/template
new file mode 100644
index 0000000..2e86d75
--- /dev/null
+++ b/tf_fuzz/regression/000006_set_sst_multi_name_rand_data/template
@@ -0,0 +1,2 @@
+purpose to show a nice party trick;
+set sst name john paul george and ringo data *;
diff --git a/tf_fuzz/regression/000007_set_sst_multi_uid_rand_data/check.py b/tf_fuzz/regression/000007_set_sst_multi_uid_rand_data/check.py
new file mode 100644
index 0000000..1bc5cbe
--- /dev/null
+++ b/tf_fuzz/regression/000007_set_sst_multi_uid_rand_data/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000007_set_sst_multi_uid_rand_data/exp_stdout_stderr b/tf_fuzz/regression/000007_set_sst_multi_uid_rand_data/exp_stdout_stderr
new file mode 100644
index 0000000..5e9e362
--- /dev/null
+++ b/tf_fuzz/regression/000007_set_sst_multi_uid_rand_data/exp_stdout_stderr
@@ -0,0 +1,37 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  same with UIDs
+ASSET_NUMBER:  "17"
+ASSET_NUMBER:  "19"
+ASSET_NUMBER:  "24"
+ASSET_NUMBER:  "31"
+ASSET_NUMBER:  "34"
+ASSET_NUMBER:  "41"
+SST-asset UID list:  "data"
+Create from random data
+Set SST command:  "*"
+Appended to end of call sequence:  SST-set call.
+Appended to end of call sequence:  SST-set call.
+Appended to end of call sequence:  SST-set call.
+Appended to end of call sequence:  SST-set call.
+Appended to end of call sequence:  SST-set call.
+Appended to end of call sequence:  SST-set call.
+Set command:  "*"
+Command with no expect:  ";"
+Lines:  Line number 3.
+Lines:  Line number 3.
+Call sequence generated.
+Simulating call sequence...
+Call sequence:
+    SST-set call for asset SST_ID_17
+    SST-set call for asset SST_ID_19
+    SST-set call for asset SST_ID_24
+    SST-set call for asset SST_ID_31
+    SST-set call for asset SST_ID_34
+    SST-set call for asset SST_ID_41
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/000007_set_sst_multi_uid_rand_data/exp_test.c b/tf_fuzz/regression/000007_set_sst_multi_uid_rand_data/exp_test.c
new file mode 100644
index 0000000..02055e8
--- /dev/null
+++ b/tf_fuzz/regression/000007_set_sst_multi_uid_rand_data/exp_test.c
@@ -0,0 +1,131 @@
+/*
+ * Test purpose:
+ *     same with UIDs
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t SST_ID_17_set_data\[\] = "@@012@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t SST_ID_17_set_length = \d+;
+    static uint8_t SST_ID_19_set_data\[\] = "@@013@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t SST_ID_19_set_length = \d+;
+    static uint8_t SST_ID_24_set_data\[\] = "@@014@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t SST_ID_24_set_length = \d+;
+    static uint8_t SST_ID_31_set_data\[\] = "@@015@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t SST_ID_31_set_length = \d+;
+    static uint8_t SST_ID_34_set_data\[\] = "@@016@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t SST_ID_34_set_length = \d+;
+    static uint8_t SST_ID_41_set_data\[\] = "@@017@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t SST_ID_41_set_length = \d+;
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test same with UIDs");
+
+
+    /* PSA calls to test: */
+    /\* Creating SST asset UID = 17 with data "@@012@10@@...". \*/
+    sst_status = psa_ps_set(17, SST_ID_17_set_length, SST_ID_17_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    /\* Creating SST asset UID = 19 with data "@@013@10@@...". \*/
+    sst_status = psa_ps_set(19, SST_ID_19_set_length, SST_ID_19_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    /\* Creating SST asset UID = 24 with data "@@014@10@@...". \*/
+    sst_status = psa_ps_set(24, SST_ID_24_set_length, SST_ID_24_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    /\* Creating SST asset UID = 31 with data "@@015@10@@...". \*/
+    sst_status = psa_ps_set(31, SST_ID_31_set_length, SST_ID_31_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    /\* Creating SST asset UID = 34 with data "@@016@10@@...". \*/
+    sst_status = psa_ps_set(34, SST_ID_34_set_length, SST_ID_34_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    /\* Creating SST asset UID = 41 with data "@@017@10@@...". \*/
+    sst_status = psa_ps_set(41, SST_ID_41_set_length, SST_ID_41_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+
+
+    /* Removing assets left over from testing: */
+    psa_ps_remove(17);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+    psa_ps_remove(19);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+    psa_ps_remove(24);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+    psa_ps_remove(31);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+    psa_ps_remove(34);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+    psa_ps_remove(41);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/000007_set_sst_multi_uid_rand_data/template b/tf_fuzz/regression/000007_set_sst_multi_uid_rand_data/template
new file mode 100644
index 0000000..903027e
--- /dev/null
+++ b/tf_fuzz/regression/000007_set_sst_multi_uid_rand_data/template
@@ -0,0 +1,2 @@
+purpose same with UIDs;
+set sst uid 17 19 24 31 34 41 data *;
diff --git a/tf_fuzz/regression/000008_set_sst_name_rand_data_read_check_wrong/check.py b/tf_fuzz/regression/000008_set_sst_name_rand_data_read_check_wrong/check.py
new file mode 100644
index 0000000..1bc5cbe
--- /dev/null
+++ b/tf_fuzz/regression/000008_set_sst_name_rand_data_read_check_wrong/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000008_set_sst_name_rand_data_read_check_wrong/exp_stdout_stderr b/tf_fuzz/regression/000008_set_sst_name_rand_data_read_check_wrong/exp_stdout_stderr
new file mode 100644
index 0000000..a138dc4
--- /dev/null
+++ b/tf_fuzz/regression/000008_set_sst_name_rand_data_read_check_wrong/exp_stdout_stderr
@@ -0,0 +1,34 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to create and show an asset
+ASSET_IDENTIFIER:  "snortwaggle"
+Asset identifier list:  "data"
+Create from random data
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "snortwaggle"
+Asset identifier list:  "check"
+LITERAL string:  "almost certainly not *this*"
+Read check against literal:  "almost certainly not *this*"
+SST-read arguments:  expect"
+Read SST command:  "expect"
+Appended to end of call sequence:  SST-get call.
+Read command:  "expect"
+Expect fail clause:  "fail"
+Command with expect:  ";"
+Lines:  Line number 4.
+Lines:  Line number 4.
+Lines:  Line number 4.
+Call sequence generated.
+Simulating call sequence...
+Call sequence:
+    SST-set call for asset snortwaggle
+    SST-get call for asset snortwaggle
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/000008_set_sst_name_rand_data_read_check_wrong/exp_test.c b/tf_fuzz/regression/000008_set_sst_name_rand_data_read_check_wrong/exp_test.c
new file mode 100644
index 0000000..5f8486c
--- /dev/null
+++ b/tf_fuzz/regression/000008_set_sst_name_rand_data_read_check_wrong/exp_test.c
@@ -0,0 +1,76 @@
+/*
+ * Test purpose:
+ *     to create and show an asset
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t snortwaggle_set_data\[\] = "@@002@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t snortwaggle_set_length = \d+;
+    static uint8_t snortwaggle_exp_data[] = "almost certainly not *this*";
+    static uint8_t snortwaggle_act_data\[2048\] = "[A-Z][a-z ]*[\.\?\!]";
+    static size_t snortwaggle_act_length = \d+;
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to create and show an asset");
+
+
+    /* PSA calls to test: */
+    /\* Creating SST asset "snortwaggle," with data "@@002@10@@...". \*/
+    sst_status = psa_ps_set\(@@@001@@@, snortwaggle_set_length, snortwaggle_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    sst_status = psa_ps_get\(@@@001@@@, 0, @@@003@@@, snortwaggle_act_data
+                            &snortwaggle_act_length);
+    if (sst_status == PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_get() expected not PSA_SUCCESS.");
+        return;
+    }
+    /* Check that the data is correct */
+    if \(tfm_memcmp\(snortwaggle_act_data, snortwaggle_exp_data, 
+                   snortwaggle_act_length\) != 0\) {
+        TEST_FAIL("Read data should be equal to result data");
+        return;
+    }
+
+
+    /* Removing assets left over from testing: */
+    psa_ps_remove\(@@@001@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/000008_set_sst_name_rand_data_read_check_wrong/template b/tf_fuzz/regression/000008_set_sst_name_rand_data_read_check_wrong/template
new file mode 100644
index 0000000..03b22d9
--- /dev/null
+++ b/tf_fuzz/regression/000008_set_sst_name_rand_data_read_check_wrong/template
@@ -0,0 +1,3 @@
+purpose to create and show an asset;
+set sst name snortwaggle data *;
+read sst name snortwaggle check "almost certainly not *this*" expect fail;
diff --git a/tf_fuzz/regression/000009_set_sst_name_rand_data_read_check_var_read_print/check.py b/tf_fuzz/regression/000009_set_sst_name_rand_data_read_check_var_read_print/check.py
new file mode 100644
index 0000000..1bc5cbe
--- /dev/null
+++ b/tf_fuzz/regression/000009_set_sst_name_rand_data_read_check_var_read_print/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000009_set_sst_name_rand_data_read_check_var_read_print/exp_stdout_stderr b/tf_fuzz/regression/000009_set_sst_name_rand_data_read_check_var_read_print/exp_stdout_stderr
new file mode 100644
index 0000000..844cb17
--- /dev/null
+++ b/tf_fuzz/regression/000009_set_sst_name_rand_data_read_check_var_read_print/exp_stdout_stderr
@@ -0,0 +1,44 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to check against a variable or dump into the log
+ASSET_IDENTIFIER:  "greebledorf"
+Asset identifier list:  "data"
+Create from random data
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "greebledorf"
+Asset identifier list:  "chk"
+IDENTIFIER:  "a_variable"
+Read-arguments variable name:  "a_variable"
+Read check against variable:  "a_variable"
+SST-read arguments:  ;"
+Read SST command:  ";"
+Appended to end of call sequence:  SST-get call.
+Read command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "greebledorf"
+Asset identifier list:  "print"
+Read log to test log:  "print"
+SST-read arguments:  ;"
+Read SST command:  ";"
+Appended to end of call sequence:  SST-get call.
+Read command:  ";"
+Command with no expect:  ";"
+Lines:  Line number 5.
+Lines:  Line number 5.
+Lines:  Line number 5.
+Lines:  Line number 5.
+Call sequence generated.
+Simulating call sequence...
+Call sequence:
+    SST-set call for asset greebledorf
+    SST-get call for asset greebledorf
+    SST-get call for asset greebledorf
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/000009_set_sst_name_rand_data_read_check_var_read_print/exp_test.c b/tf_fuzz/regression/000009_set_sst_name_rand_data_read_check_var_read_print/exp_test.c
new file mode 100644
index 0000000..f745c1f
--- /dev/null
+++ b/tf_fuzz/regression/000009_set_sst_name_rand_data_read_check_var_read_print/exp_test.c
@@ -0,0 +1,83 @@
+/*
+ * Test purpose:
+ *     to check against a variable or dump into the log
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t greebledorf_set_data\[\] = "@@002@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t greebledorf_set_length = \d+;
+    static uint8_t a_variable_data\[\] = "[A-Z][a-z ]*[\.\?\!]";
+    static uint8_t greebledorf_act_data\[2048\] = "[A-Z][a-z ]*[\.\?\!]";
+    static size_t greebledorf_act_length = \d+;
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to check against a variable or dump into the log");
+
+
+    /* PSA calls to test: */
+    /\* Creating SST asset "greebledorf," with data "@@002@10@@...". \*/
+    sst_status = psa_ps_set\(@@@001@@@, greebledorf_set_length, greebledorf_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    sst_status = psa_ps_get\(@@@001@@@, 0, \d+, greebledorf_act_data,
+                            &greebledorf_act_length);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_get() expected PSA_SUCCESS.");
+        return;
+    }
+    /* Check that the data is correct */
+    if (tfm_memcmp(greebledorf_act_data, a_variable_data,
+                   greebledorf_act_length) != 0) {
+        TEST_FAIL("Read data should be equal to result data");
+        return;
+    }
+    sst_status = psa_ps_get\(@@@001@@@, 0, \d+, greebledorf_act_data,
+                            &greebledorf_act_length);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_get() expected PSA_SUCCESS.");
+        return;
+    }
+    TEST_LOG\(\"greebledorf_act_data\"\);
+
+
+    /* Removing assets left over from testing: */
+    psa_ps_remove\(@@@001@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/000009_set_sst_name_rand_data_read_check_var_read_print/template b/tf_fuzz/regression/000009_set_sst_name_rand_data_read_check_var_read_print/template
new file mode 100644
index 0000000..a1a4d61
--- /dev/null
+++ b/tf_fuzz/regression/000009_set_sst_name_rand_data_read_check_var_read_print/template
@@ -0,0 +1,4 @@
+purpose to check against a variable or dump into the log;
+set sst name greebledorf data *;
+read sst name greebledorf chk a_variable;
+read sst name greebledorf print;
diff --git a/tf_fuzz/regression/000010_read_nonexistent_sst_check_string/check.py b/tf_fuzz/regression/000010_read_nonexistent_sst_check_string/check.py
new file mode 100644
index 0000000..1bc5cbe
--- /dev/null
+++ b/tf_fuzz/regression/000010_read_nonexistent_sst_check_string/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000010_read_nonexistent_sst_check_string/exp_stdout_stderr b/tf_fuzz/regression/000010_read_nonexistent_sst_check_string/exp_stdout_stderr
new file mode 100644
index 0000000..b8316fc
--- /dev/null
+++ b/tf_fuzz/regression/000010_read_nonexistent_sst_check_string/exp_stdout_stderr
@@ -0,0 +1,24 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to show what happens when you 'read' a non-existent asset
+ASSET_IDENTIFIER:  "napoleon"
+Asset identifier list:  "check"
+LITERAL string:  "this won't work"
+Read check against literal:  "this won't work"
+SST-read arguments:  ;"
+Read SST command:  ";"
+Appended to end of call sequence:  SST-get call.
+Read command:  ";"
+Command with no expect:  ";"
+Lines:  Line number 3.
+Lines:  Line number 3.
+Call sequence generated.
+Simulating call sequence...
+Call sequence:
+    SST-get call for asset napoleon
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/000010_read_nonexistent_sst_check_string/exp_test.c b/tf_fuzz/regression/000010_read_nonexistent_sst_check_string/exp_test.c
new file mode 100644
index 0000000..2048a69
--- /dev/null
+++ b/tf_fuzz/regression/000010_read_nonexistent_sst_check_string/exp_test.c
@@ -0,0 +1,62 @@
+/*
+ * Test purpose:
+ *     to show what happens when you 'read' a non-existent asset
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t napoleon_exp_data[] = "this won't work";
+    static uint8_t napoleon_act_data\[2048\] = "[A-Z][a-z ]*[\.\?\!]";
+    static size_t napoleon_act_length = \d+;
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to show what happens when you 'read' a non-existent asset");
+
+
+    /* PSA calls to test: */
+    sst_status = psa_ps_get\(\d+, 0, \d+, napoleon_act_data
+                            &napoleon_act_length);
+    if (sst_status != PSA_ERROR_DOES_NOT_EXIST) {
+        TEST_FAIL("psa_ps_get() expected PSA_ERROR_DOES_NOT_EXIST.");
+        return;
+    }
+    /* Check that the data is correct */
+    if \(tfm_memcmp\(napoleon_act_data, napoleon_exp_data, 
+                   napoleon_act_length\) != 0\) {
+        TEST_FAIL("Read data should be equal to result data");
+        return;
+    }
+
+
+    /* Removing assets left over from testing: */
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/000010_read_nonexistent_sst_check_string/template b/tf_fuzz/regression/000010_read_nonexistent_sst_check_string/template
new file mode 100644
index 0000000..3e70099
--- /dev/null
+++ b/tf_fuzz/regression/000010_read_nonexistent_sst_check_string/template
@@ -0,0 +1,2 @@
+purpose to show what happens when you 'read' a non-existent asset;
+read sst name napoleon check "this won't work";
diff --git a/tf_fuzz/regression/000011_read_nonexistent_sst_check_string_expect_pass/check.py b/tf_fuzz/regression/000011_read_nonexistent_sst_check_string_expect_pass/check.py
new file mode 100644
index 0000000..1bc5cbe
--- /dev/null
+++ b/tf_fuzz/regression/000011_read_nonexistent_sst_check_string_expect_pass/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000011_read_nonexistent_sst_check_string_expect_pass/exp_stdout_stderr b/tf_fuzz/regression/000011_read_nonexistent_sst_check_string_expect_pass/exp_stdout_stderr
new file mode 100644
index 0000000..2a7d593
--- /dev/null
+++ b/tf_fuzz/regression/000011_read_nonexistent_sst_check_string_expect_pass/exp_stdout_stderr
@@ -0,0 +1,25 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to illustrate that you can override TF-Fuzz's expected result
+ASSET_IDENTIFIER:  "napoleon"
+Asset identifier list:  "chk"
+LITERAL string:  "this won't work"
+Read check against literal:  "this won't work"
+SST-read arguments:  expect"
+Read SST command:  "expect"
+Appended to end of call sequence:  SST-get call.
+Read command:  "expect"
+Expect pass clause:  "pass"
+Command with expect:  ";"
+Lines:  Line number 3.
+Lines:  Line number 3.
+Call sequence generated.
+Simulating call sequence...
+Call sequence:
+    SST-get call for asset napoleon
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/000011_read_nonexistent_sst_check_string_expect_pass/exp_test.c b/tf_fuzz/regression/000011_read_nonexistent_sst_check_string_expect_pass/exp_test.c
new file mode 100644
index 0000000..d5d3e40
--- /dev/null
+++ b/tf_fuzz/regression/000011_read_nonexistent_sst_check_string_expect_pass/exp_test.c
@@ -0,0 +1,62 @@
+/*
+ * Test purpose:
+ *     to illustrate that you can override TF-Fuzz's expected result
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t napoleon_exp_data[] = "this won't work";
+    static uint8_t napoleon_act_data\[2048\] = "[A-Z][a-z ]*[\.\?\!]";
+    static size_t napoleon_act_length = \d+;
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to illustrate that you can override TF-Fuzz's expected result");
+
+
+    /* PSA calls to test: */
+    sst_status = psa_ps_get\(\d+, 0, @@@001@@@, napoleon_act_data,
+                            &napoleon_act_length);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_get() expected PSA_SUCCESS.");
+        return;
+    }
+    /* Check that the data is correct */
+    if \(tfm_memcmp\(napoleon_act_data, napoleon_exp_data, 
+                   napoleon_act_length\) != 0\) \{
+        TEST_FAIL("Read data should be equal to result data");
+        return;
+    }
+
+
+    /* Removing assets left over from testing: */
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/000011_read_nonexistent_sst_check_string_expect_pass/template b/tf_fuzz/regression/000011_read_nonexistent_sst_check_string_expect_pass/template
new file mode 100644
index 0000000..6372bad
--- /dev/null
+++ b/tf_fuzz/regression/000011_read_nonexistent_sst_check_string_expect_pass/template
@@ -0,0 +1,2 @@
+purpose to illustrate that you can override TF-Fuzz's expected result;
+read sst name napoleon chk "this won't work" expect pass;
diff --git a/tf_fuzz/regression/000012_read_nonexistent_sst_check_string_expect_other/check.py b/tf_fuzz/regression/000012_read_nonexistent_sst_check_string_expect_other/check.py
new file mode 100644
index 0000000..1bc5cbe
--- /dev/null
+++ b/tf_fuzz/regression/000012_read_nonexistent_sst_check_string_expect_other/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000012_read_nonexistent_sst_check_string_expect_other/exp_stdout_stderr b/tf_fuzz/regression/000012_read_nonexistent_sst_check_string_expect_other/exp_stdout_stderr
new file mode 100644
index 0000000..44bc211
--- /dev/null
+++ b/tf_fuzz/regression/000012_read_nonexistent_sst_check_string_expect_other/exp_stdout_stderr
@@ -0,0 +1,26 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to more-specifically override TF-Fuzz's expected result
+ASSET_IDENTIFIER:  "napoleon"
+Asset identifier list:  "check"
+LITERAL string:  "this won't work"
+Read check against literal:  "this won't work"
+SST-read arguments:  expect"
+Read SST command:  "expect"
+Appended to end of call sequence:  SST-get call.
+Read command:  "expect"
+IDENTIFIER:  "PSA_ERROR_GENERIC_ERROR"
+Expect error clause:  "PSA_ERROR_GENERIC_ERROR"
+Command with expect:  ";"
+Lines:  Line number 3.
+Lines:  Line number 3.
+Call sequence generated.
+Simulating call sequence...
+Call sequence:
+    SST-get call for asset napoleon
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/000012_read_nonexistent_sst_check_string_expect_other/exp_test.c b/tf_fuzz/regression/000012_read_nonexistent_sst_check_string_expect_other/exp_test.c
new file mode 100644
index 0000000..359dd8a
--- /dev/null
+++ b/tf_fuzz/regression/000012_read_nonexistent_sst_check_string_expect_other/exp_test.c
@@ -0,0 +1,62 @@
+/*
+ * Test purpose:
+ *     to more-specifically override TF-Fuzz's expected result
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t napoleon_exp_data[] = "this won't work";
+    static uint8_t napoleon_act_data\[2048\] = "[A-Z][a-z ]*[\.\?\!]";
+    static size_t napoleon_act_length = \d+;
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to more-specifically override TF-Fuzz's expected result");
+
+
+    /* PSA calls to test: */
+    sst_status = psa_ps_get\(\d+, 0, @@@001@@@, napoleon_act_data,
+                            &napoleon_act_length);
+    if (sst_status != PSA_ERROR_GENERIC_ERROR) {
+        TEST_FAIL("psa_ps_get() expected PSA_ERROR_GENERIC_ERROR.");
+        return;
+    }
+    /* Check that the data is correct */
+    if \(tfm_memcmp\(napoleon_act_data, napoleon_exp_data, 
+                   napoleon_act_length\) != 0\) \{
+        TEST_FAIL("Read data should be equal to result data");
+        return;
+    }
+
+
+    /* Removing assets left over from testing: */
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/000012_read_nonexistent_sst_check_string_expect_other/template b/tf_fuzz/regression/000012_read_nonexistent_sst_check_string_expect_other/template
new file mode 100644
index 0000000..c7825c5
--- /dev/null
+++ b/tf_fuzz/regression/000012_read_nonexistent_sst_check_string_expect_other/template
@@ -0,0 +1,2 @@
+purpose to more-specifically override TF-Fuzz's expected result;
+read sst name napoleon check "this won't work" expect PSA_ERROR_GENERIC_ERROR;
diff --git a/tf_fuzz/regression/000013_set_sst_name_rand_data_remove_twice/check.py b/tf_fuzz/regression/000013_set_sst_name_rand_data_remove_twice/check.py
new file mode 100644
index 0000000..1bc5cbe
--- /dev/null
+++ b/tf_fuzz/regression/000013_set_sst_name_rand_data_remove_twice/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000013_set_sst_name_rand_data_remove_twice/exp_stdout_stderr b/tf_fuzz/regression/000013_set_sst_name_rand_data_remove_twice/exp_stdout_stderr
new file mode 100644
index 0000000..f10b04d
--- /dev/null
+++ b/tf_fuzz/regression/000013_set_sst_name_rand_data_remove_twice/exp_stdout_stderr
@@ -0,0 +1,38 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to illustrate deleting assets
+ASSET_IDENTIFIER:  "george"
+Asset identifier list:  "data"
+Create from random data
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "george"
+Asset identifier list:  ";"
+Remove SST command:  ";"
+Appended to end of call sequence:  SST-remove call.
+Remove command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "george"
+Asset identifier list:  ";"
+Remove SST command:  ";"
+Appended to end of call sequence:  SST-remove call.
+Remove command:  ";"
+Command with no expect:  ";"
+Lines:  Line number 5.
+Lines:  Line number 5.
+Lines:  Line number 5.
+Lines:  Line number 5.
+Call sequence generated.
+Simulating call sequence...
+Call sequence:
+    SST-set call for asset george
+    SST-remove call for asset george
+    SST-remove call for asset george
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/000013_set_sst_name_rand_data_remove_twice/exp_test.c b/tf_fuzz/regression/000013_set_sst_name_rand_data_remove_twice/exp_test.c
new file mode 100644
index 0000000..efc6bf1
--- /dev/null
+++ b/tf_fuzz/regression/000013_set_sst_name_rand_data_remove_twice/exp_test.c
@@ -0,0 +1,66 @@
+/*
+ * Test purpose:
+ *     to illustrate deleting assets
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t george_set_data\[\] = "@@002@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t george_set_length = \d+;
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to illustrate deleting assets");
+
+
+    /* PSA calls to test: */
+    /\* Creating SST asset "george," with data "@@002@10@@...". \*/
+    sst_status = psa_ps_set\(@@@001@@@, george_set_length, george_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    sst_status = psa_ps_remove\(@@@001@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_remove() expected PSA_SUCCESS.");
+        return;
+    }
+    sst_status = psa_ps_remove\(@@@001@@@\);
+    if (sst_status != PSA_ERROR_DOES_NOT_EXIST) {
+        TEST_FAIL("psa_ps_remove() expected PSA_ERROR_DOES_NOT_EXIST.");
+        return;
+    }
+
+
+    /* Removing assets left over from testing: */
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/000013_set_sst_name_rand_data_remove_twice/template b/tf_fuzz/regression/000013_set_sst_name_rand_data_remove_twice/template
new file mode 100644
index 0000000..7edb72e
--- /dev/null
+++ b/tf_fuzz/regression/000013_set_sst_name_rand_data_remove_twice/template
@@ -0,0 +1,4 @@
+purpose to illustrate deleting assets;
+set sst name george data *;
+remove sst name george;
+rm sst name george;
diff --git a/tf_fuzz/regression/000014_set_sst_name_rand_data_remove_other/check.py b/tf_fuzz/regression/000014_set_sst_name_rand_data_remove_other/check.py
new file mode 100644
index 0000000..1bc5cbe
--- /dev/null
+++ b/tf_fuzz/regression/000014_set_sst_name_rand_data_remove_other/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000014_set_sst_name_rand_data_remove_other/exp_stdout_stderr b/tf_fuzz/regression/000014_set_sst_name_rand_data_remove_other/exp_stdout_stderr
new file mode 100644
index 0000000..1c447b7
--- /dev/null
+++ b/tf_fuzz/regression/000014_set_sst_name_rand_data_remove_other/exp_stdout_stderr
@@ -0,0 +1,30 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to remove something that doesn't exist
+ASSET_IDENTIFIER:  "george"
+Asset identifier list:  "data"
+Create from random data
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "ringo"
+Asset identifier list:  ";"
+Remove SST command:  ";"
+Appended to end of call sequence:  SST-remove call.
+Remove command:  ";"
+Command with no expect:  ";"
+Lines:  Line number 4.
+Lines:  Line number 4.
+Lines:  Line number 4.
+Call sequence generated.
+Simulating call sequence...
+Call sequence:
+    SST-set call for asset george
+    SST-remove call for asset ringo
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/000014_set_sst_name_rand_data_remove_other/exp_test.c b/tf_fuzz/regression/000014_set_sst_name_rand_data_remove_other/exp_test.c
new file mode 100644
index 0000000..85d51bb
--- /dev/null
+++ b/tf_fuzz/regression/000014_set_sst_name_rand_data_remove_other/exp_test.c
@@ -0,0 +1,66 @@
+/*
+ * Test purpose:
+ *     to remove something that doesn't exist
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t george_set_data\[\] = "@@002@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t george_set_length = \d+;
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to remove something that doesn't exist");
+
+
+    /* PSA calls to test: */
+    /\* Creating SST asset "george," with data "@@002@10@@...". \*/
+    sst_status = psa_ps_set\(@@@001@@@, george_set_length, george_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    sst_status = psa_ps_remove\(\d+\);
+    if (sst_status != PSA_ERROR_DOES_NOT_EXIST) {
+        TEST_FAIL("psa_ps_remove() expected PSA_ERROR_DOES_NOT_EXIST.");
+        return;
+    }
+
+
+    /* Removing assets left over from testing: */
+    psa_ps_remove\(@@@001@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/000014_set_sst_name_rand_data_remove_other/template b/tf_fuzz/regression/000014_set_sst_name_rand_data_remove_other/template
new file mode 100644
index 0000000..5b9485c
--- /dev/null
+++ b/tf_fuzz/regression/000014_set_sst_name_rand_data_remove_other/template
@@ -0,0 +1,3 @@
+purpose to remove something that doesn't exist;
+set sst name george data *;
+remove sst name ringo;
diff --git a/tf_fuzz/regression/000015_set_sst_name_only/check.py b/tf_fuzz/regression/000015_set_sst_name_only/check.py
new file mode 100644
index 0000000..1bc5cbe
--- /dev/null
+++ b/tf_fuzz/regression/000015_set_sst_name_only/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000015_set_sst_name_only/exp_stdout_stderr b/tf_fuzz/regression/000015_set_sst_name_only/exp_stdout_stderr
new file mode 100644
index 0000000..318a125
--- /dev/null
+++ b/tf_fuzz/regression/000015_set_sst_name_only/exp_stdout_stderr
@@ -0,0 +1,30 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to show that if you don't have say anything about data to randomize it
+ASSET_IDENTIFIER:  "random"
+Asset identifier list:  ";"
+SST-create from random data (no 'data *')
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+Asset random identifier:  "*"
+SST-create from random data (no 'data *')
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+Lines:  Line number 4.
+Lines:  Line number 4.
+Lines:  Line number 4.
+Call sequence generated.
+Simulating call sequence...
+Call sequence:
+    SST-set call for asset random
+    SST-set call for asset [a-z]+
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/000015_set_sst_name_only/exp_test.c b/tf_fuzz/regression/000015_set_sst_name_only/exp_test.c
new file mode 100644
index 0000000..900d9e2
--- /dev/null
+++ b/tf_fuzz/regression/000015_set_sst_name_only/exp_test.c
@@ -0,0 +1,75 @@
+/*
+ * Test purpose:
+ *     to show that if you don't have say anything about data to randomize it
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t random_set_data\[\] = "@@002@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t random_set_length = \d+;
+    static uint8_t @@@003@@@_set_data\[\] = "@@004@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t @@@003@@@_set_length = \d+;
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to show that if you don't have say anything about data to randomize it");
+
+
+    /* PSA calls to test: */
+    /\* Creating SST asset "random," with data "@@002@10@@...". \*/
+    sst_status = psa_ps_set\(@@@001@@@, random_set_length, random_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    /\* Creating SST asset "@@@003@@@," with data "@@004@10@@...". \*/
+    sst_status = psa_ps_set\(@@@004@@@, @@@003@@@_set_length, @@@003@@@_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+
+
+    /* Removing assets left over from testing: */
+    psa_ps_remove\(@@@001@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+    psa_ps_remove\(@@@004@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/000015_set_sst_name_only/template b/tf_fuzz/regression/000015_set_sst_name_only/template
new file mode 100644
index 0000000..63220db
--- /dev/null
+++ b/tf_fuzz/regression/000015_set_sst_name_only/template
@@ -0,0 +1,3 @@
+purpose to show that if you don't have say anything about data to randomize it;
+set sst name random;
+set sst name *;
diff --git a/tf_fuzz/regression/000016_set_sst_single_asset_set_multiple_times/check.py b/tf_fuzz/regression/000016_set_sst_single_asset_set_multiple_times/check.py
new file mode 100644
index 0000000..1bc5cbe
--- /dev/null
+++ b/tf_fuzz/regression/000016_set_sst_single_asset_set_multiple_times/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000016_set_sst_single_asset_set_multiple_times/exp_stdout_stderr b/tf_fuzz/regression/000016_set_sst_single_asset_set_multiple_times/exp_stdout_stderr
new file mode 100644
index 0000000..a85de7d
--- /dev/null
+++ b/tf_fuzz/regression/000016_set_sst_single_asset_set_multiple_times/exp_stdout_stderr
@@ -0,0 +1,66 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to assign a sequence of values to a single asset
+ASSET_IDENTIFIER:  "indecisive"
+Asset identifier list:  "data"
+LITERAL string:  "First value"
+Create from literal data:  ""First value""
+SST no storage flag:  none"
+SST creation flag
+;"
+SST creation flags
+;"
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "indecisive"
+Asset identifier list:  "data"
+LITERAL string:  "Second value"
+Create from literal data:  ""Second value""
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "indecisive"
+Asset identifier list:  "data"
+Create from random data
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "indecisive"
+Asset identifier list:  "data"
+LITERAL string:  "Fourth value"
+Create from literal data:  ""Fourth value""
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "indecisive"
+Asset identifier list:  "data"
+Create from random data
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+Lines:  Line number 7.
+Lines:  Line number 7.
+Lines:  Line number 7.
+Lines:  Line number 7.
+Lines:  Line number 7.
+Lines:  Line number 7.
+Call sequence generated.
+Simulating call sequence...
+Call sequence:
+    SST-set call for asset indecisive
+    SST-set call for asset indecisive
+    SST-set call for asset indecisive
+    SST-set call for asset indecisive
+    SST-set call for asset indecisive
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/000016_set_sst_single_asset_set_multiple_times/exp_test.c b/tf_fuzz/regression/000016_set_sst_single_asset_set_multiple_times/exp_test.c
new file mode 100644
index 0000000..224c85c
--- /dev/null
+++ b/tf_fuzz/regression/000016_set_sst_single_asset_set_multiple_times/exp_test.c
@@ -0,0 +1,97 @@
+/*
+ * Test purpose:
+ *     to assign a sequence of values to a single asset
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t indecisive_set_data[] = "First value";
+    static uint32_t indecisive_set_length = 11;
+    static uint8_t indecisive_set_data_1[] = "Second value";
+    static uint32_t indecisive_set_length_1 = 12;
+    static uint8_t indecisive_set_data_2\[\] = "@@001@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t indecisive_set_length_2 = \d+;
+    static uint8_t indecisive_set_data_3[] = "Fourth value";
+    static uint32_t indecisive_set_length_3 = 12;
+    static uint8_t indecisive_set_data_4\[\] = "@@002@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t indecisive_set_length_4 = \d+;
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to assign a sequence of values to a single asset");
+
+
+    /* PSA calls to test: */
+    /* Creating SST asset "indecisive," with data "First valu...". */
+    sst_status = psa_ps_set\(@@@001@@@, indecisive_set_length, indecisive_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    /* Resetting SST asset "indecisive," with data "Second val...". */
+    sst_status = psa_ps_set\(@@@001@@@, indecisive_set_length_1, indecisive_set_data_1,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    /\* Resetting SST asset "indecisive," with data "@@001@10@@...". \*/
+    sst_status = psa_ps_set\(@@@001@@@, indecisive_set_length_2, indecisive_set_data_2,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    /* Resetting SST asset "indecisive," with data "Fourth val...". */
+    sst_status = psa_ps_set\(@@@001@@@, indecisive_set_length_3, indecisive_set_data_3,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    /\* Resetting SST asset "indecisive," with data "@@002@10@@...". \*/
+    sst_status = psa_ps_set\(@@@001@@@, indecisive_set_length_4, indecisive_set_data_4,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+
+
+    /* Removing assets left over from testing: */
+    psa_ps_remove\(@@@001@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/000016_set_sst_single_asset_set_multiple_times/template b/tf_fuzz/regression/000016_set_sst_single_asset_set_multiple_times/template
new file mode 100644
index 0000000..0127a29
--- /dev/null
+++ b/tf_fuzz/regression/000016_set_sst_single_asset_set_multiple_times/template
@@ -0,0 +1,6 @@
+purpose to assign a sequence of values to a single asset;
+set sst name indecisive data "First value" flag none;
+set sst name indecisive data "Second value";
+set sst name indecisive data *;
+set sst name indecisive data "Fourth value";
+set sst name indecisive data *;
diff --git a/tf_fuzz/regression/000017_read_sst_check_single_asset_multiple_times/check.py b/tf_fuzz/regression/000017_read_sst_check_single_asset_multiple_times/check.py
new file mode 100644
index 0000000..1bc5cbe
--- /dev/null
+++ b/tf_fuzz/regression/000017_read_sst_check_single_asset_multiple_times/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000017_read_sst_check_single_asset_multiple_times/exp_stdout_stderr b/tf_fuzz/regression/000017_read_sst_check_single_asset_multiple_times/exp_stdout_stderr
new file mode 100644
index 0000000..990480d
--- /dev/null
+++ b/tf_fuzz/regression/000017_read_sst_check_single_asset_multiple_times/exp_stdout_stderr
@@ -0,0 +1,68 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to read the value of a single asset multiple times
+ASSET_IDENTIFIER:  "just_checking"
+Asset identifier list:  "data"
+Create from random data
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "just_checking"
+Asset identifier list:  "check"
+LITERAL string:  "Not this"
+Read check against literal:  "Not this"
+SST-read arguments:  expect"
+Read SST command:  "expect"
+Appended to end of call sequence:  SST-get call.
+Read command:  "expect"
+Expect fail clause:  "fail"
+Command with expect:  ";"
+ASSET_IDENTIFIER:  "just_checking"
+Asset identifier list:  "check"
+LITERAL string:  "Not this either"
+Read check against literal:  "Not this either"
+SST-read arguments:  expect"
+Read SST command:  "expect"
+Appended to end of call sequence:  SST-get call.
+Read command:  "expect"
+Expect fail clause:  "fail"
+Command with expect:  ";"
+ASSET_IDENTIFIER:  "just_checking"
+Asset identifier list:  "check"
+LITERAL string:  "No dice on this either"
+Read check against literal:  "No dice on this either"
+SST-read arguments:  expect"
+Read SST command:  "expect"
+Appended to end of call sequence:  SST-get call.
+Read command:  "expect"
+Expect fail clause:  "fail"
+Command with expect:  ";"
+ASSET_IDENTIFIER:  "just_checking"
+Asset identifier list:  "print"
+Read log to test log:  "print"
+SST-read arguments:  ;"
+Read SST command:  ";"
+Appended to end of call sequence:  SST-get call.
+Read command:  ";"
+Command with no expect:  ";"
+Lines:  Line number 8.
+Lines:  Line number 8.
+Lines:  Line number 8.
+Lines:  Line number 8.
+Lines:  Line number 8.
+Lines:  Line number 8.
+Call sequence generated.
+Simulating call sequence...
+Call sequence:
+    SST-set call for asset just_checking
+    SST-get call for asset just_checking
+    SST-get call for asset just_checking
+    SST-get call for asset just_checking
+    SST-get call for asset just_checking
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/000017_read_sst_check_single_asset_multiple_times/exp_test.c b/tf_fuzz/regression/000017_read_sst_check_single_asset_multiple_times/exp_test.c
new file mode 100644
index 0000000..aa333ab
--- /dev/null
+++ b/tf_fuzz/regression/000017_read_sst_check_single_asset_multiple_times/exp_test.c
@@ -0,0 +1,109 @@
+/*
+ * Test purpose:
+ *     to read the value of a single asset multiple times
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t just_checking_set_data\[\] = "@@001@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t just_checking_set_length = \d+;
+    static uint8_t just_checking_exp_data[] = "Not this";
+    static uint8_t just_checking_act_data\[2048\] = "[A-Z][a-z ]*[\.\?\!]";
+    static size_t just_checking_act_length = \d+;
+    static uint8_t just_checking_exp_data_1[] = "Not this either";
+    static uint8_t just_checking_exp_data_2[] = "No dice on this either";
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to read the value of a single asset multiple times");
+
+
+    /* PSA calls to test: */
+    /\* Creating SST asset "just_checking," with data "@@001@10@@...". \*/
+    sst_status = psa_ps_set\(@@@001@@@, just_checking_set_length, just_checking_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    sst_status = psa_ps_get\(@@@001@@@, 0, \d+, just_checking_act_data,
+                            &just_checking_act_length);
+    if (sst_status == PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_get() expected not PSA_SUCCESS.");
+        return;
+    }
+    /* Check that the data is correct */
+    if \(tfm_memcmp\(just_checking_act_data, just_checking_exp_data, 
+                   just_checking_act_length\) != 0\) {
+        TEST_FAIL("Read data should be equal to result data");
+        return;
+    }
+    sst_status = psa_ps_get\(@@@001@@@, 0, \d+, just_checking_act_data,
+                            &just_checking_act_length);
+    if (sst_status == PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_get() expected not PSA_SUCCESS.");
+        return;
+    }
+    /* Check that the data is correct */
+    if \(tfm_memcmp\(just_checking_act_data, just_checking_exp_data_1, 
+                   just_checking_act_length\) != 0\) {
+        TEST_FAIL("Read data should be equal to result data");
+        return;
+    }
+    sst_status = psa_ps_get\(@@@001@@@, 0, \d+, just_checking_act_data,
+                            &just_checking_act_length);
+    if (sst_status == PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_get() expected not PSA_SUCCESS.");
+        return;
+    }
+    /* Check that the data is correct */
+    if \(tfm_memcmp\(just_checking_act_data, just_checking_exp_data_2, 
+                   just_checking_act_length\) != 0\) {
+        TEST_FAIL("Read data should be equal to result data");
+        return;
+    }
+    sst_status = psa_ps_get\(@@@001@@@, 0, \d+, just_checking_act_data,
+                            &just_checking_act_length);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_get() expected PSA_SUCCESS.");
+        return;
+    }
+    TEST_LOG\(\"just_checking_act_data\"\);
+
+
+    /* Removing assets left over from testing: */
+    psa_ps_remove\(@@@001@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/000017_read_sst_check_single_asset_multiple_times/template b/tf_fuzz/regression/000017_read_sst_check_single_asset_multiple_times/template
new file mode 100644
index 0000000..9f10122
--- /dev/null
+++ b/tf_fuzz/regression/000017_read_sst_check_single_asset_multiple_times/template
@@ -0,0 +1,7 @@
+purpose to read the value of a single asset multiple times;
+set sst name just_checking data *;
+// TF-Fuzz needs enhancements to correctly predict the "expect" values below:
+read sst name just_checking check "Not this" expect fail;
+read sst name just_checking check "Not this either" expect fail;
+read sst name just_checking check "No dice on this either" expect fail;
+read sst name just_checking print;
diff --git a/tf_fuzz/regression/000018_000016_and_000017/check.py b/tf_fuzz/regression/000018_000016_and_000017/check.py
new file mode 100644
index 0000000..1bc5cbe
--- /dev/null
+++ b/tf_fuzz/regression/000018_000016_and_000017/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000018_000016_and_000017/exp_stdout_stderr b/tf_fuzz/regression/000018_000016_and_000017/exp_stdout_stderr
new file mode 100644
index 0000000..e9fad8a
--- /dev/null
+++ b/tf_fuzz/regression/000018_000016_and_000017/exp_stdout_stderr
@@ -0,0 +1,121 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to both read the value of a single asset multiple times and assign a sequence of values to a single asset
+ASSET_IDENTIFIER:  "indecisive"
+Asset identifier list:  "data"
+LITERAL string:  "First value"
+Create from literal data:  ""First value""
+SST no storage flag:  none"
+SST creation flag
+;"
+SST creation flags
+;"
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "indecisive"
+Asset identifier list:  "check"
+LITERAL string:  "Not this"
+Read check against literal:  "Not this"
+SST-read arguments:  expect"
+Read SST command:  "expect"
+Appended to end of call sequence:  SST-get call.
+Read command:  "expect"
+Expect fail clause:  "fail"
+Command with expect:  ";"
+ASSET_IDENTIFIER:  "indecisive"
+Asset identifier list:  "data"
+LITERAL string:  "Second value"
+Create from literal data:  ""Second value""
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "indecisive"
+Asset identifier list:  "check"
+LITERAL string:  "Not this either"
+Read check against literal:  "Not this either"
+SST-read arguments:  expect"
+Read SST command:  "expect"
+Appended to end of call sequence:  SST-get call.
+Read command:  "expect"
+Expect fail clause:  "fail"
+Command with expect:  ";"
+ASSET_IDENTIFIER:  "indecisive"
+Asset identifier list:  "data"
+Create from random data
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "indecisive"
+Asset identifier list:  "data"
+LITERAL string:  "Fourth value"
+Create from literal data:  ""Fourth value""
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "indecisive"
+Asset identifier list:  "check"
+LITERAL string:  "No dice on this either"
+Read check against literal:  "No dice on this either"
+SST-read arguments:  expect"
+Read SST command:  "expect"
+Appended to end of call sequence:  SST-get call.
+Read command:  "expect"
+Expect fail clause:  "fail"
+Command with expect:  ";"
+ASSET_IDENTIFIER:  "indecisive"
+Asset identifier list:  "data"
+Create from random data
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "indecisive"
+Asset identifier list:  "data"
+Create from random data
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "indecisive"
+Asset identifier list:  "print"
+Read log to test log:  "print"
+SST-read arguments:  ;"
+Read SST command:  ";"
+Appended to end of call sequence:  SST-get call.
+Read command:  ";"
+Command with no expect:  ";"
+Lines:  Line number 12.
+Lines:  Line number 12.
+Lines:  Line number 12.
+Lines:  Line number 12.
+Lines:  Line number 12.
+Lines:  Line number 12.
+Lines:  Line number 12.
+Lines:  Line number 12.
+Lines:  Line number 12.
+Lines:  Line number 12.
+Lines:  Line number 12.
+Call sequence generated.
+Simulating call sequence...
+Call sequence:
+    SST-set call for asset indecisive
+    SST-get call for asset indecisive
+    SST-set call for asset indecisive
+    SST-get call for asset indecisive
+    SST-set call for asset indecisive
+    SST-set call for asset indecisive
+    SST-get call for asset indecisive
+    SST-set call for asset indecisive
+    SST-set call for asset indecisive
+    SST-get call for asset indecisive
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/000018_000016_and_000017/exp_test.c b/tf_fuzz/regression/000018_000016_and_000017/exp_test.c
new file mode 100644
index 0000000..ca1ba06
--- /dev/null
+++ b/tf_fuzz/regression/000018_000016_and_000017/exp_test.c
@@ -0,0 +1,154 @@
+/*
+ * Test purpose:
+ *     to both read the value of a single asset multiple times and assign a sequence of values to a single asset
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t indecisive_set_data[] = "First value";
+    static uint32_t indecisive_set_length = 11;
+    static uint8_t indecisive_exp_data[] = "Not this";
+    static uint8_t indecisive_act_data\[2048\] = "[A-Z][a-z ]*[\.\?\!]";
+    static size_t indecisive_act_length = \d+;
+    static uint8_t indecisive_set_data_1[] = "Second value";
+    static uint32_t indecisive_set_length_1 = 12;
+    static uint8_t indecisive_exp_data_1[] = "Not this either";
+    static uint8_t indecisive_set_data_2\[\] = "@@001@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t indecisive_set_length_2 = \d+;
+    static uint8_t indecisive_set_data_3[] = "Fourth value";
+    static uint32_t indecisive_set_length_3 = 12;
+    static uint8_t indecisive_exp_data_2[] = "No dice on this either";
+    static uint8_t indecisive_set_data_4\[\] = "@@002@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t indecisive_set_length_4 = \d+;
+    static uint8_t indecisive_set_data_5\[\] = "@@003@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t indecisive_set_length_5 = \d+;
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to both read the value of a single asset multiple times and assign a sequence of values to a single asset");
+
+
+    /* PSA calls to test: */
+    /* Creating SST asset "indecisive," with data "First valu...". */
+    sst_status = psa_ps_set\(@@@001@@@, indecisive_set_length, indecisive_set_data,
+                            PSA_STORAGE_FLAG_NONE);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    sst_status = psa_ps_get\(@@@001@@@, 0, 11, indecisive_act_data,
+                            &indecisive_act_length);
+    if (sst_status == PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_get() expected not PSA_SUCCESS.");
+        return;
+    }
+    /* Check that the data is correct */
+    if (tfm_memcmp(indecisive_act_data, indecisive_exp_data, 
+                   indecisive_act_length\) != 0\) {
+        TEST_FAIL("Read data should be equal to result data");
+        return;
+    }
+    /* Resetting SST asset "indecisive," with data "Second val...". */
+    sst_status = psa_ps_set\(@@@001@@@, indecisive_set_length_1, indecisive_set_data_1,
+                            PSA_STORAGE_FLAG_NONE);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    sst_status = psa_ps_get\(@@@001@@@, 0, 12, indecisive_act_data,
+                            &indecisive_act_length);
+    if (sst_status == PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_get() expected not PSA_SUCCESS.");
+        return;
+    }
+    /* Check that the data is correct */
+    if (tfm_memcmp(indecisive_act_data, indecisive_exp_data_1,
+                   indecisive_act_length) != 0) {
+        TEST_FAIL("Read data should be equal to result data");
+        return;
+    }
+    /\* Resetting SST asset "indecisive," with data "@@001@10@@...". \*/
+    sst_status = psa_ps_set\(@@@001@@@, indecisive_set_length_2, indecisive_set_data_2,
+                            PSA_STORAGE_FLAG_NONE);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    /* Resetting SST asset "indecisive," with data "Fourth val...". */
+    sst_status = psa_ps_set\(@@@001@@@, indecisive_set_length_3, indecisive_set_data_3,
+                            PSA_STORAGE_FLAG_NONE);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    sst_status = psa_ps_get\(@@@001@@@, 0, 12, indecisive_act_data,
+                            &indecisive_act_length);
+    if (sst_status == PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_get() expected not PSA_SUCCESS.");
+        return;
+    }
+    /* Check that the data is correct */
+    if (tfm_memcmp(indecisive_act_data, indecisive_exp_data_2,
+                   indecisive_act_length) != 0) {
+        TEST_FAIL("Read data should be equal to result data");
+        return;
+    }
+    /\* Resetting SST asset "indecisive," with data "@@002@10@@...". \*/
+    sst_status = psa_ps_set\(@@@001@@@, indecisive_set_length_4, indecisive_set_data_4,
+                            PSA_STORAGE_FLAG_NONE);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    /\* Resetting SST asset "indecisive," with data "@@003@10@@...". \*/
+    sst_status = psa_ps_set\(@@@001@@@, indecisive_set_length_5, indecisive_set_data_5,
+                            PSA_STORAGE_FLAG_NONE);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    sst_status = psa_ps_get\(@@@001@@@, 0, \d+, indecisive_act_data,
+                            &indecisive_act_length);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_get() expected PSA_SUCCESS.");
+        return;
+    }
+    TEST_LOG\(\"indecisive_act_data\"\);
+
+
+    /* Removing assets left over from testing: */
+    psa_ps_remove\(@@@001@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/000018_000016_and_000017/template b/tf_fuzz/regression/000018_000016_and_000017/template
new file mode 100644
index 0000000..662a252
--- /dev/null
+++ b/tf_fuzz/regression/000018_000016_and_000017/template
@@ -0,0 +1,11 @@
+purpose to both read the value of a single asset multiple times and assign a sequence of values to a single asset;
+set sst name indecisive data "First value" flag none;
+read sst name indecisive check "Not this" expect fail;
+set sst name indecisive data "Second value";
+read sst name indecisive check "Not this either" expect fail;
+set sst name indecisive data *;
+set sst name indecisive data "Fourth value";
+read sst name indecisive check "No dice on this either" expect fail;
+set sst name indecisive data *;
+set sst name indecisive data *;
+read sst name indecisive print;
diff --git a/tf_fuzz/regression/000019_read_asset_to_variable_set_other_asset/check.py b/tf_fuzz/regression/000019_read_asset_to_variable_set_other_asset/check.py
new file mode 100644
index 0000000..1bc5cbe
--- /dev/null
+++ b/tf_fuzz/regression/000019_read_asset_to_variable_set_other_asset/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000019_read_asset_to_variable_set_other_asset/exp_stdout_stderr b/tf_fuzz/regression/000019_read_asset_to_variable_set_other_asset/exp_stdout_stderr
new file mode 100644
index 0000000..ca4b2ed
--- /dev/null
+++ b/tf_fuzz/regression/000019_read_asset_to_variable_set_other_asset/exp_stdout_stderr
@@ -0,0 +1,76 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to read an asset into a named variable the set another asset from that variable
+ASSET_IDENTIFIER:  "source"
+Asset identifier list:  ";"
+SST-create from random data (no 'data *')
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "source"
+Asset identifier list:  "var"
+IDENTIFIER:  "transfer"
+Read dump to variable:  "transfer"
+SST-read arguments:  ;"
+Read SST command:  ";"
+Appended to end of call sequence:  SST-get call.
+Read command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "intermediate"
+Asset identifier list:  "var"
+IDENTIFIER:  "transfer"
+SST-set set from variable:  "transfer"
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "intermediate"
+Asset identifier list:  "var"
+IDENTIFIER:  "transfer"
+Read dump to variable:  "transfer"
+SST-read arguments:  ;"
+Read SST command:  ";"
+Appended to end of call sequence:  SST-get call.
+Read command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "destination"
+Asset identifier list:  "var"
+IDENTIFIER:  "transfer"
+SST-set set from variable:  "transfer"
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "destination"
+Asset identifier list:  "check"
+IDENTIFIER:  "transfer"
+Read-arguments variable name:  "transfer"
+Read check against variable:  "transfer"
+SST-read arguments:  ;"
+Read SST command:  ";"
+Appended to end of call sequence:  SST-get call.
+Read command:  ";"
+Command with no expect:  ";"
+Lines:  Line number 8.
+Lines:  Line number 8.
+Lines:  Line number 8.
+Lines:  Line number 8.
+Lines:  Line number 8.
+Lines:  Line number 8.
+Lines:  Line number 8.
+Call sequence generated.
+Simulating call sequence...
+Call sequence:
+    SST-set call for asset source
+    SST-get call for asset source
+    SST-set call for asset intermediate
+    SST-get call for asset intermediate
+    SST-set call for asset destination
+    SST-get call for asset destination
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/000019_read_asset_to_variable_set_other_asset/exp_test.c b/tf_fuzz/regression/000019_read_asset_to_variable_set_other_asset/exp_test.c
new file mode 100644
index 0000000..6131299
--- /dev/null
+++ b/tf_fuzz/regression/000019_read_asset_to_variable_set_other_asset/exp_test.c
@@ -0,0 +1,127 @@
+/*
+ * Test purpose:
+ *     to read an asset into a named variable the set another asset from that variable
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t source_set_data\[\] = "@@001@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t source_set_length = @@@004@@@;
+    static uint8_t source_exp_data\[\] = "@@001@10@@[a-z\ ]*[\.\?\!]";
+    static uint8_t transfer_data\[2048\] = "[A-Z][a-z ]*[\.\?\!]";
+    static size_t transfer_length = \d+;
+    static uint8_t intermediate_exp_data\[\] = "@@002@10@@[a-z\ ]*[\.\?\!]";
+    static uint8_t destination_act_data\[2048\] = "[A-Z][a-z ]*[\.\?\!]";
+    static size_t destination_act_length = \d+;
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to read an asset into a named variable the set another asset from that variable");
+
+
+    /* PSA calls to test: */
+    /\* Creating SST asset "source," with data "@@001@10@@...". \*/
+    sst_status = psa_ps_set\(@@@001@@@, source_set_length, source_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    sst_status = psa_ps_get\(@@@001@@@, 0, @@@004@@@, transfer_data,
+                            &transfer_length);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_get() expected PSA_SUCCESS.");
+        return;
+    }
+    /* Check that the data is correct */
+    if (tfm_memcmp(transfer_data, source_exp_data, 
+                   transfer_length) != 0) {
+        TEST_FAIL("Read data should be equal to result data");
+        return;
+    }
+    /\* Creating SST asset "intermediate," with data "@@002@10@@...". \*/
+    sst_status = psa_ps_set\(@@@002@@@, transfer_length, transfer_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    sst_status = psa_ps_get\(@@@002@@@, 0, \d+, transfer_data,
+                            &transfer_length);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_get() expected PSA_SUCCESS.");
+        return;
+    }
+    /* Check that the data is correct */
+    if (tfm_memcmp(transfer_data, intermediate_exp_data, 
+                   transfer_length) != 0) {
+        TEST_FAIL("Read data should be equal to result data");
+        return;
+    }
+    /\* Creating SST asset "destination," with data "[A-Z][a-z ]*...". \*/
+    sst_status = psa_ps_set\(@@@003@@@, transfer_length, transfer_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    sst_status = psa_ps_get\(@@@003@@@, 0, \d+, destination_act_data,
+                            &destination_act_length);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_get() expected PSA_SUCCESS.");
+        return;
+    }
+    /* Check that the data is correct */
+    if (tfm_memcmp(destination_act_data, transfer_data, 
+                   destination_act_length) != 0) {
+        TEST_FAIL("Read data should be equal to result data");
+        return;
+    }
+
+
+    /* Removing assets left over from testing: */
+    psa_ps_remove\(@@@001@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+    psa_ps_remove\(@@@002@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+    psa_ps_remove\(@@@003@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/000019_read_asset_to_variable_set_other_asset/template b/tf_fuzz/regression/000019_read_asset_to_variable_set_other_asset/template
new file mode 100644
index 0000000..0111ba2
--- /dev/null
+++ b/tf_fuzz/regression/000019_read_asset_to_variable_set_other_asset/template
@@ -0,0 +1,7 @@
+purpose to read an asset into a named variable the set another asset from that variable;
+set sst name source;  // shorthand for random data
+read sst name source var transfer;
+set sst name intermediate var transfer;
+read sst name intermediate var transfer;
+set sst name destination var transfer;
+read sst name destination check transfer;
diff --git a/tf_fuzz/regression/000020_no_purpose/check.py b/tf_fuzz/regression/000020_no_purpose/check.py
new file mode 100644
index 0000000..2027be8
--- /dev/null
+++ b/tf_fuzz/regression/000020_no_purpose/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000020_no_purpose/exp_stdout_stderr b/tf_fuzz/regression/000020_no_purpose/exp_stdout_stderr
new file mode 100644
index 0000000..3a87ce6
--- /dev/null
+++ b/tf_fuzz/regression/000020_no_purpose/exp_stdout_stderr
@@ -0,0 +1,17 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+ASSET_NUMBER:  "104"
+SST-asset UID list:  "data"
+LITERAL string:  "Very simple test"
+Create from literal data:  ""Very simple test""
+Set SST command:  "expect"
+Appended to end of call sequence:  SST-set call.
+Set command:  "expect"
+Expect pass clause:  "pass"
+Command with expect:  "
+
+Error:  Please begin your test with the "purpose" directive.  
+        For example, "purpose to exercise crypto and SST..."
diff --git a/tf_fuzz/regression/000020_no_purpose/exp_test.c b/tf_fuzz/regression/000020_no_purpose/exp_test.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tf_fuzz/regression/000020_no_purpose/exp_test.c
diff --git a/tf_fuzz/regression/000020_no_purpose/template b/tf_fuzz/regression/000020_no_purpose/template
new file mode 100644
index 0000000..7b7fd92
--- /dev/null
+++ b/tf_fuzz/regression/000020_no_purpose/template
@@ -0,0 +1,2 @@
+// purpose to make sure it complains if you don't provide a purpose
+set sst uid 104 data "Very simple test" expect pass;
diff --git a/tf_fuzz/regression/000021_abbreviated_result_codes/check.py b/tf_fuzz/regression/000021_abbreviated_result_codes/check.py
new file mode 100644
index 0000000..2027be8
--- /dev/null
+++ b/tf_fuzz/regression/000021_abbreviated_result_codes/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000021_abbreviated_result_codes/exp_stdout_stderr b/tf_fuzz/regression/000021_abbreviated_result_codes/exp_stdout_stderr
new file mode 100644
index 0000000..c4af682
--- /dev/null
+++ b/tf_fuzz/regression/000021_abbreviated_result_codes/exp_stdout_stderr
@@ -0,0 +1,26 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to more-specifically override TF-Fuzz's expected result
+ASSET_IDENTIFIER:  "napoleon"
+Asset identifier list:  "chk"
+LITERAL string:  "this won't work"
+Read check against literal:  "this won't work"
+SST-read arguments:  exp"
+Read SST command:  "exp"
+Appended to end of call sequence:  SST-get call.
+Read command:  "exp"
+IDENTIFIER:  "generic_error"
+Expect error clause:  "generic_error"
+Command with expect:  ";"
+Lines:  Line number 3.
+Lines:  Line number 3.
+Call sequence generated.
+Simulating call sequence...
+Call sequence:
+    SST-get call for asset napoleon
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/000021_abbreviated_result_codes/exp_test.c b/tf_fuzz/regression/000021_abbreviated_result_codes/exp_test.c
new file mode 100644
index 0000000..359dd8a
--- /dev/null
+++ b/tf_fuzz/regression/000021_abbreviated_result_codes/exp_test.c
@@ -0,0 +1,62 @@
+/*
+ * Test purpose:
+ *     to more-specifically override TF-Fuzz's expected result
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t napoleon_exp_data[] = "this won't work";
+    static uint8_t napoleon_act_data\[2048\] = "[A-Z][a-z ]*[\.\?\!]";
+    static size_t napoleon_act_length = \d+;
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to more-specifically override TF-Fuzz's expected result");
+
+
+    /* PSA calls to test: */
+    sst_status = psa_ps_get\(\d+, 0, @@@001@@@, napoleon_act_data,
+                            &napoleon_act_length);
+    if (sst_status != PSA_ERROR_GENERIC_ERROR) {
+        TEST_FAIL("psa_ps_get() expected PSA_ERROR_GENERIC_ERROR.");
+        return;
+    }
+    /* Check that the data is correct */
+    if \(tfm_memcmp\(napoleon_act_data, napoleon_exp_data, 
+                   napoleon_act_length\) != 0\) \{
+        TEST_FAIL("Read data should be equal to result data");
+        return;
+    }
+
+
+    /* Removing assets left over from testing: */
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/000021_abbreviated_result_codes/template b/tf_fuzz/regression/000021_abbreviated_result_codes/template
new file mode 100644
index 0000000..67b05b3
--- /dev/null
+++ b/tf_fuzz/regression/000021_abbreviated_result_codes/template
@@ -0,0 +1,2 @@
+purpose to more-specifically override TF-Fuzz's expected result;
+read sst name napoleon chk "this won't work" exp generic_error;
diff --git a/tf_fuzz/regression/000022_SST_offset/check.py b/tf_fuzz/regression/000022_SST_offset/check.py
new file mode 100644
index 0000000..2027be8
--- /dev/null
+++ b/tf_fuzz/regression/000022_SST_offset/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000022_SST_offset/exp_stdout_stderr b/tf_fuzz/regression/000022_SST_offset/exp_stdout_stderr
new file mode 100644
index 0000000..c9d1a0f
--- /dev/null
+++ b/tf_fuzz/regression/000022_SST_offset/exp_stdout_stderr
@@ -0,0 +1,35 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to set an offset on psa_ps_get()
+ASSET_IDENTIFIER:  "whoNose"
+Asset identifier list:  "data"
+Create from random data
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "whoNose"
+Asset identifier list:  "print"
+Read log to test log:  "print"
+SST-data offset:  "10"
+SST data offset
+10"
+SST-read arguments:  10"
+Read SST command:  "10"
+Appended to end of call sequence:  SST-get call.
+Read command:  "10"
+Command with no expect:  ";"
+Lines:  Line number 4.
+Lines:  Line number 4.
+Lines:  Line number 4.
+Call sequence generated.
+Simulating call sequence...
+Call sequence:
+    SST-set call for asset whoNose
+    SST-get call for asset whoNose
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/000022_SST_offset/exp_test.c b/tf_fuzz/regression/000022_SST_offset/exp_test.c
new file mode 100644
index 0000000..03523dc
--- /dev/null
+++ b/tf_fuzz/regression/000022_SST_offset/exp_test.c
@@ -0,0 +1,70 @@
+/*
+ * Test purpose:
+ *     to set an offset on psa_ps_get()
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t whoNose_set_data\[\] = "@@012@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t whoNose_set_length = \d+;
+    static uint8_t whoNose_act_data\[2048\] = "[A-Z][a-z\ ]*[\.\?\!]";
+    static size_t whoNose_act_length = \d+;
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to set an offset on psa_ps_get()");
+
+
+    /* PSA calls to test: */
+    /\* Creating SST asset "whoNose," with data "@@012@10@@...". \*/
+    sst_status = psa_ps_set\(@@@001@@@, whoNose_set_length, whoNose_set_data,
+                            PSA_STORAGE_FLAG_[A-Z_]+\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    sst_status = psa_ps_get\(@@@001@@@, 10, \d+, whoNose_act_data,
+                            &whoNose_act_length);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_get() expected PSA_SUCCESS.");
+        return;
+    }
+    TEST_LOG\(\"whoNose_act_data\"\);
+
+
+    /* Removing assets left over from testing: */
+    psa_ps_remove\(@@@001@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/000022_SST_offset/template b/tf_fuzz/regression/000022_SST_offset/template
new file mode 100644
index 0000000..9fa46e9
--- /dev/null
+++ b/tf_fuzz/regression/000022_SST_offset/template
@@ -0,0 +1,3 @@
+purpose to set an offset on psa_ps_get();
+set sst name whoNose data *;
+read sst name whoNose print offset 10;
diff --git a/tf_fuzz/regression/000023_SST_creation_flags/check.py b/tf_fuzz/regression/000023_SST_creation_flags/check.py
new file mode 100644
index 0000000..2027be8
--- /dev/null
+++ b/tf_fuzz/regression/000023_SST_creation_flags/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000023_SST_creation_flags/exp_stdout_stderr b/tf_fuzz/regression/000023_SST_creation_flags/exp_stdout_stderr
new file mode 100644
index 0000000..2b6ab80
--- /dev/null
+++ b/tf_fuzz/regression/000023_SST_creation_flags/exp_stdout_stderr
@@ -0,0 +1,89 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to set SST creation flags
+ASSET_IDENTIFIER:  "hasCF"
+Asset identifier list:  "data"
+LITERAL string:  "this asset has write-once"
+Create from literal data:  ""this asset has write-once""
+SST write-once flag:  write_once"
+SST creation flag
+;"
+SST creation flags
+;"
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "hasCF2"
+Asset identifier list:  "data"
+LITERAL string:  "this asset has also write-once"
+Create from literal data:  ""this asset has also write-once""
+SST write-once flag:  wo"
+SST creation flag
+;"
+SST creation flags
+;"
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "alsoHasCF"
+Asset identifier list:  "data"
+LITERAL string:  "this asset has no flags"
+Create from literal data:  ""this asset has no flags""
+SST no storage flag:  none"
+SST creation flag
+expect"
+SST creation flags
+expect"
+Set SST command:  "expect"
+Appended to end of call sequence:  SST-set call.
+Set command:  "expect"
+Expect pass clause:  "pass"
+Command with expect:  ";"
+ASSET_IDENTIFIER:  "alsoHasCF2"
+Asset identifier list:  "data"
+LITERAL string:  "this asset has NO_CONFIDENTIALITY"
+Create from literal data:  ""this asset has NO_CONFIDENTIALITY""
+SST no-confidentiality flag:  ncf"
+SST creation flag
+;"
+SST creation flags
+;"
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "yetAnother"
+Asset identifier list:  "data"
+LITERAL string:  "this asset has NO_REPLAY_PROTECTION"
+Create from literal data:  ""this asset has NO_REPLAY_PROTECTION""
+SST no-replay-protection flag:  nrp"
+SST creation flag
+;"
+SST creation flags
+;"
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+Lines:  Line number 7.
+Lines:  Line number 7.
+Lines:  Line number 7.
+Lines:  Line number 7.
+Lines:  Line number 7.
+Lines:  Line number 7.
+Call sequence generated.
+Simulating call sequence...
+Call sequence:
+    SST-set call for asset hasCF
+    SST-set call for asset hasCF2
+    SST-set call for asset alsoHasCF
+    SST-set call for asset alsoHasCF2
+    SST-set call for asset yetAnother
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/000023_SST_creation_flags/exp_test.c b/tf_fuzz/regression/000023_SST_creation_flags/exp_test.c
new file mode 100644
index 0000000..9dbe4cf
--- /dev/null
+++ b/tf_fuzz/regression/000023_SST_creation_flags/exp_test.c
@@ -0,0 +1,117 @@
+/*
+ * Test purpose:
+ *     to set SST creation flags
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t hasCF_set_data[] = "this asset has write-once";
+    static uint32_t hasCF_set_length = 25;
+    static uint8_t hasCF2_set_data[] = "this asset has also write-once";
+    static uint32_t hasCF2_set_length = 30;
+    static uint8_t alsoHasCF_set_data[] = "this asset has no flags";
+    static uint32_t alsoHasCF_set_length = 23;
+    static uint8_t alsoHasCF2_set_data[] = "this asset has NO_CONFIDENTIALITY";
+    static uint32_t alsoHasCF2_set_length = 33;
+    static uint8_t yetAnother_set_data[] = "this asset has NO_REPLAY_PROTECTION";
+    static uint32_t yetAnother_set_length = 35;
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to set SST creation flags");
+
+
+    /* PSA calls to test: */
+    /* Creating SST asset "hasCF," with data "this asset...". */
+    sst_status = psa_ps_set\(@@@001@@@, hasCF_set_length, hasCF_set_data,
+                            PSA_STORAGE_FLAG_WRITE_ONCE);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    /* Creating SST asset "hasCF2," with data "this asset...". */
+    sst_status = psa_ps_set\(@@@002@@@, hasCF2_set_length, hasCF2_set_data,
+                            PSA_STORAGE_FLAG_WRITE_ONCE);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    /* Creating SST asset "alsoHasCF," with data "this asset...". */
+    sst_status = psa_ps_set\(@@@003@@@, alsoHasCF_set_length, alsoHasCF_set_data,
+                            PSA_STORAGE_FLAG_NONE);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    /* Creating SST asset "alsoHasCF2," with data "this asset...". */
+    sst_status = psa_ps_set\(@@@004@@@, alsoHasCF2_set_length, alsoHasCF2_set_data,
+                            PSA_STORAGE_FLAG_NO_CONFIDENTIALITY);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    /* Creating SST asset "yetAnother," with data "this asset...". */
+    sst_status = psa_ps_set\(@@@005@@@, yetAnother_set_length, yetAnother_set_data,
+                            PSA_STORAGE_FLAG_NO_REPLAY_PROTECTION);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+
+
+    /* Removing assets left over from testing: */
+    psa_ps_remove\(@@@001@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+    psa_ps_remove\(@@@002@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+    psa_ps_remove\(@@@003@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+    psa_ps_remove\(@@@004@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+    psa_ps_remove\(@@@005@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/000023_SST_creation_flags/template b/tf_fuzz/regression/000023_SST_creation_flags/template
new file mode 100644
index 0000000..5cfa287
--- /dev/null
+++ b/tf_fuzz/regression/000023_SST_creation_flags/template
@@ -0,0 +1,6 @@
+purpose to set SST creation flags;
+set sst name hasCF data "this asset has write-once" flag write_once;
+set sst name hasCF2 data "this asset has also write-once" flag wo;
+set sst name alsoHasCF data "this asset has no flags" flag none expect pass;
+set sst name alsoHasCF2 data "this asset has NO_CONFIDENTIALITY" flag ncf;
+set sst name yetAnother data "this asset has NO_REPLAY_PROTECTION" flag nrp;
diff --git a/tf_fuzz/regression/000024_SST_write_once/check.py b/tf_fuzz/regression/000024_SST_write_once/check.py
new file mode 100644
index 0000000..2027be8
--- /dev/null
+++ b/tf_fuzz/regression/000024_SST_write_once/check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+'''
+    Please read .../tf_fuzz/regression/README to understand this code.
+    
+    Please also read the comments in .../tf_fuzz/regression/regress_lib/line_by_line.py.
+'''
+
+import sys, os, re, string, pdb
+sys.path.append ("../regress_lib")
+import line_by_line
+
+        
+# Describe script usage:
+def usage():
+    print ('''
+    Command-line parameters:
+    1.  The test-template file, nominally named "template",
+    2.  The expected combined stdout/stderr output, nominally named "exp_stdout_stderr",
+    3.  The actual/generated combined stdout/stderr output, nominally named "stdout_stderr",
+    4.  The expected .c test file, nominally named "exp_test.c", and
+    5.  The actual, generated .c test file, nominally named "test.c".
+    
+    Optionally, *before* these five arguments, you may add switches thus:
+    "--v" for verbose mode, to view line-by-line comparisons actual vs. expected,
+    "--q" to only print error messages and a successful-completion message,
+    "--qq" same as --q but not even printing out the completion message, and
+    "--s 12345" to run TF-Fuzz with seed value 12345 (or whatever).
+    ''')
+
+
+def main():
+    # See if we're supposed to be quiet:
+    loud = quiet = ultra_quiet = False
+    seed = ""
+    while sys.argv[1][0] == "-":
+        if sys.argv[1] == "--v":
+            loud = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--q":
+            quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--qq":
+            quiet = ultra_quiet = True
+            sys.argv.pop(1)
+        elif sys.argv[1] == "--s":
+            sys.argv.pop(1)
+            seed = sys.argv[1]
+            sys.argv.pop(1)
+            if not seed.isnumeric():
+                print ('The --s seed argument was not a number.')
+                usage()
+                sys.exit(1)
+        
+    # Run TF-Fuzz:
+    if not quiet: print ("Running TF-Fuzz...  ")
+    os.system ('rm -f stdout_stderr test.c')
+    command = '../../tfz -v ./' + sys.argv[1] + ' ./' + sys.argv[5]
+    command += ' ' + seed + ' >' + sys.argv[3] + ' 2>&1'
+    if loud:
+        print (command)
+    if os.system (command) == 0:
+        if not quiet: print ("TF-Fuzz run complete.")
+    else:
+        print ('Could not run TF-Fuzz;  please see stdout_stderr file.')
+        sys.exit(2)
+    
+    # Attempt to open files indicated on command line:
+    if len(sys.argv) != 6:
+        message = '{} requires 5 command-line arguments. Exiting.'
+        print (message.format(sys.argv[0]), file=sys.stderr)
+        usage()
+        sys.exit(3)
+    template_file_name =  sys.argv[1]
+    exp_stdout_file_name = sys.argv[2]
+    act_stdout_file_name = sys.argv[3]
+    exp_test_file_name = sys.argv[4]
+    act_test_file_name = sys.argv[5]
+
+    try:
+        template_file =  open (template_file_name, 'rt')
+        exp_stdout_file = open (exp_stdout_file_name, 'rt')
+        act_stdout_file = open (act_stdout_file_name, 'rt')
+        exp_test_file = open (exp_test_file_name, 'rt')
+        act_test_file = open (act_test_file_name, 'rt')
+    except FileNotFoundError:
+        print ('One or more files could not be found.')
+        usage();
+        sys.exit(4)
+    except:
+        print ('Something went wrong trying to open the input files.')
+        usage();
+        sys.exit(5)
+    else:
+        message =  '\nInput files:\n    {},\n    {},\n    {},\n'
+        message += '    {}, and\n    {}\nopened successfully.\n'
+        if not quiet:
+            print (message.format (template_file_name, exp_stdout_file_name, 
+                   act_stdout_file_name, exp_test_file_name, act_test_file_name))
+    
+    # Check it all:
+    if not quiet: print ("\nChecking test C file:  ", end="")
+    line_by_line.check_file (   exp_test_file, exp_test_file_name, 
+                                act_test_file, act_test_file_name,
+                                loud, quiet, ultra_quiet                      )
+    if not quiet: print ("Checking stdout and stderr:  ", end="")
+    line_by_line.check_file (   exp_stdout_file, exp_stdout_file_name, 
+                                act_stdout_file, act_stdout_file_name,
+                                loud, quiet, ultra_quiet                      )
+    
+    # Ran to completion normally, so pass:
+    if not ultra_quiet: print ("Regression test passed.")
+    sys.exit(0)
+
+if __name__ == "__main__": main()
diff --git a/tf_fuzz/regression/000024_SST_write_once/exp_stdout_stderr b/tf_fuzz/regression/000024_SST_write_once/exp_stdout_stderr
new file mode 100644
index 0000000..2273c23
--- /dev/null
+++ b/tf_fuzz/regression/000024_SST_write_once/exp_stdout_stderr
@@ -0,0 +1,45 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to verify we can't write multiple times to a write-once SST asset
+ASSET_IDENTIFIER:  "writeOnce"
+Asset identifier list:  "data"
+Create from random data
+SST write-once flag:  wo"
+SST creation flag
+;"
+SST creation flags
+;"
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "writeOnce"
+Asset identifier list:  "data"
+Create from random data
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+ASSET_IDENTIFIER:  "writeOnce"
+Asset identifier list:  "data"
+Create from random data
+Set SST command:  ";"
+Appended to end of call sequence:  SST-set call.
+Set command:  ";"
+Command with no expect:  ";"
+Lines:  Line number 5.
+Lines:  Line number 5.
+Lines:  Line number 5.
+Lines:  Line number 5.
+Call sequence generated.
+Simulating call sequence...
+Call sequence:
+    SST-set call for asset writeOnce
+    SST-set call for asset writeOnce
+    SST-set call for asset writeOnce
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/000024_SST_write_once/exp_test.c b/tf_fuzz/regression/000024_SST_write_once/exp_test.c
new file mode 100644
index 0000000..02d0530
--- /dev/null
+++ b/tf_fuzz/regression/000024_SST_write_once/exp_test.c
@@ -0,0 +1,79 @@
+/*
+ * Test purpose:
+ *     to verify we can't write multiple times to a write-once SST asset
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t writeOnce_set_data\[\] = "@@012@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t writeOnce_set_length = \d+;
+    static uint8_t writeOnce_set_data_1\[\] = "@@013@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t writeOnce_set_length_1 = \d+;
+    static uint8_t writeOnce_set_data_2\[\] = "@@014@10@@[a-z\ ]*[\.\?\!]";
+    static uint32_t writeOnce_set_length_2 = \d+;
+    (void)sst_status;
+        /* "void" to prevent unused-variable warning, since the variable may not
+         * be used in this particular test case.
+         */
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to verify we can't write multiple times to a write-once SST asset");
+
+
+    /* PSA calls to test: */
+    /\* Creating SST asset "writeOnce," with data "@@012@10@@...". \*/
+    sst_status = psa_ps_set\(@@@001@@@, writeOnce_set_length, writeOnce_set_data,
+                            PSA_STORAGE_FLAG_WRITE_ONCE);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_SUCCESS.");
+        return;
+    }
+    /\* Resetting SST asset "writeOnce," with data "@@013@10@@...". \*/
+    sst_status = psa_ps_set\(@@@001@@@, writeOnce_set_length_1, writeOnce_set_data_1,
+                            PSA_STORAGE_FLAG_WRITE_ONCE);
+    if (sst_status != PSA_ERROR_NOT_PERMITTED) {
+        TEST_FAIL("psa_ps_set() expected PSA_ERROR_NOT_PERMITTED.");
+        return;
+    }
+    /\* Resetting SST asset "writeOnce," with data "@@014@10@@...". \*/
+    sst_status = psa_ps_set\(@@@001@@@, writeOnce_set_length_2, writeOnce_set_data_2,
+                            PSA_STORAGE_FLAG_WRITE_ONCE);
+    if (sst_status != PSA_ERROR_NOT_PERMITTED) {
+        TEST_FAIL("psa_ps_set() expected PSA_ERROR_NOT_PERMITTED.");
+        return;
+    }
+
+
+    /* Removing assets left over from testing: */
+    psa_ps_remove\(@@@001@@@\);
+    if (sst_status != PSA_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion.");
+        return;
+    }
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/000024_SST_write_once/template b/tf_fuzz/regression/000024_SST_write_once/template
new file mode 100644
index 0000000..60fc978
--- /dev/null
+++ b/tf_fuzz/regression/000024_SST_write_once/template
@@ -0,0 +1,4 @@
+purpose to verify we can't write multiple times to a write-once SST asset;
+set sst name writeOnce data * flag wo;
+set sst name writeOnce data *;
+set sst name writeOnce data *;
diff --git a/tf_fuzz/regression/README b/tf_fuzz/regression/README
new file mode 100644
index 0000000..d4fbcb6
--- /dev/null
+++ b/tf_fuzz/regression/README
@@ -0,0 +1,9 @@
+This is a regression suite for the TF-Fuzz tool.
+
+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/~regression_dir.html
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/regression/add_these_tests/000015_set_sst_multi_name_remove_rand_active/exp_stdout_stderr b/tf_fuzz/regression/add_these_tests/000015_set_sst_multi_name_remove_rand_active/exp_stdout_stderr
new file mode 100644
index 0000000..3c5de35
--- /dev/null
+++ b/tf_fuzz/regression/add_these_tests/000015_set_sst_multi_name_remove_rand_active/exp_stdout_stderr
@@ -0,0 +1,30 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to show a more-interesting removal case
+ASSET_IDENTIFIER:  "president"
+ASSET_IDENTIFIER:  "george"
+ASSET_IDENTIFIER:  "herbert"
+ASSET_IDENTIFIER:  "walker"
+ASSET_IDENTIFIER:  "bush"
+Asset identifier list:  "data"
+LITERAL string:  "read my lips"
+Create from literal data:  ""read my lips""
+Set SST command:  ""read my lips""
+Set command:  ""read my lips""
+Command with no expect:  ";"
+SST-asset random active:  "active"
+SST-remove arguments:  "active"
+Remove SST command:  "active"
+Remove command:  "active"
+Command with no expect:  ";"
+Lines:  Line number 4.
+Lines:  Line number 4.
+Lines:  Line number 4.
+Call sequence generated.
+Simulating call sequence...
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/add_these_tests/000015_set_sst_multi_name_remove_rand_active/exp_test.c b/tf_fuzz/regression/add_these_tests/000015_set_sst_multi_name_remove_rand_active/exp_test.c
new file mode 100644
index 0000000..c0eddcd
--- /dev/null
+++ b/tf_fuzz/regression/add_these_tests/000015_set_sst_multi_name_remove_rand_active/exp_test.c
@@ -0,0 +1,117 @@
+/*
+ * Test purpose:
+ *     to show a more-interesting removal case
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+/* For now, just a single test_result_t struct is sufficient.*/
+static struct test_result_t ret;
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_ps_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t president_set_data[] = "read my lips";
+    int president_set_length = 12;
+    static uint8_t george_set_data[] = "read my lips";
+    int george_set_length = 12;
+    static uint8_t herbert_set_data[] = "read my lips";
+    int herbert_set_length = 12;
+    static uint8_t walker_set_data[] = "read my lips";
+    int walker_set_length = 12;
+    static uint8_t bush_set_data[] = "read my lips";
+    int bush_set_length = 12;
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to show a more-interesting removal case");
+
+
+
+
+    /* PSA calls to test: */
+
+    /* Creating SST asset "president," with data "read my li...". */
+    sst_status = psa_ps_set(@@@001@@@, president_set_length, president_data, PSA_PS_FLAG_WRITE_ONCE);
+    if (sst_status != PSA_PS_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_PS_SUCCESS, got #%d, (int) sst_status);
+        return;
+    }
+
+    /* Creating SST asset "george," with data "read my li...". */
+    sst_status = psa_ps_set(5517, george_set_length, george_data, PSA_PS_FLAG_WRITE_ONCE);
+    if (sst_status != PSA_PS_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_PS_SUCCESS, got #%d, (int) sst_status);
+        return;
+    }
+
+    /* Creating SST asset "herbert," with data "read my li...". */
+    sst_status = psa_ps_set(4661, herbert_set_length, herbert_data, PSA_PS_FLAG_WRITE_ONCE);
+    if (sst_status != PSA_PS_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_PS_SUCCESS, got #%d, (int) sst_status);
+        return;
+    }
+
+    /* Creating SST asset "walker," with data "read my li...". */
+    sst_status = psa_ps_set(3441, walker_set_length, walker_data, PSA_PS_FLAG_WRITE_ONCE);
+    if (sst_status != PSA_PS_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_PS_SUCCESS, got #%d, (int) sst_status);
+        return;
+    }
+
+    /* Creating SST asset "bush," with data "read my li...". */
+    sst_status = psa_ps_set(5446, bush_set_length, bush_data, PSA_PS_FLAG_WRITE_ONCE);
+    if (sst_status != PSA_PS_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_PS_SUCCESS, got #%d, (int) sst_status);
+        return;
+    }
+
+    sst_status = psa_ps_remove(5517);
+    if (sst_status != PSA_PS_SUCCESS) {
+        TEST_FAIL("psa_ps_remove() expected PSA_PS_SUCCESS, got #%d", (int) sst_status);
+    }
+
+
+    /* Removing assets left over from testing: */
+    psa_ps_remove(@@@001@@@);
+    if (sst_status != PSA_PS_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion!");
+        return;
+    }
+    psa_ps_remove(4661);
+    if (sst_status != PSA_PS_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion!");
+        return;
+    }
+    psa_ps_remove(3441);
+    if (sst_status != PSA_PS_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion!");
+        return;
+    }
+    psa_ps_remove(5446);
+    if (sst_status != PSA_PS_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion!");
+        return;
+    }
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/add_these_tests/000015_set_sst_multi_name_remove_rand_active/template b/tf_fuzz/regression/add_these_tests/000015_set_sst_multi_name_remove_rand_active/template
new file mode 100644
index 0000000..613439e
--- /dev/null
+++ b/tf_fuzz/regression/add_these_tests/000015_set_sst_multi_name_remove_rand_active/template
@@ -0,0 +1,3 @@
+purpose to show a more-interesting removal case;
+set sst name president george herbert walker bush data "read my lips";
+remove sst *active;  // remove *some* active asset
diff --git a/tf_fuzz/regression/add_these_tests/000016_set_sst_multi_name_remove_multi_rand_active_remove_rand_deleted/exp_stdout_stderr b/tf_fuzz/regression/add_these_tests/000016_set_sst_multi_name_remove_multi_rand_active_remove_rand_deleted/exp_stdout_stderr
new file mode 100644
index 0000000..bdeffb7
--- /dev/null
+++ b/tf_fuzz/regression/add_these_tests/000016_set_sst_multi_name_remove_multi_rand_active_remove_rand_deleted/exp_stdout_stderr
@@ -0,0 +1,48 @@
+Trusted Firmware Fuzzer (TF-Fuzz) starting...
+
+Info:  random seed was not specified.
+
+Using seed value of \d+ \(0x[a-f\d]+\).
+Purpose line:  to show a more-interesting removal case
+ASSET_IDENTIFIER:  "president"
+ASSET_IDENTIFIER:  "george"
+ASSET_IDENTIFIER:  "herbert"
+ASSET_IDENTIFIER:  "walker"
+ASSET_IDENTIFIER:  "bush"
+Asset identifier list:  "data"
+LITERAL string:  "no new taxes"
+Create from literal data:  ""no new taxes""
+Set SST command:  ""no new taxes""
+Set command:  ""no new taxes""
+Command with no expect:  ";"
+SST-asset random active:  "active"
+SST-remove arguments:  "active"
+Remove SST command:  "active"
+Remove command:  "active"
+Command with no expect:  ";"
+SST-asset random active:  "active"
+SST-remove arguments:  "active"
+Remove SST command:  "active"
+Remove command:  "active"
+Command with no expect:  ";"
+SST-asset random active:  "active"
+SST-remove arguments:  "active"
+Remove SST command:  "active"
+Remove command:  "active"
+Command with no expect:  ";"
+SST-asset random deleted:  "deleted"
+SST-remove arguments:  "deleted"
+Remove SST command:  "deleted"
+Remove command:  "deleted"
+Command with no expect:  ";"
+Lines:  Line number 7.
+Lines:  Line number 7.
+Lines:  Line number 7.
+Lines:  Line number 7.
+Lines:  Line number 7.
+Lines:  Line number 7.
+Call sequence generated.
+Simulating call sequence...
+Writing test file, ./test.c.
+
+TF-Fuzz test generation complete.
diff --git a/tf_fuzz/regression/add_these_tests/000016_set_sst_multi_name_remove_multi_rand_active_remove_rand_deleted/exp_test.c b/tf_fuzz/regression/add_these_tests/000016_set_sst_multi_name_remove_multi_rand_active_remove_rand_deleted/exp_test.c
new file mode 100644
index 0000000..c2752fb
--- /dev/null
+++ b/tf_fuzz/regression/add_these_tests/000016_set_sst_multi_name_remove_multi_rand_active_remove_rand_deleted/exp_test.c
@@ -0,0 +1,123 @@
+/*
+ * Test purpose:
+ *     to show a more-interesting removal case
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../sst/non_secure/ns_test_helpers.h"
+#include "psa/protected_storage.h"
+#include "test/framework/test_framework_helpers.h"
+#include "tfm_memory_utils.h"
+#include "psa/crypto.h"
+#include "psa/crypto_sizes.h"
+/* For now, just a single test_result_t struct is sufficient.*/
+static struct test_result_t ret;
+
+/* This is not yet right for how to run a test;  need to register tests, etc. */
+
+void test_thread (struct test_result_t *ret) {
+    psa_status_t crypto_status;  /* result from Crypto calls */
+    psa_ps_status_t sst_status;
+    /* Variables (etc.) to initialize and check PSA assets: */
+    static uint8_t president_set_data[] = "no new taxes";
+    int president_set_length = 12;
+    static uint8_t george_set_data[] = "no new taxes";
+    int george_set_length = 12;
+    static uint8_t herbert_set_data[] = "no new taxes";
+    int herbert_set_length = 12;
+    static uint8_t walker_set_data[] = "no new taxes";
+    int walker_set_length = 12;
+    static uint8_t bush_set_data[] = "no new taxes";
+    int bush_set_length = 12;
+
+    crypto_status = psa_crypto_init();
+    if (crypto_status != PSA_SUCCESS) {
+        TEST_FAIL("Could not initialize Crypto.");
+        return;
+    }
+
+    TEST_LOG("Test to show a more-interesting removal case");
+
+
+
+
+    /* PSA calls to test: */
+
+    /* Creating SST asset "president," with data "no new tax...". */
+    sst_status = psa_ps_set(4713, president_set_length, president_set_data,
+                            PSA_PS_FLAG_WRITE_ONCE);
+    if (sst_status != PSA_PS_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_PS_SUCCESS, got #%d, (int) sst_status);
+        return;
+    }
+
+    /* Creating SST asset "george," with data "no new tax...". */
+    sst_status = psa_ps_set(5517, george_set_length, george_data, PSA_PS_FLAG_WRITE_ONCE);
+    if (sst_status != PSA_PS_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_PS_SUCCESS, got #%d, (int) sst_status);
+        return;
+    }
+
+    /* Creating SST asset "herbert," with data "no new tax...". */
+    sst_status = psa_ps_set(4661, herbert_set_length, herbert_data, PSA_PS_FLAG_WRITE_ONCE);
+    if (sst_status != PSA_PS_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_PS_SUCCESS, got #%d, (int) sst_status);
+        return;
+    }
+
+    /* Creating SST asset "walker," with data "no new tax...". */
+    sst_status = psa_ps_set(3441, walker_set_length, walker_data, PSA_PS_FLAG_WRITE_ONCE);
+    if (sst_status != PSA_PS_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_PS_SUCCESS, got #%d, (int) sst_status);
+        return;
+    }
+
+    /* Creating SST asset "bush," with data "no new tax...". */
+    sst_status = psa_ps_set(5446, bush_set_length, bush_data, PSA_PS_FLAG_WRITE_ONCE);
+    if (sst_status != PSA_PS_SUCCESS) {
+        TEST_FAIL("psa_ps_set() expected PSA_PS_SUCCESS, got #%d, (int) sst_status);
+        return;
+    }
+
+    sst_status = psa_ps_remove(5517);
+    if (sst_status != PSA_PS_SUCCESS) {
+        TEST_FAIL("psa_ps_remove() expected PSA_PS_SUCCESS, got #%d", (int) sst_status);
+    }
+
+    sst_status = psa_ps_remove(4713);
+    if (sst_status != PSA_PS_SUCCESS) {
+        TEST_FAIL("psa_ps_remove() expected PSA_PS_SUCCESS, got #%d", (int) sst_status);
+    }
+
+    sst_status = psa_ps_remove(3441);
+    if (sst_status != PSA_PS_SUCCESS) {
+        TEST_FAIL("psa_ps_remove() expected PSA_PS_SUCCESS, got #%d", (int) sst_status);
+    }
+
+    sst_status = psa_ps_remove(3441);
+    if (sst_status != PSA_PS_ERROR_UID_NOT_FOUND) {
+        TEST_FAIL("psa_ps_remove() expected PSA_PS_ERROR_UID_NOT_FOUND, got #%d", (int) sst_status);
+    }
+
+
+    /* Removing assets left over from testing: */
+    psa_ps_remove(4661);
+    if (sst_status != PSA_PS_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion!");
+        return;
+    }
+    psa_ps_remove(5446);
+    if (sst_status != PSA_PS_SUCCESS) {
+        TEST_FAIL("Failed to tear down an SST asset upon test completion!");
+        return;
+    }
+
+    /* Test completed */
+    ret->val = TEST_PASSED;
+}
diff --git a/tf_fuzz/regression/add_these_tests/000016_set_sst_multi_name_remove_multi_rand_active_remove_rand_deleted/template b/tf_fuzz/regression/add_these_tests/000016_set_sst_multi_name_remove_multi_rand_active_remove_rand_deleted/template
new file mode 100644
index 0000000..2bf82b0
--- /dev/null
+++ b/tf_fuzz/regression/add_these_tests/000016_set_sst_multi_name_remove_multi_rand_active_remove_rand_deleted/template
@@ -0,0 +1,6 @@
+purpose to show a more-interesting removal case;
+set sst name president george herbert walker bush data "no new taxes";
+remove sst *active;  // remove *some* active asset
+rm sst *active;  // remove *some other* active asset
+rm sst *act;  // remove *yet another* active asset
+remove sst *del;  // attempt to remove some asset that's already been removed
diff --git a/tf_fuzz/regression/regress b/tf_fuzz/regression/regress
new file mode 100644
index 0000000..1a2b595
--- /dev/null
+++ b/tf_fuzz/regression/regress
@@ -0,0 +1,22 @@
+# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+echo
+echo TF-Fuzz Regression Testing
+echo
+for reg_test in `ls -F | grep \/$ | grep -v add_these_tests | grep -v regress_lib`; do
+    echo
+    echo Running "$reg_test"...
+    cd $reg_test
+    rm -f test.c stdout_stderr
+    python3 check.py --q template exp_stdout_stderr stdout_stderr exp_test.c test.c
+    if test $? -ne 0
+    then
+        exit
+    fi
+    cd ..
+done
+echo
+echo
+echo All TF-Fuzz regression tests passed.
diff --git a/tf_fuzz/regression/regress_lib/line_by_line.py b/tf_fuzz/regression/regress_lib/line_by_line.py
new file mode 100644
index 0000000..f09a038
--- /dev/null
+++ b/tf_fuzz/regression/regress_lib/line_by_line.py
@@ -0,0 +1,172 @@
+#!/usr/bin/env python3
+# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+'''
+The functions here perform straight-forward line-by-line comparisons of regression 
+TF-Fuzz regression tests.  These are not sufficient to address cases where the PSA
+calls are randomized.
+
+Each given line of the expected files (exp_stdout_stderr and exp_test.c) functions
+as Python regex for the corresonding line in the actual/generated corresponding
+file.  Actually, the expected-file lines may need a little bit of tweaking first.
+There are three scenarios:
+*  The line in exp_* file contains no regex content at all.  In this case, the two
+   lines must be exactly identical, character for character. The actual/generated 
+   output files do not contain regexes, but can contain parentheses or other 
+   characters that "look like" regex content, and thus confuse re.match().  So, 
+   it's first checked for an exact string == match. 
+*  The line in the exp_* file contains one or more standard-Python regex patterns
+   to match.  In this case, a Python re.match() will still report a match.
+*  The line in the exp_* file contains one or more non-standard regex pattern, in
+   which case that non-standard regex pattern needs to be replaced with the actual,
+   expected character string.
+
+As described in the above-cited README, these non-standard regex wildcards in the 
+exp_* files take either of two formats:
+*  "@@@" a 3-digit pattern number "@@@" (e.g., "@@@005@@@"):  This denotes a
+   pattern of no particular length that must match the same text every occurrence
+   in the actual/generated file.
+*  "@@" a 3-digit pattern number "@" a 2-digit length in chars "@@":  Same idea as
+   the previous pattern, except that it also has a specific length.
+   
+To address these special regex wildcards, check_gen_test() below has to:
+1.  Isolate the wildcard from the rest of the string,
+2.  Check that wildcard against a Python dictionary relating the wildcard name to 
+    its expected-text substitution value,
+3.  If not present in the dictionary, create a new dictionary entry relating the 
+    wildcard text to the text found in that spot in the actual/generated file,
+4.  Replace that wildcard text with the expected value from the hash, then
+5.  As with all lines, perform the re.match() between the two lines.
+'''
+
+import sys, os, re, string, pdb
+
+
+'''
+mask_other_wildcards(), used by resolve_wildcards() below, is used in harvesting
+the value of a certain wildcard of the sort described above.  After the caller
+replaces the wildcard of interest with a regex to retrieve that data from actual-
+output file, it passes the string into here, to replace all other wildcards with
+"anything goes" regexes.
+'''
+def mask_other_wildcards (a_string):
+    # Unsized wildcards:
+    while True:
+        matchInfo = re.match ('.*(@@@\d\d\d@@@)', a_string)
+        if not matchInfo:
+            break
+        wildcard = matchInfo.group(1)
+        a_string = a_string.replace (wildcard, '.*')
+    # Sized wildcards:
+    while True:
+        matchInfo = re.match ('.*(@@\d\d\d@\d\d@@)', a_string)
+        if not matchInfo:
+            break
+        wildcard = matchInfo.group(1)
+        a_string = a_string.replace (wildcard, '.*')
+    return a_string
+
+
+'''
+resolve_wildcards() resolves wildcards of the sort described above, in an expected
+file line (exp) from a wildcard dictionary (wildcard_dict).  In particular, it
+replaces them with what the wildcards are found to stand for in the actual test 
+output (act).  If it encounters a wildcard it has not seen before, it adds it to 
+the dictionary, based upon what's in the test.c output.  Further occurrences of that
+wildcard, it pulls from the wildcard dictionary, meaning that the subsequent 
+occurrences must resolve to the same text string.
+'''
+def resolve_wildcards (exp, act, wildcard_dict):
+    # Loop through each wildcard on the line, filling them in with values from the 
+    # wildcard dictionary, or filling them into the wildcard dictionary.
+
+    #pdb.set_trace()
+
+    while True:
+        wildcard_sized = False
+        matchInfo = re.match ('.*(@@@\d\d\d@@@)', exp)
+        if not matchInfo:
+            wildcard_sized = True
+                # 0 = sized, and we'll fill in that size below, if we don't already know
+            matchInfo = re.match ('.*(@@\d\d\d@\d\d@@)', exp)
+            if not matchInfo:
+                break
+        wildcard = matchInfo.group(1)
+        if wildcard in wildcard_dict:
+            # Previously-encountered wildcard:
+            wildcard_value = wildcard_dict[wildcard]
+        else:
+            # New wildcard:
+            if wildcard_sized:  # find the size
+                size_str = re.match ("@@\d\d\d@(\d\d)@@",wildcard).group(1)
+                find_sub = exp.replace (wildcard, '(.{' + size_str + '})', 1)
+            else:
+                find_sub = exp.replace (wildcard, '(.*)', 1)
+            find_sub = mask_other_wildcards (find_sub)
+            matchInfo = re.match (find_sub, act)
+            wildcard_value = matchInfo.group(1)
+            wildcard_dict[wildcard] = wildcard_value
+        exp = exp.replace (wildcard, wildcard_value)
+    return exp
+
+'''
+check_file() checks that an actual-output test file (act_test_file) matches an 
+expected-output file (exp_test_file), line by line, including resolving the 
+wildcards of the nature described above.
+'''
+def check_file (   exp_test_file, exp_test_file_name, 
+                   act_test_file, act_test_file_name,
+                   loud, quiet, ultra_quiet                   ):
+    # This is the dictionary of wildcards, of the nature described above.
+    wildcard_dict = dict()
+
+    line_no = 0
+    while True:
+        exp_line = exp_test_file.readline()
+        act_line = act_test_file.readline()
+        # Ignore the special case where a seed was specified in generating actual,
+        # but wasn't in expected file:
+        if exp_line == 'Info:  random seed was not specified.\n' and act_line == '\n':
+            print ("(Note:  Ignoring no-seed-specified message in expected.)")
+            exp_line = exp_test_file.readline()
+        line_no += 1
+        if not quiet and not loud: print (".", end="")
+        if not exp_line and act_line:
+            message = "\nError:  More lines in file {} than in {}."
+            if not ultra_quiet:
+                print (message.format(act_test_file_name, exp_test_file_name))
+            sys.exit(8)
+        elif not act_line and exp_line:
+            message = "\nError:  More lines in file {} than in {}."
+            if not ultra_quiet:
+                print (message.format(exp_test_file_name, act_test_file_name))
+            sys.exit(9)
+        # No line-count mismatch (so far);  either both reads succeeded or both failed:
+        if not exp_line:
+            break  # all lines read;  kick out of the loop.
+        exp_line = exp_line.rstrip();  act_line = act_line.rstrip()
+        if loud and not quiet:
+            print ("\n" + str(line_no) + "\nExpect:  '" + exp_line + "'")
+            print ("Actual:  '" + act_line + "'")
+        # If the two lines match as raw strings then we're good:
+        if exp_line == act_line:
+            pass  # this line passes
+        else:
+            # Before doing a re.match() on this line pair, replace any nontraditional
+            # wildcards with what they're expected to contain:
+            if re.match (".*@@\d\d\d@", exp_line):  # just to save time if no wildcards
+                exp_line = resolve_wildcards (exp_line, act_line, wildcard_dict)
+            if (exp_line == "" and act_line != "") or not re.match (exp_line, act_line):
+                message  = "\nError:  At line {} mismatch between {} and {}:"
+                message1 = "    Expected:  {}"
+                message2 = "         Got:  {}\n"
+                if not ultra_quiet:
+                    print (message.format(line_no, exp_test_file_name, act_test_file_name))
+                    print (message1.format(exp_line))
+                    print (message2.format(act_line))
+                sys.exit(10)
+    if not quiet:  print ("\nGenerated file complies with expected file.")
+
+
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
diff --git a/tf_fuzz/tests/example_template b/tf_fuzz/tests/example_template
new file mode 100644
index 0000000..4ecfd53
--- /dev/null
+++ b/tf_fuzz/tests/example_template
@@ -0,0 +1,20 @@
+purpose to check basic functionality of TF-Fuzz;
+
+/*// Attempt to get data from a deleted SST asset, using human-readable name:
+set sst name creditCardNos data "0985-9375-0338-3406";
+set sst name creditCardNos data "5687-3782-1127-9821";
+remove sst name creditCardNos;
+remove sst name creditCardNos;
+*/
+
+//remove sst name creditCardNos;
+
+//remove sst name creditCardNos expect user_defined_error;
+
+//read sst name creditCardNos dfname 'ccNumbersRead' expect uid_not_found;
+
+//set SST asset by raw UID number and then get its data:
+
+//set sst uid 38 data "Very short data set" expect nothing;
+
+//read sst uid 38 check "Very short data set" expect pass;
diff --git a/tf_fuzz/tests/sstReads b/tf_fuzz/tests/sstReads
new file mode 100644
index 0000000..d2ad8b9
--- /dev/null
+++ b/tf_fuzz/tests/sstReads
@@ -0,0 +1,87 @@
+purpose to beat the heck out of read sst template lines;
+
+read sst name nonexistent check "XYZ PDQ";  // fail
+
+/*
+set sst name passwords data "Very short data set";
+read sst name passwords check "Very short data set";
+read sst name passwords check greeble;
+//read sst name passwords assign dorf;
+//read sst name passwords print;
+*/
+
+/*
+set sst uid 1234 data *;
+read sst uid 1234 check "Very short data set";
+//read sst uid 1234 check greeble;
+//read sst uid 1234 assign dorf;
+*/
+
+/*
+set sst name moe curly larry data *;
+remove sst *active;
+read sst *active assign shemp;
+read sst *active print;
+*/
+
+//read sst uid 205 assign aVariable;
+
+//read sst uid 15 41 check "self-destruct using top secret corbomite device" expect pass;
+
+//read sst uid 17 41 19 31 10 53 data *;
+
+/*
+set sst name apollo_11 data *;
+read sst name apollo_11 hash;
+*/
+
+/*
+set sst name jim lovell gemini_7 gemini_12 apollo_8 apollo_13 data *;
+read sst name jim lovell gemini_7 gemini_12 apollo_8 apollo_13 hash;
+secure hash neq jim lovell gemini_7 gemini_12 apollo_8 apollo_13;
+*/
+
+/*
+set sst name friendship_7 apollo_14 data *;
+read sst name friendship_7 apollo_14 hash;
+secure hash neq friendship_7 apollo_14;
+*/
+
+// /*
+set sst name astp data *;
+read sst name astp hash;
+secure hash neq astp;
+// */
+
+/*
+set sst name chapman cleese gilliam idle jones palin data *;
+4 of {
+    set sst name cleveland data *;
+    read sst *active check "totally wrong data";
+    remove sst *active;
+} */
+
+/*
+2 to 6 of {
+    read sst name passwords check "Very short data set";
+    read sst name CCnumbers check "Ask not what your country can do for you.";
+    read sst name * data *;
+    read sst uid * data * expect pass;
+} */
+
+/*
+shuffle {
+    read sst name passwords check "Very short data set";
+    read sst name CCnumbers data *;
+    read sst name Kirk check "Beam me up.";
+    read sst uid 42 check "Don't panic.";
+    read sst name Spock check "Fascinating." expect pass;
+    read sst name McCoy check "I'm a doctor, not a bricklayer." expect pass;
+    read sst name Scotty check "I'm giving her all she's got!" expect pass;
+} */
+
+/*
+read sst name neil buzz mike data *;
+remove sst *active expect pass;  // zap a random currently-active SST asset
+remove sst *deleted;  // delete an already-deleted asset
+*/
diff --git a/tf_fuzz/tests/sstSets b/tf_fuzz/tests/sstSets
new file mode 100644
index 0000000..fb0981d
--- /dev/null
+++ b/tf_fuzz/tests/sstSets
@@ -0,0 +1,59 @@
+purpose to beat the heck out of set sst template lines;
+
+//set sst name passwords data "Very short data set";
+
+//set sst uid 15 41 data "self-destruct using top secret corbomite device" expect pass;
+
+//set sst uid 38 data "So long, and thanks for all the fish!" expect nothing;
+
+//set sst uid * data * expect pass;
+
+set sst name CCnumbers data *;
+
+//set sst name CCnumbers securityAnswers passwords data *;
+
+//set sst uid 17 41 19 31 10 53 data *;
+
+//3 of {set sst name * data "The trick to flying is to throw yourself at the ground, and miss.";}
+
+//5 of {set sst name snortwaggle data *;}
+
+//4 of set sst uid * data "that's one small step for [a] man;  one giant leap for mankind";
+
+//5 of set sst uid * data *;  // should have different data each time!
+
+/*
+4 of {
+    set sst name passwords data "Very short data set";
+    set sst name CCnumbers data "Beam me up, Scotty!";
+    set sst uid 1941 data "December 7th 1941:  A day that will live in infamy";
+    set sst name snortwaggle data * expect pass;
+    set sst name gurgleflurtz data "If you're going through hell, keep going.";
+    set sst name Picard data *;
+} */
+
+/*
+2 to 6 of {
+    set sst name passwords data "Very short data set";
+    set sst name CCnumbers data "Ask rather what you can do for your country.";
+    set sst name * data *;
+    set sst uid * data * expect pass;
+} */
+
+/*
+shuffle {
+    set sst name passwords data "Very short data set";
+    set sst name CCnumbers data *;
+    set sst name Kirk data "Beam me up.";
+    set sst uid 42 data "Don't panic.";
+    set sst name Spock data "Fascinating." expect pass;
+    set sst name McCoy data "I'm a doctor, not a bricklayer." expect pass;
+    set sst name Scotty data "I'm giving her all she's got!" expect pass;
+} */
+
+/*
+set sst name neil buzz mike data *;
+remove sst *active expect pass;  // zap a random currently-active SST asset
+remove sst *deleted;  // delete an already-deleted asset
+*/
+//set sst *deleted data "a over-ripe banana walks into a bar..." expect pass;
diff --git a/tf_fuzz/tf_fuzz.cpp b/tf_fuzz/tf_fuzz.cpp
new file mode 100644
index 0000000..57ae836
--- /dev/null
+++ b/tf_fuzz/tf_fuzz.cpp
@@ -0,0 +1,512 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <ctime>  // to seed random, if seed not passed in
+#include <string>
+#include <vector>
+#include <iostream>
+#include <cstdlib>  // for srand() and rand()
+#include <cstdio>  // for template lex&yacc input file
+#include "class_forwards.hpp"
+#include "boilerplate.hpp"
+#include "gibberish.hpp"
+#include "compute.hpp"
+#include "string_ops.hpp"
+#include "data_blocks.hpp"
+#include "psa_asset.hpp"
+#include "find_or_create_asset.hpp"
+#include "template_line.hpp"
+#include "tf_fuzz.hpp"
+#include "sst_asset.hpp"
+#include "crypto_asset.hpp"
+#include "psa_call.hpp"
+#include "tf_fuzz_grammar.tab.hpp"
+#include "variables.hpp"
+
+
+extern FILE* yyin;  // telling lex&yacc which file to parse
+
+using namespace std;
+
+long psa_asset::unique_id_counter = 10;  // counts unique IDs for assets
+long psa_call::unique_id_counter = 10;  // counts unique IDs for assets
+    /* FYI:  Must initialize these class variables outside the class.  If
+             initialized inside the class, g++ requires they be const. */
+
+/**********************************************************************************
+   Methods of class tf_fuzz_info follow:
+**********************************************************************************/
+
+asset_search tf_fuzz_info::find_or_create_sst_asset (
+    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 by asset's unique serial number
+    bool create_asset,  // true to create the asset if it doesn't exist
+    vector<psa_asset*>::iterator &asset  // returns a pointer to requested asset
+) {
+    return generic_find_or_create_asset<sst_asset>(
+               active_sst_asset, deleted_sst_asset,
+               invalid_sst_asset, criterion, where, target_name, target_id,
+               serial_no, create_asset, asset
+           );
+}
+
+asset_search tf_fuzz_info::find_or_create_key_asset (
+    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 by asset's unique serial number
+    bool create_asset,  // true to create the asset if it doesn't exist
+    vector<psa_asset*>:: iterator &asset  // returns iterator to requested asset
+) {
+    return generic_find_or_create_asset<key_asset>(
+               active_key_asset, deleted_key_asset,
+               invalid_key_asset, criterion, where, target_name, target_id,
+               serial_no, create_asset, asset
+           );
+}
+
+asset_search tf_fuzz_info::find_or_create_policy_asset (
+    psa_asset_search criterion,  // what to search on
+    psa_asset_usage where,  // where to search
+    string target_name,  // ignored unless searching on name
+    uint64_t target_id,  // also ignored unless searching on ID (e.g., SST UID)
+    long &serial_no,  // search by asset's unique serial number
+    bool create_asset,  // true to create the asset if it doesn't exist
+    vector<psa_asset*>::iterator &asset  // iterator to requested asset
+) {
+    return generic_find_or_create_asset<policy_asset>(
+               active_policy_asset, deleted_policy_asset,
+               invalid_policy_asset, criterion, where, target_name, target_id,
+               serial_no, create_asset, asset
+           );
+}
+
+asset_search tf_fuzz_info::find_or_create_psa_asset (
+    psa_asset_type asset_type,  // what type of asset to find
+    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 by asset's unique serial number
+    bool create_asset,  // true to create the asset if it doesn't exist
+    vector<psa_asset*>::iterator &asset  // returns iterator to asset
+) {
+    switch (asset_type) {
+        case psa_asset_type::sst:
+            return find_or_create_sst_asset (
+                criterion, where, target_name, target_id,
+                serial_no, create_asset, asset);
+            break;
+        case psa_asset_type::key:
+            return find_or_create_key_asset (
+                criterion, where, target_name, target_id,
+                serial_no, create_asset, asset);
+            break;
+        case psa_asset_type::policy:
+            return find_or_create_policy_asset (
+                criterion, where, target_name, target_id,
+                serial_no, create_asset, asset);
+            break;
+        default:
+            cerr << "\nError:  Internal:  Please report error "
+                 << "#1503 to TF-Fuzz developers." << endl;
+            exit (1500);
+    }
+}
+
+// Return an iterator to a variable, if it exists.  If not return variable.end().
+vector<variable_info>::iterator tf_fuzz_info::find_var (string var_name)
+{
+    vector<variable_info>::iterator the_var;
+    if (variable.empty()) {
+        return variable.end();
+    }
+    for (the_var = variable.begin();  the_var < variable.end();  the_var++) {
+        if (the_var->name == var_name) {
+            break;
+        }
+    }
+    return the_var;
+}
+// Add a variable to the vector if not already there; return true if already there.
+bool tf_fuzz_info::make_var (string var_name)
+{
+    bool found = false;
+    variable_info new_variable;
+
+    found = (find_var (var_name) != variable.end());
+    if (!found) {
+        new_variable.name.assign (var_name);
+        variable.push_back (new_variable);
+    }
+    return found;
+}
+
+
+// Remove any PSA resources used in the test.  Returns success==true, fail==false.
+void tf_fuzz_info::teardown_test (void)
+{
+    string call;
+    // Traverse through the SST-assets list, writing out remove commands:
+    for (auto &asset : active_sst_asset) {
+        // It turns out you're not allowed to remove "WRITE_ONCE" assets:
+        if (   asset->set_data.flags_string.find("PSA_STORAGE_FLAG_WRITE_ONCE")
+            == string::npos
+           ) {
+            call = bplate->bplate_string[teardown_sst];
+            find_replace_1st ("$uid", to_string(asset->asset_info.id_n), call);
+            call.append (bplate->bplate_string[teardown_sst_check]);
+            output_C_file << call;
+        }
+    }
+    // Same, but with key assets:
+    for (auto &asset : active_key_asset) {
+        call = bplate->bplate_string[teardown_key];
+        find_replace_1st ("$handle", asset->handle_str, call);
+        call.append (bplate->bplate_string[teardown_key_check]);
+        output_C_file << call;
+    }
+}
+
+// Write out the test itself.
+void tf_fuzz_info::write_test (void)
+{
+    string call;
+    string work = bplate->bplate_string[preamble_A];  // a temporary workspace string
+
+    // The test file should be open before calling this method.
+    // Spit out the obligatory preamble:
+    find_replace_all ("$purpose", test_purpose, work);
+    output_C_file << work;
+
+    // If using hashing, then spit out the hashing functions:
+    if (include_hashing_code) {
+        work = bplate->bplate_string[hashing_code];
+        output_C_file << work;
+    }
+
+    // Print out the second part of the preamble code:
+    work = bplate->bplate_string[preamble_B];
+    find_replace_all ("$purpose", test_purpose, work);
+    output_C_file << work;
+
+    output_C_file << "    /* Variables (etc.) to initialize and check PSA "
+                  << "assets: */" << endl;
+    for (auto call : calls) {
+        // Reminder:  calls is a vector of *pointers to* psa_call subclass objects.
+        call->fill_in_prep_code();
+        call->write_out_prep_code (output_C_file);
+    }
+
+    // Print out the final part of the preamble code:
+    work = bplate->bplate_string[preamble_C];
+    find_replace_all ("$purpose", test_purpose, work);
+    output_C_file << work;
+
+    output_C_file << "\n\n    /* PSA calls to test: */" << endl;
+    for (auto call : calls) {
+        call->fill_in_command();  // (fills in check code too)
+        call->write_out_command (output_C_file);
+        call->write_out_check_code (output_C_file);
+    }
+
+    output_C_file << "\n\n    /* Removing assets left over from testing: */"
+                  << endl;
+    teardown_test();
+
+    // Seal the deal:
+    output_C_file << bplate->bplate_string[closeout];
+
+    // Close the template and test files:
+    output_C_file.close();
+    fclose (template_file);
+}
+
+
+/* simulate_calls() goes through the vector of generated calls calculating expected
+   results for each. */
+void tf_fuzz_info::simulate_calls (void)
+{
+    bool asset_state_changed = false;
+
+    IV(cout << "Call sequence:" << endl;)
+    /* For now, much of the simulation "thinking" infrastructure is here for future
+       elaboration.  The algorithm is to through each call one by one, copying
+       information to the asset in question.  Then each currently-active asset is
+       allowed to react to that information until they all agree that they're
+       "quiescent."  Finally, result information is copied from the asset back to
+       the call. */
+    for (auto this_call : calls) {
+        IV(cout << "    " << this_call->call_description << " for asset "
+                << this_call->asset_info.get_name() << endl;)
+        this_call->copy_call_to_asset();
+           /* Note:  this_call->the_asset will now point to the asset
+                     associated with this_call, if any such asset exists. */
+        if (this_call->asset_info.the_asset != nullptr) {
+            /* If the asset exists, allow changes to it to affect other active
+               assets. */
+            asset_state_changed = false;
+            do {
+               for (auto this_asset : active_sst_asset) {
+                   asset_state_changed |= this_asset->simulate();
+               }
+               for (auto this_asset : active_policy_asset) {
+                   asset_state_changed |= this_asset->simulate();
+               }
+               for (auto this_asset : active_key_asset) {
+                   asset_state_changed |= this_asset->simulate();
+               }
+            } while (asset_state_changed);
+        }
+        this_call->copy_asset_to_call();
+    }
+}
+
+
+/* Parse command-line parameters.  exit() if error(s) found.  Place results into
+   the resource object. */
+void tf_fuzz_info::parse_cmd_line_params (int argc, char* argv[])
+{
+    int exit_val = 0;  // the linux return value, default 0, meaning all-good
+    vector<string> cmd_line_parameter, cmd_line_switch;
+        // (STL) vectors of hard cmd_line_parameter and cmd_line_switches
+    int n_parameters = 0, n_switches = 0;
+        // counting off cmd_line_parameter and cmd_line_switches while parsing
+    char testc;
+
+    // Parse arguments into lists of strings:
+    for (int i = 1;  i < argc;  ++i) {
+        if (argv[i][0] == '-') {  // cmd_line_switch
+            if (argv[i][1] == '-') {  // double-dash
+                cmd_line_switch.push_back (string(argv[i]+2));
+            } else {  // single-dash cmd_line_switch;  fine either way
+                cmd_line_switch.push_back (string(argv[i]+1));
+            }
+            ++n_switches;
+        } else {  // hard cmd_line_parameter
+            cmd_line_parameter.push_back(argv[i]);
+            ++n_parameters;
+        }
+    }
+    // If too-few or too many cmd_line_parameter supplied
+    for (int i = 0;  i < n_switches;  ++i) {
+        // If usage string requested...
+        if (cmd_line_switch[i] == "h") {
+            exit_val = 10;
+        }
+        // If verbose requested, make note:
+        if (cmd_line_switch[i] == "v") {
+            verbose_mode = true;
+        }
+    }
+    if (exit_val == 10) {  // -h switch
+        cout << "\nHow to run TF-Fuzz:" << endl;
+    } else if (n_parameters < 2) {
+        cerr << "\nToo few command-line parameters." << endl;
+        exit_val = 11;
+    } else if (n_parameters > 3) {
+        cerr << "\nToo many command-line parameters." << endl;
+        exit_val = 12;
+    } else {
+        template_file_name = cmd_line_parameter[0];
+        template_file = fopen (template_file_name.c_str(), "r");
+        test_output_file_name = cmd_line_parameter[1];
+        output_C_file.open (test_output_file_name, ios::out);
+        if (n_parameters == 3) {
+            /* TODO:  The try-catch below doesn't always seem to work.  For now,
+               manually "catch" the most basic problem: */
+            testc = cmd_line_parameter[2][0];
+            if (testc < '0' || testc > '9') {
+                cerr << "\nError:  Random-seed value (third parameter) could "
+                     << "not be interpreted as a number." << endl;
+                rand_seed = 0;
+            } else {
+                try {
+                    rand_seed = stol (cmd_line_parameter[2], 0, 0);
+                } catch (int excep) {
+                    excep = 0;  // (keep compiler from complaining about not using excep)
+                    cerr << "\nWarning:  Random-seed value (third parameter) could "
+                         << "not be interpreted as a number." << endl;
+                    rand_seed = 0;
+                }
+            }
+        }
+        if (rand_seed == 0 || n_parameters < 3) {
+            if (n_parameters < 3) {
+                cout << "Info:  random seed was not specified." << endl;
+            } else {
+                cout << "Warning:  random seed, " << cmd_line_parameter[2]
+                     << ", was not usable!" << endl;
+            }
+            srand((unsigned int) time(0));  // TODO:  ideally, XOR or add in PID#
+            rand_seed = rand();
+                /* doesn't really matter, but it just "feels better" when the
+                   default seed value is itself more random. */
+        }
+        cout << endl << "Using seed value of " << dec << rand_seed << " " << hex
+             << "(0x" << rand_seed << ")." << endl;
+        srand(rand_seed);
+        if (template_file == NULL) {
+            cerr << "\nError:  Template file " << template_file_name
+                 << " could not be opened." << endl;
+            exit_val = 13;
+        } else if (!output_C_file.is_open()) {
+            // If test-output file couldn't be opened
+            cerr << "\nError:  Output C test file " << test_output_file_name
+                 << " could not be opened." << endl;
+            exit_val = 14;
+        }
+        // Default (not entirely worthless) purpose of the test:
+        test_purpose.assign (  "template = " + template_file_name + ", seed = "
+                             + to_string(rand_seed));
+    }
+    // Bad command line, or request for usage blurb, so tell them how to run us:
+    if (exit_val != 0) {
+        cout << endl << argv[0] << " usage:" << endl;
+        cout << "    Basic cmd_line_parameter (positional, in order, "
+             << "left-to-right):" << endl;
+        cout << "        Test-template file" << endl;
+        cout << "        Test-output .c file" << endl;
+        cout << "        (optional) random seed value" << endl;
+        cout << "    Optional switches:" << endl;
+        cout << "        -h or --h:  This help (command-line usage) summary."
+             << endl;
+        cout << "        -v or --v:  Verbose mode." << endl;
+        cout << "Examples:" << endl;
+        cout << "    " << argv[0] << " -h" << endl;
+        cout << "    " << argv[0] << " template.txt output_test.c 0x5EED" << endl;
+        exit (exit_val);
+    }
+}
+
+
+void tf_fuzz_info::add_call (psa_call *the_call, bool append_bool,
+                             bool set_barrier_bool) {
+    // For testing purposes only, uncomment this to force sequential ordering:
+    //append_bool = true;
+    vector<psa_call*>::size_type
+        barrier_pos = 0,
+            // barrier pos. before which calls for this asset may not be placed
+        insert_call_pos = 0,  // where to place the new call
+        i;  // loop index
+    bool barrier_found = false;
+    psa_call *candidate = nullptr;  // (not for long)
+
+    if (set_barrier_bool) {
+        // Prevent calls regarding this asset being placed before this call:
+        the_call->barrier.assign (the_call->target_barrier);
+        IV(cout << "Inserted barrier for asset " << the_call->barrier << "." << endl;)
+    }
+    if (append_bool || calls.size() == 0) {
+        // Just .push_back() onto the end if asked to, or if this is the first call:
+        calls.push_back (the_call);
+        IV(cout << "Appended to end of call sequence:  " << the_call->call_description
+                 << "." << endl;)
+        return;  // done, easy!
+    }
+    /* Now search for last call with a barrier for this asset.  (Note:  because
+       vector<psa_call*>::size_type is unsigned, we can't search backward from
+       .end(), decrementing past 0.  Also, cannot initialize barrier_pos to -1;
+       must maintain boolean for that.) */
+    for (i = 0ULL, barrier_found = false;  i < calls.size();  i++) {
+        candidate = calls[i];
+        if (candidate->barrier == the_call->target_barrier) {
+            barrier_pos = i;
+            barrier_found = true;
+        }
+    }
+    if (!barrier_found) {
+        /* STL-vector inserts occur *before* the stated index.  With no barrier
+           found, we want to insert somewhere between before .begin() and after
+           .end().  So, we want a number between 0 and calls.size(), inclusive. */
+        insert_call_pos = (rand() % (calls.size() + 1));
+        IV(cout << "No barrier for asset " << the_call->asset_info.get_name()
+                 << " found." << endl
+                 << "    Placing " << the_call->call_description
+                 << " at position " << insert_call_pos << " in call sequence."
+                 << endl;)
+    } else {
+        /* Insert at a random point between just after barrier and after the end
+           (including possibly after the end, but strictly after that barrier).
+           Since STL-vector inserts occur before the stated index, we want an
+           insertion point between the call after the barrier and calls.end(),
+           inclusive. */
+        insert_call_pos = (vector<psa_call*>::size_type)
+                          (   barrier_pos + 1  // must be *after* barrier-carrying call
+                           + (rand() % (calls.size() - barrier_pos))
+                          );
+        IV(cout << "Barrier for asset " << the_call->asset_info.get_name()
+                 << " found at position " << dec << barrier_pos << "." << endl;)
+    }
+    if (insert_call_pos == calls.size()) {
+        // Insert at end:
+        calls.push_back (the_call);
+        IV(cout << "Insertion position is at end of call list." << endl;)
+    } else {
+        // Insert before insert_call_position:
+        calls.insert (calls.begin() + insert_call_pos, the_call);
+        IV(cout << "Inserting " << the_call->call_description
+                 << " at position " << dec << insert_call_pos << " in call sequence."
+                 << endl;)
+    }
+}
+
+
+tf_fuzz_info::tf_fuzz_info (void)  // (constructor)
+{
+    this->bplate = new boilerplate();
+    test_purpose = template_file_name = test_output_file_name = "";
+    rand_seed = 0;
+    verbose_mode = false;
+    include_hashing_code = false;  // default
+}
+
+tf_fuzz_info::~tf_fuzz_info (void)
+{
+    delete bplate;
+}
+
+/**********************************************************************************
+   End of methods of class tf_fuzz_info.
+**********************************************************************************/
+
+
+int main(int argc, char* argv[])
+{
+    cout << "Trusted Firmware Fuzzer (TF-Fuzz) starting..." << endl << endl;
+
+    // Allocate "the world":
+    tf_fuzz_info *rsrc = new tf_fuzz_info;
+
+    // Parse parameters and open files:
+    rsrc->parse_cmd_line_params (argc, argv);
+
+    // Parse the test-template file:
+    yyin = rsrc->template_file;
+    int parse_result = yyparse (rsrc);
+
+    if (parse_result == 1) {
+        cerr << "\nError:  Template file has errors." << endl;
+    } else if (parse_result == 2) {
+        cerr << "\nError:  Sorry, TF-Fuzz ran out of memory." << endl;
+    }
+    cout << "Call sequence generated." << endl;
+
+    cout << "Simulating call sequence..." << endl;
+    rsrc->simulate_calls();
+
+    cout << "Writing test file, " << rsrc->test_output_file_name << "." << endl;
+    rsrc->write_test();
+    rsrc->output_C_file.close();
+
+    cout << endl << "TF-Fuzz test generation complete." << endl;
+    return 0;
+}
diff --git a/tf_fuzz/tf_fuzz.hpp b/tf_fuzz/tf_fuzz.hpp
new file mode 100644
index 0000000..ce9051f
--- /dev/null
+++ b/tf_fuzz/tf_fuzz.hpp
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef TF_FUZZ_HPP
+#define TF_FUZZ_HPP
+
+#include <string>
+#include <vector>
+#include <iostream>
+#include <fstream>
+
+
+/* This project's header files #including other project headers quickly becomes
+   unrealistically complicated.  The only solution is for each .cpp to include
+   the headers it needs.
+#include "psa_call.hpp"
+#include "sst_asset.hpp"
+#include "crypto_asset.hpp"
+#include "boilerplate.hpp"
+*/
+
+/* Shortcuts, to reduce code clutter, and reduce risk of coding errors. */
+#define IVM(content) if(rsrc->verbose_mode){content}  // IVM = "If Verbose Mode"
+#define IV(content) if(verbose_mode){content}  // Same, but for use by tf_fuzz methods
+
+
+// consts to help readability:
+const bool add_to_end = true;  // add a call to the end of the call vector
+const bool add_random_after_barrier = false;
+    /* add to the call list randomly after the latest barrier for this asset, and
+       as late as the end of the list. */
+const bool yes_set_barrier = true;  // create the call and set a barrier for that asset
+const bool dont_set_barrier = false;
+    // inserted call does not preclude calls related to that asset being placed earlier
+
+using namespace std;
+
+// class tf_fuzz_info mostly just groups together everything needed generate the test.
+class tf_fuzz_info
+{
+    /* In creating a test, TF-Fuzz parses the test template, creating a vector of
+       PSA-call-tracker objects.  TF-Fuzz then performs a simulation of those calls
+       -- simulation only in enough detail to predict expected results of those PSA
+       calls. After that simulation phase, write_test() writes it all out.  The
+       process of creating these structures also requires the boilerplate text
+       strings. */
+
+public:
+    // Data members (this class is mostly just to group stuff together, so public):
+        vector<string> prep_code;  // variable declarations to write out to test file
+        vector<psa_call*> calls;
+            /* the calls to perform:  Note:  must be vector *psa_call;  a vector of
+               psa_call does not allow (run-time) polymorphism. */
+        boilerplate *bplate;  // the boilerplate text for building the test
+        gibberish gibbergen;  // the gibberish asset-data generator
+        crc32 hashgen;  // simple 32-bit LFSR-based hashing generator
+        /* Note:  The following asset-lists are kept in base-class type to allow a
+                  common template-line processing function in tf_fuzz_grammar.y. */
+        vector<psa_asset*> active_sst_asset;  // list of known and usable SST assets
+        vector<psa_asset*> deleted_sst_asset;  // deleted SST assets
+        vector<psa_asset*> invalid_sst_asset;  // SST assets with invalid attributes
+        vector<psa_asset*> active_key_asset;  // list of known and usable keys
+        vector<psa_asset*> deleted_key_asset;  // deleted keys
+        vector<psa_asset*> invalid_key_asset;  // keys with invalid attributes
+        vector<psa_asset*> active_policy_asset;  // list of known, usable policies
+        vector<psa_asset*> deleted_policy_asset;  // deleted policies
+        vector<psa_asset*> invalid_policy_asset;  // policies with invalid attrs
+        /* The "variable" vector tracks variables in the generated code.  Actually,
+           it tracks variables explicitly named in the test template, and actual-data
+           holder variables from reading an asset.  It does not track asset set-data
+           or asset expect-data variables, because there are multiple versions of
+           those, and it's easier to just to "count off" those multiple versions.
+           Notice that, unlike the above vectors, the variable vector is not a
+           vector of pointers to variable_info objects, but of the objects themselves.
+           This is because polymorphism is not of concern here. */
+        vector<variable_info> variable;
+        string test_purpose;  // what the test tests
+        long rand_seed;  // the original random seed, whether passed in or defaulted
+        string template_file_name, test_output_file_name;
+        FILE *template_file;
+            /* handle to the test-template input file.  Unfortunately I can't seem to
+               get lex/yacc to understand C++ file references, probably because I'm
+               "extern C"ing the Lex content (Yacc/Bison turns out to be a lot easier
+               to coerce into generating C++ code than (F)Lex). */
+        ofstream output_C_file;  // handle to the output C test file
+        bool verbose_mode;  // true to "think aloud"
+        bool include_hashing_code;  // true to instantiate the hashing code
+    // Methods:
+        asset_search find_or_create_sst_asset (
+            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,  // ignored if not searching on ID (e.g., SST UID)
+            long &serial_no,  // search by asset's unique serial number
+            bool create_asset,  // true to create the asset if it doesn't exist
+            vector<psa_asset*>::iterator &asset  // returns a pointer to asset
+        );
+        asset_search find_or_create_key_asset (
+            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,  // ignored if not searching on ID (e.g., SST UID)
+            long &serial_no,  // search by asset's unique serial number
+            bool create_asset,  // true to create the asset if it doesn't exist
+            vector<psa_asset*>:: iterator &asset  // returns iterator to asset
+        );
+        asset_search find_or_create_policy_asset (
+            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 by asset's unique serial number
+            bool create_asset,  // true to create the asset if it doesn't exist
+            vector<psa_asset*>::iterator &asset  // returns iterator to asset
+        );
+        asset_search find_or_create_psa_asset (
+            psa_asset_type asset_type,  // what type of asset to find
+            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 by asset's unique serial number
+            bool create_asset,  // true to create the asset if it doesn't exist
+            vector<psa_asset*>::iterator &asset  // returns iterator to asset
+        );
+        vector<variable_info>::iterator find_var (string var_name);
+        void parse_cmd_line_params (int argc, char* argv[]);
+            // parse command-line parameters, and open files
+        void add_call (psa_call *the_call, bool to_end, bool set_barrier_bool);
+            /* stuffs a new call into the call list, either sequentially or at a random
+               place after a "barrier" for that particular asset.  If set_barrier_bool
+               is true, it will prevent calls related to this asset from going before
+               this call. */
+        bool make_var (string var_name);
+        void simulate_calls (void);
+            // goes through generated calls calculating expected results
+        void write_test (void);  // writes out the test's .c file
+        void teardown_test(void);  // removes any PSA resources used in the test
+        tf_fuzz_info (void);  // (constructor)
+        ~tf_fuzz_info (void);
+
+protected:
+    // Data members:
+        vector<string> teardown_calls;
+            // list of PSA commands to remove assets left over upon test completion
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+/*--------------------------------------------------------------
+   Helper functions:
+--------------------------------------------------------------*/
+
+
+template<typename CALL_TYPE>
+void define_call (set_data_info set_data, bool random_data, bool fill_in_template,
+                 bool create_call, template_line *temLin, tf_fuzz_info *rsrc,
+                 bool to_end_bool, bool set_barrier_bool) {
+    CALL_TYPE *the_call;
+    gibberish gib;
+    char gib_buff[1000];
+    string t_string;
+
+    if (fill_in_template) {
+        if (set_data.literal_data_not_file) {
+            if (random_data) {
+                int rand_data_length = 12 + (rand() % 800);
+                gib.sentence (gib_buff, gib_buff + rand_data_length - 1);
+                t_string = gib_buff;
+                temLin->set_data.set_calculated (t_string);
+            }
+        } else {
+            if (set_data.file_path == "") {  // catch the most likely failure at least!
+                cerr << "Error:  Tool-internal:  Please report error "
+                     << "#407 to the TF-Fuzz developers." << endl;
+                exit(407);
+            }
+            temLin->set_data.set_file (set_data.file_path);
+                // set in sst_asset_make_file_path
+        }
+    }
+    if (create_call) {
+        the_call = new CALL_TYPE (rsrc, temLin->call_ser_no,
+                                  temLin->asset_info.how_asset_found);
+        if (!temLin->copy_template_to_call (the_call)) {
+            cerr << "Error:  Tool-internal:  Please report error "
+                 << "#402 to the TF-Fuzz developers." << endl;
+            exit(402);
+        }
+        rsrc->add_call (the_call, to_end_bool, set_barrier_bool);
+    }
+}
+
+#endif  // #ifndef TF_FUZZ_HPP
diff --git a/tf_fuzz/tf_fuzz.o b/tf_fuzz/tf_fuzz.o
new file mode 100644
index 0000000..0e33578
--- /dev/null
+++ b/tf_fuzz/tf_fuzz.o
Binary files differ
diff --git a/tf_fuzz/tfz b/tf_fuzz/tfz
new file mode 100755
index 0000000..7d588ca
--- /dev/null
+++ b/tf_fuzz/tfz
Binary files differ
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
diff --git a/tf_fuzz/visualStudio/README b/tf_fuzz/visualStudio/README
new file mode 100644
index 0000000..faa99b2
--- /dev/null
+++ b/tf_fuzz/visualStudio/README
@@ -0,0 +1,10 @@
+This is just things to support running and debug under Microsoft Visual Studio
+(tm).
+
+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/visualStudio_dir.html
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/visualStudio/unistd.c b/tf_fuzz/visualStudio/unistd.c
new file mode 100644
index 0000000..7e21cc5
--- /dev/null
+++ b/tf_fuzz/visualStudio/unistd.c
@@ -0,0 +1,3 @@
+int isatty(int arg) {
+	return 0;
+}
\ No newline at end of file
diff --git a/tf_fuzz/visualStudio/unistd.h b/tf_fuzz/visualStudio/unistd.h
new file mode 100644
index 0000000..613ed5f
--- /dev/null
+++ b/tf_fuzz/visualStudio/unistd.h
@@ -0,0 +1,2 @@
+#pragma once
+int isatty(int);
\ No newline at end of file