blob: 5683b06cb9f290505fbec8dee72a589e9f6198fd [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 Dewally6663dde2024-08-09 16:12:27 +010012#include <stdexcept>
Nik Dewallybacae6c2024-07-30 16:58:14 +010013#include <stdlib.h>
Karl Zhang3de5ab12021-05-31 11:45:48 +080014#include <string>
15#include <vector>
Nik Dewallybacae6c2024-07-30 16:58:14 +010016#include <iostream>
Karl Zhang3de5ab12021-05-31 11:45:48 +080017
Karl Zhang3de5ab12021-05-31 11:45:48 +080018#include "randomization.hpp"
19#include "gibberish.hpp"
Karl Zhang3de5ab12021-05-31 11:45:48 +080020#include "data_blocks.hpp"
Karl Zhang3de5ab12021-05-31 11:45:48 +080021#include "find_or_create_asset.hpp"
22#include "psa_call.hpp"
Karl Zhang3de5ab12021-05-31 11:45:48 +080023
24
25
26/**********************************************************************************
27 Methods of class expect_info follow:
28**********************************************************************************/
29
30expect_info::expect_info (void) // (default constructor)
31{
Nik Dewally6663dde2024-08-09 16:12:27 +010032 result_code_checking_enabled_f = true;
33 return_code_result_string.assign ("");
34
35 expected_return_code = expected_return_code_t::DontKnow;
36
37 data.assign ("");
Karl Zhang3de5ab12021-05-31 11:45:48 +080038 data_var.assign (""); // name of expected-data variable
Nik Dewally6663dde2024-08-09 16:12:27 +010039
40 data_var_specified = false;
Karl Zhang3de5ab12021-05-31 11:45:48 +080041 data_specified = false;
42 data_matches_asset = false;
Karl Zhang3de5ab12021-05-31 11:45:48 +080043 n_exp_vars = -1; // so the first reference is 0 (no suffix), then _1, _2, ...
Karl Zhang3de5ab12021-05-31 11:45:48 +080044}
Nik Dewally6663dde2024-08-09 16:12:27 +010045
Karl Zhang3de5ab12021-05-31 11:45:48 +080046expect_info::~expect_info (void) // (destructor)
47{}
48
Nik Dewally6663dde2024-08-09 16:12:27 +010049bool expect_info::simulation_needed(void) {
50 if (result_code_checking_enabled_f &&
51 expected_return_code == expected_return_code_t::DontKnow) {
52 return true;
53 }
54
55 return false;
Karl Zhang3de5ab12021-05-31 11:45:48 +080056}
57
Nik Dewally6663dde2024-08-09 16:12:27 +010058void expect_info::expect_pass (void)
Karl Zhang3de5ab12021-05-31 11:45:48 +080059{
Nik Dewally6663dde2024-08-09 16:12:27 +010060 expected_return_code = expected_return_code_t::Pass;
61 return_code_result_string = "";
Karl Zhang3de5ab12021-05-31 11:45:48 +080062}
63
Nik Dewally6663dde2024-08-09 16:12:27 +010064void expect_info::expect_failure(void)
Karl Zhang3de5ab12021-05-31 11:45:48 +080065{
Nik Dewally6663dde2024-08-09 16:12:27 +010066 expected_return_code = expected_return_code_t::Fail;
67 return_code_result_string = "";
Karl Zhang3de5ab12021-05-31 11:45:48 +080068}
69
Nik Dewally6663dde2024-08-09 16:12:27 +010070void expect_info::expect_error_code (string error)
Karl Zhang3de5ab12021-05-31 11:45:48 +080071{
Nik Dewally6663dde2024-08-09 16:12:27 +010072 expected_return_code = expected_return_code_t::SpecificFail;
73 return_code_result_string = error;
Karl Zhang3de5ab12021-05-31 11:45:48 +080074}
75
Nik Dewally6663dde2024-08-09 16:12:27 +010076
77void expect_info::clear_expected_code (void)
78{
79 expected_return_code = expected_return_code_t::DontKnow;
80}
81
82expected_return_code_t expect_info::get_expected_return_code(void) {
83
84 // NOTE: we do not store DontCare in expected_return_code, as this would erase
85 // the value stored prior to checks being disabled. This way, when
86 // enable_result_code_checking is called, it can use the value given by the
87 // user previously.
88 // ..
89 // Despite this, having DontCare as a value is still useful: it allows user
90 // code that uses expected return codes to just be a switch statement.
91
92 if (result_code_checking_enabled_f) {
93 return expected_return_code;
94 }
95
96 return expected_return_code_t::DontCare;
97}
98
99string expect_info::get_expected_return_code_string(void) {
100 if (result_code_checking_enabled_f && expected_return_code == expected_return_code_t::SpecificFail) {
101 return return_code_result_string;
102 }
103 throw std::logic_error("get_expected_return_code_string called when return code is not SpecificFail");
104}
105
106void expect_info::disable_result_code_checking (void)
107{
108 result_code_checking_enabled_f = false;
109}
110
111void expect_info::enable_result_code_checking (void)
112{
113 result_code_checking_enabled_f = true;
114}
115
116bool expect_info::result_code_checking_enabled (void) {
117 return result_code_checking_enabled_f;
118}
119
Karl Zhang3de5ab12021-05-31 11:45:48 +0800120void expect_info::copy_expect_to_call (psa_call *the_call)
121{
Nik Dewally6663dde2024-08-09 16:12:27 +0100122 the_call->exp_data = *this;
Karl Zhang3de5ab12021-05-31 11:45:48 +0800123}
124
125/**********************************************************************************
126 End of methods of class expect_info.
127**********************************************************************************/
128
129
130/**********************************************************************************
131 Class set_data_info methods regarding setting and getting asset-data values:
132**********************************************************************************/
133
134string set_data_info::rand_creation_flags (void)
135{
Karl Zhang3de5ab12021-05-31 11:45:48 +0800136 string result = "";
Nik Dewally841612a2024-07-22 15:27:43 +0100137 const int most_flags = 2;
Karl Zhang3de5ab12021-05-31 11:45:48 +0800138 int n_flags = (rand() % most_flags);
139
Nik Dewally841612a2024-07-22 15:27:43 +0100140 for (int i = 0; i < n_flags; ++i) {
141 switch (rand() % 3) {
Karl Zhang3de5ab12021-05-31 11:45:48 +0800142 case 0:
143 result += "PSA_STORAGE_FLAG_NONE";
144 break;
145 case 1:
Karl Zhang3de5ab12021-05-31 11:45:48 +0800146 result += "PSA_STORAGE_FLAG_NO_REPLAY_PROTECTION";
147 break;
Nik Dewally841612a2024-07-22 15:27:43 +0100148 case 2:
Karl Zhang3de5ab12021-05-31 11:45:48 +0800149 result += "PSA_STORAGE_FLAG_NO_CONFIDENTIALITY";
150 break;
151 }
152 if (i < n_flags-1)
153 result += " | ";
154 }
155 if (result == "") result = "PSA_STORAGE_FLAG_NONE";
Nik Dewally841612a2024-07-22 15:27:43 +0100156
157 return result;
Karl Zhang3de5ab12021-05-31 11:45:48 +0800158}
159
160set_data_info::set_data_info (void) // (default constructor)
161{
162 literal_data_not_file = true; // currently, not using files as data sources
163 string_specified = false;
164 data.assign ("");
165 random_data = false;
166 file_specified = false;
167 file_path.assign ("");
168 n_set_vars = -1; // so the first reference is 0 (no suffix), then _1, _2, ...
169 data_offset = 0;
170 flags_string = rand_creation_flags();
171}
172set_data_info::~set_data_info (void) // (destructor)
173{}
174
175/* set() establishes:
176 * An asset's data value from a template line (e.g., set sst snort data "data
177 value"), and
178 * *That* such a value was directly specified, as opposed to no data value having
179 been specified, or a random data value being requested.
180 Arguably, this method "has side effects," in that it not only sets a value, but
181 also "takes notes" about where that value came from.
182*/
183void set_data_info::set (string set_val)
184{
185 literal_data_not_file = true; // currently, not using files as data sources
186 string_specified = true;
187 data.assign (set_val);
188}
189
190/* set_calculated() establishes:
191 * An asset's data value as *not* taken from a template line, and
192 * *That* such a value was not directly specified in any template line, such as
193 if a random data value being requested.
194 Arguably, this method "has side effects," in that it not only sets a value, but
195 also "takes notes" about where that value came from.
196*/
197void set_data_info::set_calculated (string set_val)
198{
199 literal_data_not_file = true; // currently, not using files as data sources
200 string_specified = false;
201 data.assign (set_val);
202}
203
204/* randomize() establishes:
205 * An asset's data value as *not* taken from a template line, and
206 * *That* such a value was randomized.
207 Arguably, this method "has side effects," in that it not only sets a value, but
208 also "takes notes" about where that value came from.
209*/
210void set_data_info::randomize (void)
211{
212 gibberish gib;
213 char gib_buff[4096]; // spew gibberish into here
214 int rand_data_length = 0;
215
216 string_specified = false;
217 random_data = true;
218 literal_data_not_file = true;
219 rand_data_length = 40 + (rand() % 256);
Nik Dewally6663dde2024-08-09 16:12:27 +0100220 /* Note: Multiple assets do get different random data */
Karl Zhang3de5ab12021-05-31 11:45:48 +0800221 gib.sentence (gib_buff, gib_buff + rand_data_length - 1);
222 data = gib_buff;
223}
224
225/* Getter for protected member, data. Protected so that it can only be set by
226 set() or set_calculated(), above, to establish not only its value but
227 how it came about. */
228string set_data_info::get (void)
229{
230 return data;
231}
232
233/* Currently, files as data sources aren't used, so this whole method is not "of
234 use," but that might change at some point. */
235bool set_data_info::set_file (string file_name)
236{
237 literal_data_not_file = true;
238 string_specified = false;
239 data.assign ("");
240 file_specified = true;
241 // Remove the ' ' quotes around the file name:
242 file_name.erase (0, 1);
243 file_name.erase (file_name.length()-1, 1);
244 file_path = file_name;
245 return true;
246}
247
248/**********************************************************************************
249 End of methods of class set_data_info.
250**********************************************************************************/
251
252
253/**********************************************************************************
254 Class asset_name_id_info methods regarding setting and getting asset-data values:
255**********************************************************************************/
256
257asset_name_id_info::asset_name_id_info (void) // (default constructor)
258{
259 id_n_not_name = false; // (arbitrary)
260 id_n = 100LL + ((uint64_t) rand() % 10000); // default to random ID#
261 asset_name.assign ("");
262 id_n_specified = name_specified = false; // no ID info yet
263 asset_type = psa_asset_type::unknown;
264 how_asset_found = asset_search::not_found;
265 the_asset = nullptr;
266 asset_ser_no = -1;
267}
268asset_name_id_info::~asset_name_id_info (void)
269{
270 asset_name_vector.clear();
271 asset_id_n_vector.clear();
272}
273
274/* set_name() establishes:
275 * An asset's "human" name from a template line, and
276 * *That* that name was directly specified, as opposed to the asset being defined
277 by ID only, or a random name being requested.
278 Arguably, this method "has side effects," in that it not only sets a name, but
279 also "takes notes" about where that name came from.
280*/
281void asset_name_id_info::set_name (string set_val)
282{
283 /* Use this to set the name as specified in the template file. Call this only
284 if the template file does indeed define a name. */
285 name_specified = true;
286 asset_name.assign (set_val);
287}
288
289/* set_calc_name() establishes:
290 * An asset's "human" name *not* from a template line, and
291 * *That* that name was *not* directly specified in any template line.
292 Arguably, this method "has side effects," in that it not only sets a name, but
293 also "takes notes" about where that name came from.
294*/
295void asset_name_id_info::set_calc_name (string set_val)
296{
297 name_specified = false;
298 asset_name.assign (set_val);
299}
300
301// set_just_name() sets an asset's "human" name, without noting how that name came up.
302void asset_name_id_info::set_just_name (string set_val)
303{
304 asset_name.assign (set_val);
305}
306
307/* Getter for protected member, asset_name. Protected so that it can only be set by
308 set_name() or set_calc_name(), above, to establish not only its value but
309 how it came about. */
310string asset_name_id_info::get_name (void)
311{
312 return asset_name;
313}
314
315// Asset IDs can be set directly from a uint64_t or converted from a string:
316void asset_name_id_info::set_id_n (string set_val)
317{
318 id_n = stol (set_val, 0, 0);
319}
320void asset_name_id_info::set_id_n (uint64_t set_val)
321{
322 id_n = set_val;
323}
324
325// Create ID-based name:
326string asset_name_id_info::make_id_n_based_name (uint64_t id_n)
327{
328 string result;
329
330 switch (asset_type) {
331 case psa_asset_type::sst:
332 result = "SST_ID_";
333 break;
334 case psa_asset_type::key:
335 result = "Key_ID_";
336 break;
337 case psa_asset_type::policy:
338 result = "Policy_ID_";
339 break;
340 default:
341 cerr << "\nError: Tool-internal: Please report error "
Nik Dewally6663dde2024-08-09 16:12:27 +0100342 << "#1223 to the TF-Fuzz developers." << endl;
Karl Zhang3de5ab12021-05-31 11:45:48 +0800343 exit(1223);
344 }
345 result.append(to_string(id_n));
346 return result;
347}
348
349/**********************************************************************************
350 End of methods of class asset_name_id_info.
351**********************************************************************************/
352
353
354/**********************************************************************************
355 Class key_policy_info methods:
356**********************************************************************************/
357
358key_policy_info::key_policy_info (void) // (default constructor)
359{
360 get_policy_from_key = false; // specify policy asset by a key that uses it.
361 copy_key = false; // not copying one key to another
362 /* The following settings are not necessarily being randomized in mutually-
363 consistent ways, for two reasons: First, the template should set all that
364 matter, and second, testing TF response to nonsensical settings is also
365 valuable. */
366 exportable = (rand()%2==1? true : false);
367 copyable = (rand()%2==1? true : false);
368 can_encrypt = (rand()%2==1? true : false);
369 can_decrypt = (rand()%2==1? true : false);
370 can_sign = (rand()%2==1? true : false);
371 can_verify = (rand()%2==1? true : false);
372 derivable = (rand()%2==1? true : false);
373 persistent = (rand()%2==1? true : false);
374 // There's a really huge number of possible key types; won't randomize all:
375 key_type = rand_key_type();
376 usage_string.assign ("");
377 print_usage_true_string.assign ("");
378 print_usage_false_string.assign ("");
379 key_algorithm = rand_key_algorithm();
380 n_bits = 55 + (rand() % 1000);
381 gibberish *gib = new gibberish;
382 char buffer[256];
383 char *end;
384 int buf_len = 5ULL + (uint64_t) (rand() % 10);
385 end = gib->word (false, buffer, buffer + buf_len);
386 *end = '\0';
387 buffer[buf_len] = '\0';
388 handle_str = buffer;
389 gib->sentence (buffer, buffer + (40ULL + (uint64_t) (rand() % 200)));
390 key_data = buffer;
391 delete gib;
392}
393key_policy_info::~key_policy_info (void) // (destructor)
394{
395 return; // (even if only to have something to pin a breakpoint on)
396}
397
398
399/**********************************************************************************
400 End of methods of class key_policy_info.
401**********************************************************************************/