blob: c84d4d247a8b04b6b50e6036bbb19461ec9ef9ff [file] [log] [blame]
Karl Zhang3de5ab12021-05-31 11:45:48 +08001/*
Nik Dewally841612a2024-07-22 15:27:43 +01002 * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
Karl Zhang3de5ab12021-05-31 11:45:48 +08003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8/* These classes "cut down the clutter" by grouping together related data and
9 associated methods (most importantly their constructors) used in template_
10 line, psa_call, psa_asset (etc.). */
11
12#include <string>
13#include <vector>
14#include <cstdint>
15
16#include "class_forwards.hpp"
17
18#include "boilerplate.hpp"
19#include "randomization.hpp"
20#include "gibberish.hpp"
21#include "compute.hpp"
22#include "string_ops.hpp"
23#include "data_blocks.hpp"
24#include "psa_asset.hpp"
25#include "crypto_asset.hpp"
26#include "find_or_create_asset.hpp"
27#include "psa_call.hpp"
28#include "template_line.hpp"
29#include "tf_fuzz.hpp"
30
31
32
33/**********************************************************************************
34 Methods of class expect_info follow:
35**********************************************************************************/
36
37expect_info::expect_info (void) // (default constructor)
38{
39 pf_nothing = false; // by default, TF-Fuzz provides expected results
40 pf_pass = pf_fail = pf_specified = false;
41 pf_result_string.assign (""); data.assign ("");
42 data_var_specified = false;
43 data_var.assign (""); // name of expected-data variable
44 data_specified = false;
45 data_matches_asset = false;
46 data.assign ("");
47 pf_info_incomplete = true;
48 n_exp_vars = -1; // so the first reference is 0 (no suffix), then _1, _2, ...
49 expected_results_saved = false;
50}
51expect_info::~expect_info (void) // (destructor)
52{}
53
54void expect_info::set_pf_pass (void)
55{
56 pf_pass = true;
57 pf_fail = pf_nothing = pf_specified = false;
58 pf_result_string = "";
59}
60
61void expect_info::set_pf_fail (void)
62{
63 pf_fail = true;
64 pf_pass = pf_nothing = pf_specified = false;
65 pf_result_string = "";
66}
67
68void expect_info::set_pf_nothing (void)
69{
70 pf_nothing = true;
71 pf_fail = pf_pass = pf_specified = false;
72 pf_result_string = "";
73}
74
75void expect_info::set_pf_error (string error)
76{
77 pf_specified = true;
78 pf_result_string.assign (error); // just default "guess," to be filled in
79 pf_pass = pf_fail = pf_nothing = false;
80}
81
82/* The expected pass/fail results are not available from the parser until the call has
83 already been created. The flag, pf_info_incomplete, that indicates whether or not
84 the "expects" information has been filled in. If not, fill it in from the template,
85 once that info has been parsed. */
86void expect_info::copy_expect_to_call (psa_call *the_call)
87{
88 the_call->exp_data.pf_nothing = pf_nothing;
89 the_call->exp_data.pf_pass = pf_pass;
90 the_call->exp_data.pf_fail = pf_fail;
91 the_call->exp_data.pf_specified = pf_specified;
92 the_call->exp_data.pf_result_string = pf_result_string;
93 the_call->exp_data.expected_results_saved = true;
94 the_call->exp_data.pf_info_incomplete = false;
95}
96
97/**********************************************************************************
98 End of methods of class expect_info.
99**********************************************************************************/
100
101
102/**********************************************************************************
103 Class set_data_info methods regarding setting and getting asset-data values:
104**********************************************************************************/
105
106string set_data_info::rand_creation_flags (void)
107{
Karl Zhang3de5ab12021-05-31 11:45:48 +0800108 string result = "";
Nik Dewally841612a2024-07-22 15:27:43 +0100109 const int most_flags = 2;
Karl Zhang3de5ab12021-05-31 11:45:48 +0800110 int n_flags = (rand() % most_flags);
111
Nik Dewally841612a2024-07-22 15:27:43 +0100112 for (int i = 0; i < n_flags; ++i) {
113 switch (rand() % 3) {
Karl Zhang3de5ab12021-05-31 11:45:48 +0800114 case 0:
115 result += "PSA_STORAGE_FLAG_NONE";
116 break;
117 case 1:
Karl Zhang3de5ab12021-05-31 11:45:48 +0800118 result += "PSA_STORAGE_FLAG_NO_REPLAY_PROTECTION";
119 break;
Nik Dewally841612a2024-07-22 15:27:43 +0100120 case 2:
Karl Zhang3de5ab12021-05-31 11:45:48 +0800121 result += "PSA_STORAGE_FLAG_NO_CONFIDENTIALITY";
122 break;
123 }
124 if (i < n_flags-1)
125 result += " | ";
126 }
127 if (result == "") result = "PSA_STORAGE_FLAG_NONE";
Nik Dewally841612a2024-07-22 15:27:43 +0100128
129 return result;
Karl Zhang3de5ab12021-05-31 11:45:48 +0800130}
131
132set_data_info::set_data_info (void) // (default constructor)
133{
134 literal_data_not_file = true; // currently, not using files as data sources
135 string_specified = false;
136 data.assign ("");
137 random_data = false;
138 file_specified = false;
139 file_path.assign ("");
140 n_set_vars = -1; // so the first reference is 0 (no suffix), then _1, _2, ...
141 data_offset = 0;
142 flags_string = rand_creation_flags();
143}
144set_data_info::~set_data_info (void) // (destructor)
145{}
146
147/* set() establishes:
148 * An asset's data value from a template line (e.g., set sst snort data "data
149 value"), and
150 * *That* such a value was directly specified, as opposed to no data value having
151 been specified, or a random data value being requested.
152 Arguably, this method "has side effects," in that it not only sets a value, but
153 also "takes notes" about where that value came from.
154*/
155void set_data_info::set (string set_val)
156{
157 literal_data_not_file = true; // currently, not using files as data sources
158 string_specified = true;
159 data.assign (set_val);
160}
161
162/* set_calculated() establishes:
163 * An asset's data value as *not* taken from a template line, and
164 * *That* such a value was not directly specified in any template line, such as
165 if a random data value being requested.
166 Arguably, this method "has side effects," in that it not only sets a value, but
167 also "takes notes" about where that value came from.
168*/
169void set_data_info::set_calculated (string set_val)
170{
171 literal_data_not_file = true; // currently, not using files as data sources
172 string_specified = false;
173 data.assign (set_val);
174}
175
176/* randomize() establishes:
177 * An asset's data value as *not* taken from a template line, and
178 * *That* such a value was randomized.
179 Arguably, this method "has side effects," in that it not only sets a value, but
180 also "takes notes" about where that value came from.
181*/
182void set_data_info::randomize (void)
183{
184 gibberish gib;
185 char gib_buff[4096]; // spew gibberish into here
186 int rand_data_length = 0;
187
188 string_specified = false;
189 random_data = true;
190 literal_data_not_file = true;
191 rand_data_length = 40 + (rand() % 256);
192 /* Note: Multiple assets do get different random data */
193 gib.sentence (gib_buff, gib_buff + rand_data_length - 1);
194 data = gib_buff;
195}
196
197/* Getter for protected member, data. Protected so that it can only be set by
198 set() or set_calculated(), above, to establish not only its value but
199 how it came about. */
200string set_data_info::get (void)
201{
202 return data;
203}
204
205/* Currently, files as data sources aren't used, so this whole method is not "of
206 use," but that might change at some point. */
207bool set_data_info::set_file (string file_name)
208{
209 literal_data_not_file = true;
210 string_specified = false;
211 data.assign ("");
212 file_specified = true;
213 // Remove the ' ' quotes around the file name:
214 file_name.erase (0, 1);
215 file_name.erase (file_name.length()-1, 1);
216 file_path = file_name;
217 return true;
218}
219
220/**********************************************************************************
221 End of methods of class set_data_info.
222**********************************************************************************/
223
224
225/**********************************************************************************
226 Class asset_name_id_info methods regarding setting and getting asset-data values:
227**********************************************************************************/
228
229asset_name_id_info::asset_name_id_info (void) // (default constructor)
230{
231 id_n_not_name = false; // (arbitrary)
232 id_n = 100LL + ((uint64_t) rand() % 10000); // default to random ID#
233 asset_name.assign ("");
234 id_n_specified = name_specified = false; // no ID info yet
235 asset_type = psa_asset_type::unknown;
236 how_asset_found = asset_search::not_found;
237 the_asset = nullptr;
238 asset_ser_no = -1;
239}
240asset_name_id_info::~asset_name_id_info (void)
241{
242 asset_name_vector.clear();
243 asset_id_n_vector.clear();
244}
245
246/* set_name() establishes:
247 * An asset's "human" name from a template line, and
248 * *That* that name was directly specified, as opposed to the asset being defined
249 by ID only, or a random name being requested.
250 Arguably, this method "has side effects," in that it not only sets a name, but
251 also "takes notes" about where that name came from.
252*/
253void asset_name_id_info::set_name (string set_val)
254{
255 /* Use this to set the name as specified in the template file. Call this only
256 if the template file does indeed define a name. */
257 name_specified = true;
258 asset_name.assign (set_val);
259}
260
261/* set_calc_name() establishes:
262 * An asset's "human" name *not* from a template line, and
263 * *That* that name was *not* directly specified in any template line.
264 Arguably, this method "has side effects," in that it not only sets a name, but
265 also "takes notes" about where that name came from.
266*/
267void asset_name_id_info::set_calc_name (string set_val)
268{
269 name_specified = false;
270 asset_name.assign (set_val);
271}
272
273// set_just_name() sets an asset's "human" name, without noting how that name came up.
274void asset_name_id_info::set_just_name (string set_val)
275{
276 asset_name.assign (set_val);
277}
278
279/* Getter for protected member, asset_name. Protected so that it can only be set by
280 set_name() or set_calc_name(), above, to establish not only its value but
281 how it came about. */
282string asset_name_id_info::get_name (void)
283{
284 return asset_name;
285}
286
287// Asset IDs can be set directly from a uint64_t or converted from a string:
288void asset_name_id_info::set_id_n (string set_val)
289{
290 id_n = stol (set_val, 0, 0);
291}
292void asset_name_id_info::set_id_n (uint64_t set_val)
293{
294 id_n = set_val;
295}
296
297// Create ID-based name:
298string asset_name_id_info::make_id_n_based_name (uint64_t id_n)
299{
300 string result;
301
302 switch (asset_type) {
303 case psa_asset_type::sst:
304 result = "SST_ID_";
305 break;
306 case psa_asset_type::key:
307 result = "Key_ID_";
308 break;
309 case psa_asset_type::policy:
310 result = "Policy_ID_";
311 break;
312 default:
313 cerr << "\nError: Tool-internal: Please report error "
314 << "#1223 to the TF-Fuzz developers." << endl;
315 exit(1223);
316 }
317 result.append(to_string(id_n));
318 return result;
319}
320
321/**********************************************************************************
322 End of methods of class asset_name_id_info.
323**********************************************************************************/
324
325
326/**********************************************************************************
327 Class key_policy_info methods:
328**********************************************************************************/
329
330key_policy_info::key_policy_info (void) // (default constructor)
331{
332 get_policy_from_key = false; // specify policy asset by a key that uses it.
333 copy_key = false; // not copying one key to another
334 /* The following settings are not necessarily being randomized in mutually-
335 consistent ways, for two reasons: First, the template should set all that
336 matter, and second, testing TF response to nonsensical settings is also
337 valuable. */
338 exportable = (rand()%2==1? true : false);
339 copyable = (rand()%2==1? true : false);
340 can_encrypt = (rand()%2==1? true : false);
341 can_decrypt = (rand()%2==1? true : false);
342 can_sign = (rand()%2==1? true : false);
343 can_verify = (rand()%2==1? true : false);
344 derivable = (rand()%2==1? true : false);
345 persistent = (rand()%2==1? true : false);
346 // There's a really huge number of possible key types; won't randomize all:
347 key_type = rand_key_type();
348 usage_string.assign ("");
349 print_usage_true_string.assign ("");
350 print_usage_false_string.assign ("");
351 key_algorithm = rand_key_algorithm();
352 n_bits = 55 + (rand() % 1000);
353 gibberish *gib = new gibberish;
354 char buffer[256];
355 char *end;
356 int buf_len = 5ULL + (uint64_t) (rand() % 10);
357 end = gib->word (false, buffer, buffer + buf_len);
358 *end = '\0';
359 buffer[buf_len] = '\0';
360 handle_str = buffer;
361 gib->sentence (buffer, buffer + (40ULL + (uint64_t) (rand() % 200)));
362 key_data = buffer;
363 delete gib;
364}
365key_policy_info::~key_policy_info (void) // (destructor)
366{
367 return; // (even if only to have something to pin a breakpoint on)
368}
369
370
371/**********************************************************************************
372 End of methods of class key_policy_info.
373**********************************************************************************/