tf_fuzz: fix key import and export simulation

Fix the simulation of psa_import_key() and psa_export_key(). This fixes
demo/28.test.

* This patch moves the existing simulation code for these calls from
  code generation methods to a new simulate() method, as described in
  ub52d00b (tf_fuzz: add new crypto key generation model, 2024-08-02).

* Extend the simulation code for `import_key_call` to check whether the
  key policy is valid when calculating the expected result of the call.
  This uses the new crypto simulation methods introduced in b52d00b
  (tf_fuzz: add new crypto key generation model, 2024-08-02).

* Extend the simulation code for `read_key_call` (the call for
  `psa_export_key()`).

* Allow `copy_policy_to_call` to fetch policy information from key
  assets as well as policy assets.

  Previously if a call used the policy of another policy or key asset,
  the details of that policy was not stored in the call at all. To fix
  this, b52d00b (tf_fuzz: add new crypto key generation model,
  2024-08-02) added `copy_policy_to_call`, which copies policy
  information into a call at simulation time from a named policy asset.

  To correctly calculate the expected result of `read_key_call`, the
  keys policy needs to be checked for the exportable usage flag. This
  patch makes `copy_policy_to_call` able to fetch the policy of both a
  key asset and a policy asset and copy it into the call, providing the
  information necessary to do this check.

* Since the `create_key_call` was named, psa_create_key() has been
  removed from PSA Crypto, and replaced with psa_import_key(). Rename
  `create_key_call` to `import_key_call` to reflect this.

* In tests that use import (demo/28 and demo/32), set policy key size to
  0.

  In a key policy, size=0 means that the size of the key does not
  matter. This change is necessary for the functioning of
  psa_import_key, as the size of the data to be imported to the key is
  unknown at policy-creation time.

Change-Id: I49ca3a6fa2d7d2e0deb958a15f9671f3d7c1365c
Signed-off-by: Nik Dewally <Nik.Dewally@arm.com>
diff --git a/tf_fuzz/demo/28.test b/tf_fuzz/demo/28.test
index 0faee18..cc9e7c5 100644
--- a/tf_fuzz/demo/28.test
+++ b/tf_fuzz/demo/28.test
@@ -1,4 +1,12 @@
 purpose to create a key, then read the key data ("material") into a variable;
-set policy name somePolicy alg cfb attr noexport volatile valid;
+
+1 of {
+// key policy must be set to 0 for import to work -- this tells PSA Crypto that
+// we don't care about the size of the key
+set policy name somePolicy attr noexport volatile size 0 valid;
+set policy name somePolicy attr export volatile size 0 valid;
+set policy name somePolicy attr export volatile valid;
+set policy name somePolicy attr export volatile valid;
+}
 set key name aKey data * policy somePolicy;
 read key name aKey var keyDataVar;
diff --git a/tf_fuzz/demo/32.test b/tf_fuzz/demo/32.test
index 7c575af..a879162 100644
--- a/tf_fuzz/demo/32.test
+++ b/tf_fuzz/demo/32.test
@@ -1,4 +1,4 @@
 purpose to create then remove a key;
-set policy name somePolicy attr sign verify copy alg stream_cipher;
+set policy name somePolicy attr sign verify copy size 0 valid;
 set key name akey data * policy somePolicy;
 remove key name akey;
diff --git a/tf_fuzz/lib/tfm_boilerplate.txt b/tf_fuzz/lib/tfm_boilerplate.txt
index d7bbb90..9c89b09 100644
--- a/tf_fuzz/lib/tfm_boilerplate.txt
+++ b/tf_fuzz/lib/tfm_boilerplate.txt
@@ -105,7 +105,7 @@
 `005
     static uint8_t $var[] = "$init";
 `006
-    static uint8_t $var[2048] = "$init";
+    static uint8_t $var[PSA_EXPORT_KEY_PAIR_MAX_SIZE] = "$init";
 `007
     static size_t $var = $init;
 `008
@@ -245,13 +245,14 @@
     crypto_status = psa_generate_key (&$policy, &$key);
 `051
     if (crypto_status != $expect && crypto_status != PSA_ERROR_INSUFFICIENT_MEMORY) {
+        TEST_LOG("(got status code %d)",crypto_status);
         TEST_FAIL("psa_generate_key() expected $expect.");
         return;
     }
 
     if (crypto_status == PSA_ERROR_INSUFFICIENT_MEMORY) {
         TEST_FAIL("psa_generate_key() call ran out of memory. To test this combination, try increasing the MbedTLS static allocator memory.");
-        TEST_LOG("psa_generate_key() call ran out of memory. To test this combination, try increasing the MbedTLS static allocator memory.");
+        TEST_LOG("psa_generate_key() call ran out of memory. To test this combination, try increasing the MbedTLS static allocator memory.\n");
         ret->val = TEST_SKIPPED;
         return;
     }
@@ -259,15 +260,22 @@
     crypto_status
         = psa_import_key (&$policy, $data, $length, &$key);
 `053
-    if (crypto_status != $expect) {
+    if (crypto_status != $expect && crypto_status != PSA_ERROR_INSUFFICIENT_MEMORY) {
         TEST_FAIL("psa_import_key() expected $expect.");
+        TEST_LOG("(got status code %d)",crypto_status);
+        return;
+    }
+    if (crypto_status == PSA_ERROR_INSUFFICIENT_MEMORY) {
+        TEST_FAIL("psa_generate_key() call ran out of memory. To test this combination, try increasing the MbedTLS static allocator memory.");
+        TEST_LOG("psa_generate_key() call ran out of memory. To test this combination, try increasing the MbedTLS static allocator memory.\n");
+        ret->val = TEST_SKIPPED;
         return;
     }
 `054
     crypto_status = psa_copy_key ($master, $policy, $copy);
 `055
     if (crypto_status != $expect) {
-        TEST_FAIL("psa_export_key() expected $expect.");
+        TEST_FAIL("psa_copy_key() expected $expect.");
         return;
     }
 `056
@@ -281,8 +289,17 @@
     crypto_status
         = psa_export_key ($key, $data, $length, &$act_size);
 `058
-    if (crypto_status != $expect) {
+    if (crypto_status != $expect && crypto_status != PSA_ERROR_BUFFER_TOO_SMALL) {
         TEST_FAIL("psa_export_key() expected $expect.");
+        TEST_LOG("(got status code %d)",crypto_status);
+        return;
+    }
+
+    if (crypto_status == PSA_ERROR_BUFFER_TOO_SMALL) {
+        // tfz cannot currently calculate this buffer size automatically.
+        TEST_FAIL("Too small a buffer was assigned for the output of psa_export_key(). To increase buffer size, edit entry 006 of lib/tfm_boilerplate.txt.");
+        TEST_LOG("Too small a buffer was assigned for the output of psa_export_key(). To increase buffer size, edit entry 006 of lib/tfm_boilerplate.txt.");
+        ret->val = TEST_SKIPPED;
         return;
     }
 `059
diff --git a/tf_fuzz/tfz-cpp/Makefile b/tf_fuzz/tfz-cpp/Makefile
index e0a099f..e68e821 100644
--- a/tf_fuzz/tfz-cpp/Makefile
+++ b/tf_fuzz/tfz-cpp/Makefile
@@ -14,6 +14,14 @@
 		  $(wildcard utility/*.cpp) \
 		  $(wildcard *.cpp)
 
+headers = $(wildcard assets/*.hpp) \
+          $(wildcard crypto_model/*.hpp) \
+		  $(wildcard boilerplate/*.hpp) \
+		  $(wildcard calls/*.hpp) \
+		  $(wildcard template/*.hpp) \
+		  $(wildcard utility/*.hpp) \
+		  $(wildcard *.hpp)
+
 objs    = $(sources:.cpp=.o)
 depends = $(sources:.cpp=.d)
 
@@ -35,7 +43,7 @@
 	sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
 	rm -f $@.$$$$
 
-tfz: $(generated_includes) $(generated_objs) $(objs) Makefile
+tfz: $(generated_includes) $(generated_objs) $(objs) $(headers) Makefile
 	$(CXX) $(CXXFLAGS) -o tfz $(generated_objs) $(objs)
 
 parser/tf_fuzz_grammar.tab.hpp:  parser/tf_fuzz_grammar.y class_forwards.hpp \
diff --git a/tf_fuzz/tfz-cpp/calls/crypto_call.cpp b/tf_fuzz/tfz-cpp/calls/crypto_call.cpp
index c9d000d..92d3d2e 100644
--- a/tf_fuzz/tfz-cpp/calls/crypto_call.cpp
+++ b/tf_fuzz/tfz-cpp/calls/crypto_call.cpp
@@ -5,6 +5,7 @@
  *
  */
 
+#include <cstring>
 #include <stdint.h>
 #include <cstdlib>
 #include <iostream>
@@ -1039,7 +1040,7 @@
    Methods of class create_key_call follow:
 **********************************************************************************/
 
-create_key_call::create_key_call (tf_fuzz_info *test_state,    // (constructor)
+import_key_call::import_key_call (tf_fuzz_info *test_state,    // (constructor)
                                     long &call_ser_no,
                                     asset_search how_asset_found)
                                         : key_call(test_state, call_ser_no,
@@ -1051,18 +1052,66 @@
     check_code.assign (test_state->bplate->bplate_string[create_key_check]);
     call_description = "key-create call";
 }
-create_key_call::~create_key_call (void)
+import_key_call::~import_key_call (void)
 {
     return;  // just to have something to pin a breakpoint onto
 }
 
 
-bool create_key_call::copy_call_to_asset (void)
+bool import_key_call::copy_call_to_asset (void)
 {
     return copy_call_to_asset_t<key_asset*> (this, dont_create_asset);
 }
 
-void create_key_call::fill_in_prep_code (void)
+
+bool import_key_call::simulate (void) {
+    bool is_policy_valid;
+
+    string data_str  = set_data.get();
+    const char* data_buf = data_str.c_str();
+    size_t data_size = strlen(data_buf) * 8;
+
+    // RSA keys have a very specific binary format that is checked on import.
+    // a random / user given string almost certainly won't be valid here.
+    if  (policy.key_type == "PSA_KEY_TYPE_RSA_KEY_PAIR") {
+        is_policy_valid = false;
+
+    } else if (policy.key_type == "PSA_KEY_TYPE_PEPPER") {
+        is_policy_valid = false;
+
+    } else {
+        is_policy_valid=true;
+    }
+
+    // policy.n_bits == 0 means to PSA crypto that we don't care about key size
+    // (this is good for import)
+    if (policy.n_bits != 0 && policy.n_bits != data_size) {
+        is_policy_valid = false;
+    }
+
+    if (!is_policy_valid) {
+        // do not create a key when policy is invalid
+        exp_data.expect_failure();
+        return true;
+    }
+
+    // create an asset, and copy the information we want in it to it.
+    copy_call_to_asset_t<key_asset*> (this, yes_create_asset);
+    switch (asset_info.how_asset_found) {
+    case asset_search::created_new:
+        exp_data.expect_pass();
+
+        break;
+
+    default: // asset already exists!
+        exp_data.expect_failure();
+        break;
+    }
+
+    return true;
+};
+
+void import_key_call::fill_in_prep_code (void)
 {
     string var_name = asset_info.get_name();
     vector<variable_info>::iterator assign_variable;
@@ -1078,6 +1127,8 @@
         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);
@@ -1086,19 +1137,18 @@
         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;
+        t_string = set_data.get();
         find_replace_all ("$init", t_string, prep_code);
     }
 }
 
-void create_key_call::fill_in_command (void)
+void import_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 ("$length", to_string(strlen(set_data.get().c_str())), call_code);
     find_replace_all ("$key", asset_info.get_name(), call_code);
     // Calculate the expected results:
     fill_in_result_code();
@@ -1221,6 +1271,36 @@
     return copy_call_to_asset_t<key_asset*> (this, dont_create_asset);
 }
 
+bool read_key_data_call::simulate() {
+
+    copy_call_to_asset_t<key_asset*> (this, dont_create_asset);
+    switch (asset_info.how_asset_found) {
+    case asset_search::found_active:
+        exp_data.expect_pass();
+
+        // Can always export public keys but all other keys need USAGE_EXPORT.
+        if (!policy.exportable && policy.key_type != "PSA_KEY_TYPE_RSA_PUBLIC_KEY") {
+            exp_data.expect_error_code("PSA_ERROR_NOT_PERMITTED");
+        }
+        break;
+
+    case asset_search::found_deleted:
+    case asset_search::found_invalid:
+    case asset_search::not_found:
+        exp_data.expect_error_code("PSA_ERROR_INVALID_HANDLE");
+        break;
+
+    // should never happen in this case
+    case asset_search::unsuccessful:
+    case asset_search::created_new:
+    case asset_search::something_wrong:
+        exp_data.expect_failure();
+        break;
+    }
+
+    return true;
+}
+
 void read_key_data_call::fill_in_prep_code (void)
 {
     string var_name, length_var_name, actual_length_var_name, var_name_suffix,
@@ -1332,15 +1412,6 @@
     find_replace_1st ("$act_size", actual_length_var_name, call_code);
     find_replace_1st ("$length", length_var_name, call_code);
 
-    // TODO: move error checking code to simulate().
-
-    // TODO:  check data?
-
-    // See if the source key did not exist:
-    if (!policy.exportable) {
-        // See if the source key does not support export:
-        exp_data.expect_error_code("PSA_ERROR_NOT_PERMITTED");
-    }
     fill_in_result_code();
 }
 
diff --git a/tf_fuzz/tfz-cpp/calls/crypto_call.hpp b/tf_fuzz/tfz-cpp/calls/crypto_call.hpp
index 9d6b457..93eb0be 100644
--- a/tf_fuzz/tfz-cpp/calls/crypto_call.hpp
+++ b/tf_fuzz/tfz-cpp/calls/crypto_call.hpp
@@ -484,17 +484,16 @@
 };
 
 
-class create_key_call : public key_call
+class import_key_call : public key_call
 {
 public:
-    // Data members:
-    // Methods:
-        bool copy_call_to_asset (void) override;
-        void fill_in_prep_code (void) override;
-        void fill_in_command (void) override;
-        create_key_call (tf_fuzz_info *test_state, long &asset_ser_no,
+    bool copy_call_to_asset (void) override;
+    void fill_in_prep_code (void) override;
+    void fill_in_command (void) override;
+    bool simulate (void) override;
+    import_key_call (tf_fuzz_info *test_state, long &asset_ser_no,
                          asset_search how_asset_found);  // (constructor)
-        ~create_key_call (void);
+    ~import_key_call (void);
 
 
 protected:
@@ -533,14 +532,13 @@
 class read_key_data_call : public key_call
 {
 public:
-    // Data members:
-    // Methods:
-        bool copy_call_to_asset (void) override;
-        void fill_in_prep_code (void) override;
-        void fill_in_command (void) override;
-        read_key_data_call (tf_fuzz_info *test_state, long &asset_ser_no,
-                            asset_search how_asset_found);  // (constructor)
-        ~read_key_data_call (void);
+    bool copy_call_to_asset (void) override;
+    bool simulate (void) override;
+    void fill_in_prep_code (void) override;
+    void fill_in_command (void) override;
+    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:
diff --git a/tf_fuzz/tfz-cpp/calls/psa_call.cpp b/tf_fuzz/tfz-cpp/calls/psa_call.cpp
index c9763aa..d5b5130 100644
--- a/tf_fuzz/tfz-cpp/calls/psa_call.cpp
+++ b/tf_fuzz/tfz-cpp/calls/psa_call.cpp
@@ -75,39 +75,56 @@
 
 void psa_call::copy_policy_to_call(void) {
 
-    string name = policy.get_policy_from_policy;
-
-    // name represents the policy asset we want to use for this call.
-
-    // We don't want to use a policy asset, so we have nothing to do here.
-    if (name == ""){
+    if (policy.get_policy_info_from == ""){
         return;
     }
 
+    string asset_name = policy.get_policy_info_from;
+
     vector<psa_asset*>::iterator found_asset;
     long x; // doesnt matter
-    asset_search status = test_state->find_or_create_policy_asset(psa_asset_search::name,psa_asset_usage::all,name,0,x,dont_create_asset,found_asset);
+    asset_search status = test_state->find_or_create_policy_asset(psa_asset_search::name,psa_asset_usage::all,asset_name,0,x,dont_create_asset,found_asset);
 
     switch (status) {
 
     case asset_search::found_active:
     case asset_search::found_deleted:
-    case asset_search::found_invalid:
-        break;
+    case asset_search::found_invalid: {
+        string handle = policy.handle_str;
+        string asset_2_name = policy.asset_2_name;
+        string asset_3_name = policy.asset_3_name;
 
+        policy = found_asset[0]->policy;
+        policy.handle_str = handle;
+        policy.asset_2_name = asset_2_name;
+        policy.asset_3_name = asset_3_name;
+        return;
+    }
     default:
-        cerr << "Fatal: could not find policy asset " << name << endl;
-        exit(1);
+        break;
     }
 
-    string handle = policy.handle_str;
-    string asset_2_name = policy.asset_2_name;
-    string asset_3_name = policy.asset_3_name;
+    status = test_state->find_or_create_key_asset(psa_asset_search::name,psa_asset_usage::all,asset_name,0,x,dont_create_asset,found_asset);
 
-    policy = found_asset[0]->policy;
-    policy.handle_str = handle;
-    policy.asset_2_name = asset_2_name;
-    policy.asset_3_name = asset_3_name;
+    switch (status) {
+
+    case asset_search::found_active:
+    case asset_search::found_deleted:
+    case asset_search::found_invalid: {
+        string handle = policy.handle_str;
+        string asset_2_name = policy.asset_2_name;
+        string asset_3_name = policy.asset_3_name;
+
+        policy = found_asset[0]->policy;
+        policy.handle_str = handle;
+        policy.asset_2_name = asset_2_name;
+        policy.asset_3_name = asset_3_name;
+        break;
+    }
+    default:
+        break;
+    }
+
 }
 
 /**********************************************************************************
diff --git a/tf_fuzz/tfz-cpp/calls/psa_call.hpp b/tf_fuzz/tfz-cpp/calls/psa_call.hpp
index 9a497c0..4787792 100644
--- a/tf_fuzz/tfz-cpp/calls/psa_call.hpp
+++ b/tf_fuzz/tfz-cpp/calls/psa_call.hpp
@@ -83,13 +83,13 @@
     /// never be overwritten.
     virtual bool simulate (void);
 
-    // Update policy information in the call based on the policy
-    // asset specified in policy.get_policy_from_policy. If this is unset,
+    // Update policy information in the call based on the policy or key
+    // asset specified in policy.get_policy_info_from. If this is unset,
     // the existing values are used as-is.
     //
     // This enables the simulation time setting of the policy.
     //
-    // See `key_policy_info.get_policy_from_policy`.
+    // See `key_policy_info.get_policy_info_from`.
     void copy_policy_to_call(void);
 
     // TODO: move simulation and error modelling code code into simulate().
diff --git a/tf_fuzz/tfz-cpp/class_forwards.hpp b/tf_fuzz/tfz-cpp/class_forwards.hpp
index 893cdd9..5131bd0 100644
--- a/tf_fuzz/tfz-cpp/class_forwards.hpp
+++ b/tf_fuzz/tfz-cpp/class_forwards.hpp
@@ -70,7 +70,7 @@
 class print_policy_usage_call;
 class get_key_policy_call;
 class generate_key_call;
-class create_key_call;
+class import_key_call;
 class copy_key_call;
 class read_key_data_call;
 class remove_key_call;
diff --git a/tf_fuzz/tfz-cpp/crypto_model/crypto_model.cpp b/tf_fuzz/tfz-cpp/crypto_model/crypto_model.cpp
index e6b8caf..beec424 100644
--- a/tf_fuzz/tfz-cpp/crypto_model/crypto_model.cpp
+++ b/tf_fuzz/tfz-cpp/crypto_model/crypto_model.cpp
@@ -417,6 +417,7 @@
 }
 
 bool key_type::is_valid_key_size(uint size) {
+
     // (MbedTLS): size is always byte aligned
     if (size % 8 != 0) {
         return false;
diff --git a/tf_fuzz/tfz-cpp/crypto_model/fill_in_policy.cpp b/tf_fuzz/tfz-cpp/crypto_model/fill_in_policy.cpp
index 306d93a..e3b7181 100644
--- a/tf_fuzz/tfz-cpp/crypto_model/fill_in_policy.cpp
+++ b/tf_fuzz/tfz-cpp/crypto_model/fill_in_policy.cpp
@@ -17,7 +17,7 @@
 
   // in this scenario, the policy cant be filled out now, and the information
   // should be copied over later.
-  if (!policy_info.get_policy_from_policy.empty()) {
+  if (!policy_info.get_policy_info_from.empty()) {
         return;
   }
 
@@ -38,7 +38,9 @@
             policy_info.key_type = kt.get_string();
         }
 
-        if (policy_info.n_bits == 0) {
+        // key size of 0 tells psa crypto that we don't care.
+        // this is useful, for example, when importing data into a key.
+        if (policy_info.n_bits < 0) {
             policy_info.n_bits = kt.get_random_valid_key_size();
         }
 
@@ -51,7 +53,7 @@
             policy_info.key_algorithm= crypto_model::get_random_algorithm().get_string_with_hash();
         }
 
-        if (policy_info.n_bits == 0) {
+        if (policy_info.n_bits < 0) {
             policy_info.n_bits = crypto_model::get_random_key_size();
         }
     }
diff --git a/tf_fuzz/tfz-cpp/parser/tf_fuzz_grammar.y b/tf_fuzz/tfz-cpp/parser/tf_fuzz_grammar.y
index 9b93df5..41889a9 100644
--- a/tf_fuzz/tfz-cpp/parser/tf_fuzz_grammar.y
+++ b/tf_fuzz/tfz-cpp/parser/tf_fuzz_grammar.y
@@ -99,7 +99,7 @@
       get_key_policy_call       *getKeyPolCal = nullptr;
     key_call                    *keyCal = nullptr;
       generate_key_call         *genKeyCal = nullptr;
-      create_key_call           *creKeyCal = nullptr;
+      import_key_call           *creKeyCal = nullptr;
       copy_key_call             *copKeyCal = nullptr;
       read_key_data_call        *reaKeyDatCal = nullptr;
       remove_key_call           *remKeyCal = nullptr;
@@ -1139,6 +1139,13 @@
             policy_info.n_bits = num;
             IVM(cout << yytext << "\"" << endl;)
     }
+
+    | SIZE STAR{
+            IVM(cout << "Policy-Size: random \"" << flush;)
+            int num = atol(yytext);
+            policy_info.n_bits = -1;
+            IVM(cout << yytext << "\"" << endl;)
+    }
 policy_specs:
         %empty  /* nothing */
       | policy_spec policy_specs {
@@ -1176,7 +1183,7 @@
         NAME IDENTIFIER {
             IVM(cout << "policy-asset identifier list:  \"" << flush;)
             random_name = false;
-            policy_info.get_policy_from_key = false;
+            policy_info.generate_get_policy_from_key_call = false;
             asset_name = 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 */
@@ -1185,21 +1192,21 @@
         }
       | STAR ACTIVE {
             IVM(cout << "policy-asset random active:  \"" << flush;)
-            policy_info.get_policy_from_key = false;
+            policy_info.generate_get_policy_from_key_call = 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;
+            policy_info.generate_get_policy_from_key_call = 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;
+            policy_info.generate_get_policy_from_key_call = 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 */
@@ -1245,7 +1252,7 @@
       | POLICY IDENTIFIER {
             IVM(cout << "Key-set sources, explicitly-specified policy name:  "
                      << flush;)
-            policy_info.get_policy_from_policy = identifier;
+            policy_info.get_policy_info_from = identifier;
             policy_info.asset_2_name = identifier;  /* policy */
             /* Make note that key data (key material) was not specified: */
             IVM(cout << yytext << "\"" << endl;)
diff --git a/tf_fuzz/tfz-cpp/template/crypto_template_line.hpp b/tf_fuzz/tfz-cpp/template/crypto_template_line.hpp
index 40218e5..86e866a 100644
--- a/tf_fuzz/tfz-cpp/template/crypto_template_line.hpp
+++ b/tf_fuzz/tfz-cpp/template/crypto_template_line.hpp
@@ -125,10 +125,11 @@
                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) {
+            if (policy_info.generate_get_policy_from_key_call) {
                 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,
@@ -220,7 +221,7 @@
                                 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,
+                define_call<import_key_call> (set_info, random_data,
                                 fill_in_template, create_call, temLin, rsrc,
                                 add_to_end, yes_set_barrier);
             } else {
@@ -250,6 +251,8 @@
         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) {
+
+            temLin->policy_info.get_policy_info_from=temLin->asset_info.get_name();
             define_call<read_key_data_call> (set_data, random_data,
                             fill_in_template, create_call, temLin, rsrc,
                             add_to_end, yes_set_barrier);
diff --git a/tf_fuzz/tfz-cpp/utility/data_blocks.cpp b/tf_fuzz/tfz-cpp/utility/data_blocks.cpp
index d80d46f..7a62d6b 100644
--- a/tf_fuzz/tfz-cpp/utility/data_blocks.cpp
+++ b/tf_fuzz/tfz-cpp/utility/data_blocks.cpp
@@ -357,7 +357,7 @@
 
 key_policy_info::key_policy_info (void)  // (default constructor)
 {
-    get_policy_from_key = false;  // specify policy asset by a key that uses it.
+    generate_get_policy_from_key_call = false;
     copy_key = false;  // not copying one key to another
     exportable = false;
     copyable = false;
@@ -368,7 +368,7 @@
     derivable= false;
     persistent= false;
 
-    get_policy_from_policy = "";
+    get_policy_info_from = "";
     key_type = "";
     key_algorithm = "";
     n_bits = 0;
diff --git a/tf_fuzz/tfz-cpp/utility/data_blocks.hpp b/tf_fuzz/tfz-cpp/utility/data_blocks.hpp
index 03b1294..5294de0 100644
--- a/tf_fuzz/tfz-cpp/utility/data_blocks.hpp
+++ b/tf_fuzz/tfz-cpp/utility/data_blocks.hpp
@@ -211,80 +211,89 @@
 class key_policy_info
 {
 public:
-    // Data members:
-    // Digested info:
-    /* 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 get_policy_from_key;
+  /* if true, then we must get generate a call to get policy info from a stated
+    key. */
+  bool generate_get_policy_from_key_call;
 
-    // If set, the policy asset specified should be used to fill in the policy
-    // at simulation time. This overwrites the other values in the object.
-    //
-    // If blank, the values in the object are used as-is.
-    //
-    // See `psa_call::copy_policy_to_call`
-    string get_policy_from_policy;
+  // If set, the policy or key asset specified should be used to fill in the
+  // policy at simulation time. This overwrites the other values in the object.
+  //
+  // If blank, the values in the object are used as-is.
+  //
+  // See `psa_call::copy_policy_to_call`
+  string get_policy_info_from;
 
-    /* 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 implicit_policy;
-    bool copy_key = false;  // true to indicate copying one key to another
-    bool exportable=false;   // key data can be exported (viewed - fail exports if not).
-    bool copyable=false;     // can be copied (fail key-copies if not).
-    bool can_encrypt=false;  // OK for encryption (fail other uses).
-    bool can_decrypt=false;  // OK for decryption (fail other uses).
-    bool can_sign=false;     // OK for signing (fail other operations).
-    bool can_verify=false;   // OK for verifying a message signature (fail other uses).
-    bool derivable=false;    // OK for derive other keys (fail other uses).
-    bool persistent=false;   // must be deleted at the end of test.
+  /* 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 implicit_policy;
+  bool copy_key = false; // true to indicate copying one key to another
+  bool exportable =
+      false; // key data can be exported (viewed - fail exports if not).
+  bool copyable = false;    // can be copied (fail key-copies if not).
+  bool can_encrypt = false; // OK for encryption (fail other uses).
+  bool can_decrypt = false; // OK for decryption (fail other uses).
+  bool can_sign = false;    // OK for signing (fail other operations).
+  bool can_verify =
+      false; // OK for verifying a message signature (fail other uses).
+  bool derivable = false;  // OK for derive other keys (fail other uses).
+  bool persistent = false; // must be deleted at the end of test.
 
+  // no_<flag> denotes that <flag> must not be set in the key.
+  //
+  // For the above flags, truth means "must be set" and false means "don't
+  // care". Setting no_<flag> means "must not be set". no_<flag> takes
+  // presedence over <flag>.
 
-    // no_<flag> denotes that <flag> must not be set in the key.
-    //
-    // For the above flags, truth means "must be set" and false means "don't care".
-    // Setting no_<flag> means "must not be set". no_<flag> takes presedence over <flag>.
+  bool no_exportable = false;  // true to indicate that exportable must not be
+                               // set during randomisation
+  bool no_copyable = false;    // true to indicate that copyable must not be set
+                               // during randomisation
+  bool no_can_encrypt = false; // true to indicate that can_encrypt must not be
+                               // set during randomisation
+  bool no_can_decrypt = false; // true to indicate that can_decrypt must not be
+                               // set during randomisation
+  bool no_can_sign = false;    // true to indicate that can_sign must not be set
+                               // during randomisation
+  bool no_can_verify = false;  // true to indicate that can_verify must not be
+                               // set during randomisation
+  bool no_derivable = false;  // true to indicate that derivable must not be set
+                              // during randomisation
+  bool no_persistent = false; // true to indicate that persistent must not be
+                              // set during randomisation
 
-    bool no_exportable=false; // true to indicate that exportable must not be set during randomisation
-    bool no_copyable=false; // true to indicate that copyable must not be set during randomisation
-    bool no_can_encrypt=false; // true to indicate that can_encrypt must not be set during randomisation
-    bool no_can_decrypt=false; // true to indicate that can_decrypt must not be set during randomisation
-    bool no_can_sign=false; // true to indicate that can_sign must not be set during randomisation
-    bool no_can_verify=false; // true to indicate that can_verify must not be set during randomisation
-    bool no_derivable=false; // true to indicate that derivable must not be set during randomisation
-    bool no_persistent=false; // true to indicate that persistent must not be set during randomisation
+  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;
 
-    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
+  // The key size. If <0, this will be re-generated by fill_in_policy.
+  int n_bits=-1;
+  // 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)
+  // Methods:
+  key_policy_info(void);  // (default constructor)
+  ~key_policy_info(void); // (destructor)
 
-
-    /** Creates a random, but not necessarily valid, policy */
-    static key_policy_info create_random();
+  /** Creates a random, but not necessarily valid, policy */
+  static key_policy_info create_random();
 
 
 protected: