/* * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * */ #ifndef TF_FUZZ_HPP #define TF_FUZZ_HPP #include #include #include #include /* 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" */ using namespace std; /* class tf_fuzz_info mostly just groups together everything needed to gather, then write out the test. This, so that they can be passed into the parser. */ class tf_fuzz_info { /* In creating a test, TF-Fuzz collects together a vector of strings cataloging data structures used by PSA commands, and a vector of PSA call objects. Once the template is completely parsed, write_test() writes it all out. The process of creating these structures also requires the boilerplate text strings. In the process of building the test, it must track PSA assets to "model" expected results of calls. */ public: // Data members (this class is mostly just to group stuff together, so public): vector prep_code; // variable declarations to write out to test file vector 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 active_sst_asset; // list of known and usable SST assets vector deleted_sst_asset; // deleted SST assets vector invalid_sst_asset; // SST assets with invalid attributes vector active_key_asset; // list of known and usable keys vector deleted_key_asset; // deleted keys vector invalid_key_asset; // keys with invalid attributes vector active_policy_asset; // list of known, usable policies vector deleted_policy_asset; // deleted policies vector invalid_policy_asset; // policies with invalid attrs string test_purpose; // one text substitution to be performed at the top level 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::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, // 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:: 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::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::iterator &asset // returns iterator to asset ); void teardown_test(void); // removes any PSA resources used in the test void write_test (void); // returns success==true, fail==false void parse_cmd_line_params (int argc, char* argv[]); // parse command-line parameters, and open files tf_fuzz_info (void); // (constructor) ~tf_fuzz_info (void); protected: // Data members: vector teardown_calls; // list of PSA commands to remove assets left over upon test completion // Methods: private: // Data members: // Methods: }; /*-------------------------------------------------------------- Helper functions: --------------------------------------------------------------*/ template 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 ) { 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 = 10 + (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) { if (temLin->how_asset_found == asset_search::unsuccessful) { cerr << "Error: Tool-internal: Please report error " << "#401 to the TF-Fuzz developers." << endl; exit(401); } the_call = new CALL_TYPE (rsrc, temLin->call_ser_no, temLin->how_asset_found); rsrc->calls.push_back(the_call); /* (note: this is not a memory leak!) */ temLin->copy_template_to_asset(); if (!temLin->copy_template_to_call()) { cerr << "Error: Tool-internal: Please report error " << "#402 to the TF-Fuzz developers." << endl; exit(402); } } } #endif // #ifndef TF_FUZZ_HPP