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/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;