tf_fuzz: add new crypto key generation model

* Add a new model of what it means for a crypto policy to be valid. This
  fixes the simulation of psa_generate_key() calls, which TF-Fuzz
  currently cannot accurately predict.

  The PSA Crypto properties modelled are whether an algorithm and key
  type are compatible, whether a key type/ algorithm are disabled, and
  what key sizes are allowed.

  Although the PSA Crypto specification has additional, more complicated
  requirements for policies and keys, this commit only implements what
  is necessary for predicting the outcome of psa_generate_key(), and not
  requirements that make a key useless but still valid or involve
  features not yet in TF-M or MbedTLS.

* Improve the way in which policies are filled in, and allow policies to
  be updated at simulation time using the value of a named policy asset.
  Information about other assets and calls is not accessible during
  parse time when the key policy is usually filled in. However, this is
  required for the improved simulation of psa_generate_key calls. This
  is because policy information for generate key calls come from a named
  policy created earlier in the test file.

* Add valid flag to set-policy calls, allowing the creation of a random
  valid policy. For example, see demo/36.test.

* Add demo/36.test. This test generates a policy with a (roughly) even
  chance of being valid or invalid and then tries to generate a key
  using it.

  Running this test a large number of times (~300) succeeds with the
  changes in this commit, showing that TF-Fuzz can now accurately
  predict the outcome of psa_generate_key calls.

Change-Id: Ia40ff893db50b8d2c579d975aa23341b7aab004d
Signed-off-by: Nik Dewally <Nik.Dewally@arm.com>
diff --git a/tf_fuzz/tfz-cpp/utility/data_blocks.cpp b/tf_fuzz/tfz-cpp/utility/data_blocks.cpp
index 5683b06..d80d46f 100644
--- a/tf_fuzz/tfz-cpp/utility/data_blocks.cpp
+++ b/tf_fuzz/tfz-cpp/utility/data_blocks.cpp
@@ -15,7 +15,7 @@
 #include <vector>
 #include <iostream>
 
-#include "randomization.hpp"
+#include "fill_in_policy.hpp"
 #include "gibberish.hpp"
 #include "data_blocks.hpp"
 #include "find_or_create_asset.hpp"
@@ -359,25 +359,24 @@
 {
     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();
+    exportable = false;
+    copyable = false;
+    can_encrypt = false;
+    can_decrypt = false;
+    can_sign = false;
+    can_verify = false;
+    derivable= false;
+    persistent= false;
+
+    get_policy_from_policy = "";
+    key_type = "";
+    key_algorithm = "";
+    n_bits = 0;
+
     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;
@@ -389,7 +388,15 @@
     gib->sentence (buffer, buffer + (40ULL + (uint64_t) (rand() % 200)));
     key_data = buffer;
     delete gib;
+
 }
+
+key_policy_info key_policy_info::create_random() {
+    key_policy_info policy;
+    fill_in_policy(policy,false);
+    return policy;
+}
+
 key_policy_info::~key_policy_info (void)  // (destructor)
 {
     return;  // (even if only to have something to pin a breakpoint on)
diff --git a/tf_fuzz/tfz-cpp/utility/data_blocks.hpp b/tf_fuzz/tfz-cpp/utility/data_blocks.hpp
index 9f6cfc2..03b1294 100644
--- a/tf_fuzz/tfz-cpp/utility/data_blocks.hpp
+++ b/tf_fuzz/tfz-cpp/utility/data_blocks.hpp
@@ -213,21 +213,46 @@
 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;
+      here is a key that uses the policy, and not the policy itself. */
+    bool get_policy_from_key;
+
+    // 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 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 verifying 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.
+     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>.
+
+    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>.
@@ -258,7 +283,16 @@
     ~key_policy_info (void);  // (destructor)
 
 
+    /** Creates a random, but not necessarily valid, policy */
+    static key_policy_info create_random();
+
+
 protected:
+
+    /* 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. */
     // Data members:
     bool data_matches_asset;
     /* true if template specifies expected data, and that expected data
diff --git a/tf_fuzz/tfz-cpp/utility/randomization.cpp b/tf_fuzz/tfz-cpp/utility/randomization.cpp
deleted file mode 100644
index ded87bb..0000000
--- a/tf_fuzz/tfz-cpp/utility/randomization.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2019-2024, 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.
-**********************************************************************************/
-
-// TODO: the key usages, algorithms, and types are currently incomplete.
-
-#include "randomization.hpp"
-
-#include <stdlib.h>
-
-/**
- * \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_HASH";
-        case 4:  return "PSA_KEY_USAGE_VERIFY_HASH";
-        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() % 24) {
-        case 0:  return "PSA_ALG_MD5";
-        case 1:  return "PSA_ALG_RIPEMD160";
-        case 2:  return "PSA_ALG_SHA_1";
-        case 3:  return "PSA_ALG_SHA_224";
-        case 4:  return "PSA_ALG_SHA_256";
-        case 5:  return "PSA_ALG_SHA_384";
-        case 6:  return "PSA_ALG_SHA_512";
-        case 7:  return "PSA_ALG_SHA_512_224";
-        case 8:  return "PSA_ALG_SHA_512_256";
-        case 9:  return "PSA_ALG_SHA3_224";
-        case 10:  return "PSA_ALG_SHA3_256";
-        case 11:  return "PSA_ALG_SHA3_384";
-        case 12:  return "PSA_ALG_SHA3_512";
-        case 13:  return "PSA_ALG_ANY_HASH";
-        case 14:  return "PSA_ALG_CBC_MAC";
-        case 15:  return "PSA_ALG_CMAC";
-        case 16:  return "PSA_ALG_CTR";
-        case 17:  return "PSA_ALG_CFB";
-        case 18:  return "PSA_ALG_OFB";
-        case 19:  return "PSA_ALG_XTS";
-        case 20:  return "PSA_ALG_CBC_NO_PADDING";
-        case 21:  return "PSA_ALG_CBC_PKCS7";
-        case 22:  return "PSA_ALG_CCM";
-        case 23:  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() % 9) {
-        case 0:  return "PSA_KEY_TYPE_NONE";
-        case 1:  return "PSA_KEY_TYPE_RAW_DATA";
-        case 2:  return "PSA_KEY_TYPE_HMAC";
-        case 3:  return "PSA_KEY_TYPE_DERIVE";
-        case 4:  return "PSA_KEY_TYPE_AES";
-        case 5:  return "PSA_KEY_TYPE_DES";
-        case 6:  return "PSA_KEY_TYPE_CAMELLIA";
-        case 7:  return "PSA_KEY_TYPE_RSA_PUBLIC_KEY";
-        case 8:  return "PSA_KEY_TYPE_RSA_KEY_PAIR";
-    }
-    return "";  /* placate compiler */
-}
diff --git a/tf_fuzz/tfz-cpp/utility/randomization.hpp b/tf_fuzz/tfz-cpp/utility/randomization.hpp
deleted file mode 100644
index b47742a..0000000
--- a/tf_fuzz/tfz-cpp/utility/randomization.hpp
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (c) 2019-2024, 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 */