blob: 09a25e916a99442b12aa2fc93f2dc9bd9edb4a2e [file] [log] [blame]
Karl Zhang3de5ab12021-05-31 11:45:48 +08001/*
2 * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
3 *
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{
108 return ((rand() % 2) == 1)?
109 "PSA_STORAGE_FLAG_WRITE_ONCE" : "PSA_STORAGE_FLAG_NONE";
110
111 /* TODO: There are also PSA_STORAGE_FLAG_NO_REPLAY_PROTECTION and
112 PSA_STORAGE_FLAG_NO_CONFIDENTIALITY, but they don't seem to appear
113 in any test suites, so it's iffy as to whether they really exist.
114 We'll not routinely initialize to them, for now at least, but if
115 we want to enable them, then uncomment the following:
116 string result = "";
117 const int most_flags = 2,
118 int n_flags = (rand() % most_flags);
119
120 for (int i = 0; i < ; i < n_flags; ++i) {
121 switch (rand() % 4) {
122 case 0:
123 result += "PSA_STORAGE_FLAG_NONE";
124 break;
125 case 1:
126 result += "PSA_STORAGE_FLAG_WRITE_ONCE";
127 break;
128 case 2:
129 result += "PSA_STORAGE_FLAG_NO_REPLAY_PROTECTION";
130 break;
131 case 3:
132 result += "PSA_STORAGE_FLAG_NO_CONFIDENTIALITY";
133 break;
134 }
135 if (i < n_flags-1)
136 result += " | ";
137 }
138 if (result == "") result = "PSA_STORAGE_FLAG_NONE";
139*/
140}
141
142set_data_info::set_data_info (void) // (default constructor)
143{
144 literal_data_not_file = true; // currently, not using files as data sources
145 string_specified = false;
146 data.assign ("");
147 random_data = false;
148 file_specified = false;
149 file_path.assign ("");
150 n_set_vars = -1; // so the first reference is 0 (no suffix), then _1, _2, ...
151 data_offset = 0;
152 flags_string = rand_creation_flags();
153}
154set_data_info::~set_data_info (void) // (destructor)
155{}
156
157/* set() establishes:
158 * An asset's data value from a template line (e.g., set sst snort data "data
159 value"), and
160 * *That* such a value was directly specified, as opposed to no data value having
161 been specified, or a random data value being requested.
162 Arguably, this method "has side effects," in that it not only sets a value, but
163 also "takes notes" about where that value came from.
164*/
165void set_data_info::set (string set_val)
166{
167 literal_data_not_file = true; // currently, not using files as data sources
168 string_specified = true;
169 data.assign (set_val);
170}
171
172/* set_calculated() establishes:
173 * An asset's data value as *not* taken from a template line, and
174 * *That* such a value was not directly specified in any template line, such as
175 if a random data value being requested.
176 Arguably, this method "has side effects," in that it not only sets a value, but
177 also "takes notes" about where that value came from.
178*/
179void set_data_info::set_calculated (string set_val)
180{
181 literal_data_not_file = true; // currently, not using files as data sources
182 string_specified = false;
183 data.assign (set_val);
184}
185
186/* randomize() establishes:
187 * An asset's data value as *not* taken from a template line, and
188 * *That* such a value was randomized.
189 Arguably, this method "has side effects," in that it not only sets a value, but
190 also "takes notes" about where that value came from.
191*/
192void set_data_info::randomize (void)
193{
194 gibberish gib;
195 char gib_buff[4096]; // spew gibberish into here
196 int rand_data_length = 0;
197
198 string_specified = false;
199 random_data = true;
200 literal_data_not_file = true;
201 rand_data_length = 40 + (rand() % 256);
202 /* Note: Multiple assets do get different random data */
203 gib.sentence (gib_buff, gib_buff + rand_data_length - 1);
204 data = gib_buff;
205}
206
207/* Getter for protected member, data. Protected so that it can only be set by
208 set() or set_calculated(), above, to establish not only its value but
209 how it came about. */
210string set_data_info::get (void)
211{
212 return data;
213}
214
215/* Currently, files as data sources aren't used, so this whole method is not "of
216 use," but that might change at some point. */
217bool set_data_info::set_file (string file_name)
218{
219 literal_data_not_file = true;
220 string_specified = false;
221 data.assign ("");
222 file_specified = true;
223 // Remove the ' ' quotes around the file name:
224 file_name.erase (0, 1);
225 file_name.erase (file_name.length()-1, 1);
226 file_path = file_name;
227 return true;
228}
229
230/**********************************************************************************
231 End of methods of class set_data_info.
232**********************************************************************************/
233
234
235/**********************************************************************************
236 Class asset_name_id_info methods regarding setting and getting asset-data values:
237**********************************************************************************/
238
239asset_name_id_info::asset_name_id_info (void) // (default constructor)
240{
241 id_n_not_name = false; // (arbitrary)
242 id_n = 100LL + ((uint64_t) rand() % 10000); // default to random ID#
243 asset_name.assign ("");
244 id_n_specified = name_specified = false; // no ID info yet
245 asset_type = psa_asset_type::unknown;
246 how_asset_found = asset_search::not_found;
247 the_asset = nullptr;
248 asset_ser_no = -1;
249}
250asset_name_id_info::~asset_name_id_info (void)
251{
252 asset_name_vector.clear();
253 asset_id_n_vector.clear();
254}
255
256/* set_name() establishes:
257 * An asset's "human" name from a template line, and
258 * *That* that name was directly specified, as opposed to the asset being defined
259 by ID only, or a random name being requested.
260 Arguably, this method "has side effects," in that it not only sets a name, but
261 also "takes notes" about where that name came from.
262*/
263void asset_name_id_info::set_name (string set_val)
264{
265 /* Use this to set the name as specified in the template file. Call this only
266 if the template file does indeed define a name. */
267 name_specified = true;
268 asset_name.assign (set_val);
269}
270
271/* set_calc_name() establishes:
272 * An asset's "human" name *not* from a template line, and
273 * *That* that name was *not* directly specified in any template line.
274 Arguably, this method "has side effects," in that it not only sets a name, but
275 also "takes notes" about where that name came from.
276*/
277void asset_name_id_info::set_calc_name (string set_val)
278{
279 name_specified = false;
280 asset_name.assign (set_val);
281}
282
283// set_just_name() sets an asset's "human" name, without noting how that name came up.
284void asset_name_id_info::set_just_name (string set_val)
285{
286 asset_name.assign (set_val);
287}
288
289/* Getter for protected member, asset_name. Protected so that it can only be set by
290 set_name() or set_calc_name(), above, to establish not only its value but
291 how it came about. */
292string asset_name_id_info::get_name (void)
293{
294 return asset_name;
295}
296
297// Asset IDs can be set directly from a uint64_t or converted from a string:
298void asset_name_id_info::set_id_n (string set_val)
299{
300 id_n = stol (set_val, 0, 0);
301}
302void asset_name_id_info::set_id_n (uint64_t set_val)
303{
304 id_n = set_val;
305}
306
307// Create ID-based name:
308string asset_name_id_info::make_id_n_based_name (uint64_t id_n)
309{
310 string result;
311
312 switch (asset_type) {
313 case psa_asset_type::sst:
314 result = "SST_ID_";
315 break;
316 case psa_asset_type::key:
317 result = "Key_ID_";
318 break;
319 case psa_asset_type::policy:
320 result = "Policy_ID_";
321 break;
322 default:
323 cerr << "\nError: Tool-internal: Please report error "
324 << "#1223 to the TF-Fuzz developers." << endl;
325 exit(1223);
326 }
327 result.append(to_string(id_n));
328 return result;
329}
330
331/**********************************************************************************
332 End of methods of class asset_name_id_info.
333**********************************************************************************/
334
335
336/**********************************************************************************
337 Class key_policy_info methods:
338**********************************************************************************/
339
340key_policy_info::key_policy_info (void) // (default constructor)
341{
342 get_policy_from_key = false; // specify policy asset by a key that uses it.
343 copy_key = false; // not copying one key to another
344 /* The following settings are not necessarily being randomized in mutually-
345 consistent ways, for two reasons: First, the template should set all that
346 matter, and second, testing TF response to nonsensical settings is also
347 valuable. */
348 exportable = (rand()%2==1? true : false);
349 copyable = (rand()%2==1? true : false);
350 can_encrypt = (rand()%2==1? true : false);
351 can_decrypt = (rand()%2==1? true : false);
352 can_sign = (rand()%2==1? true : false);
353 can_verify = (rand()%2==1? true : false);
354 derivable = (rand()%2==1? true : false);
355 persistent = (rand()%2==1? true : false);
356 // There's a really huge number of possible key types; won't randomize all:
357 key_type = rand_key_type();
358 usage_string.assign ("");
359 print_usage_true_string.assign ("");
360 print_usage_false_string.assign ("");
361 key_algorithm = rand_key_algorithm();
362 n_bits = 55 + (rand() % 1000);
363 gibberish *gib = new gibberish;
364 char buffer[256];
365 char *end;
366 int buf_len = 5ULL + (uint64_t) (rand() % 10);
367 end = gib->word (false, buffer, buffer + buf_len);
368 *end = '\0';
369 buffer[buf_len] = '\0';
370 handle_str = buffer;
371 gib->sentence (buffer, buffer + (40ULL + (uint64_t) (rand() % 200)));
372 key_data = buffer;
373 delete gib;
374}
375key_policy_info::~key_policy_info (void) // (destructor)
376{
377 return; // (even if only to have something to pin a breakpoint on)
378}
379
380
381/**********************************************************************************
382 End of methods of class key_policy_info.
383**********************************************************************************/