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