blob: e6b8cafc8cd097ef50f36405937024e134a9e3b2 [file] [log] [blame]
Nik Dewallyabac0e52024-08-02 13:42:27 +01001/* Copyright (c) 2024 Arm Limited. All Rights Reserved.
2 *
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
6#include "crypto_model.hpp"
7#include <algorithm>
8#include <cmath>
9#include <map>
10#include <numeric>
11#include <stdexcept>
12
13using namespace crypto_model;
14using namespace crypto_model::internal;
15using namespace std;
16
17std::map<std::string,crypto_model::key_type> key_types;
18std::map<std::string,crypto_model::algorithm> algorithms;
19std::vector<std::string> hash_algorithms;
20
21// From PSA_VENDOR_RSA_MAX_KEY_BITS
22const uint RSA_KEY_MAX_SIZE = 4096;
23
24// From PSA_VENDOR_RSA_MIN_KEY_BITS
25const uint RSA_KEY_MIN_SIZE = 1024;
26
27// From PSA_MAX_KEY_BITS
28const uint MAX_KEY_SIZE = 0xfff8;
29
30// Size cannot be 0
31const uint MIN_KEY_SIZE = 1;
32
33const std::vector<std::pair<string, string>> key_type_allowed_with_algorithm = {
34 {"PSA_KEY_TYPE_AES","PSA_ALG_CBC_MAC"},
35 {"PSA_KEY_TYPE_AES","PSA_ALG_CMAC"},
36 {"PSA_KEY_TYPE_AES","PSA_ALG_CTR"},
37 {"PSA_KEY_TYPE_AES","PSA_ALG_CFB"},
38 {"PSA_KEY_TYPE_AES","PSA_ALG_OFB"},
39 {"PSA_KEY_TYPE_AES","PSA_ALG_CBC_NO_PADDING"},
40 {"PSA_KEY_TYPE_AES","PSA_ALG_CBC_PKCS7"},
41 {"PSA_KEY_TYPE_AES","PSA_ALG_ECB_NO_PADDING"},
42 {"PSA_KEY_TYPE_AES","PSA_ALG_CCM"},
43 {"PSA_KEY_TYPE_AES","PSA_ALG_GCM"},
44
45 {"PSA_KEY_TYPE_ARC4","PSA_ALG_STREAM_CIPHER"},
46
47 {"PSA_KEY_TYPE_ARIA","PSA_ALG_CBC_MAC"},
48 {"PSA_KEY_TYPE_ARIA","PSA_ALG_CMAC"},
49 {"PSA_KEY_TYPE_ARIA","PSA_ALG_CTR"},
50 {"PSA_KEY_TYPE_ARIA","PSA_ALG_CFB"},
51 {"PSA_KEY_TYPE_ARIA","PSA_ALG_OFB"},
52 {"PSA_KEY_TYPE_ARIA","PSA_ALG_CBC_NO_PADDING"},
53 {"PSA_KEY_TYPE_ARIA","PSA_ALG_CBC_PKCS7"},
54 {"PSA_KEY_TYPE_ARIA","PSA_ALG_ECB_NO_PADDING"},
55 {"PSA_KEY_TYPE_ARIA","PSA_ALG_CCM"},
56 {"PSA_KEY_TYPE_ARIA","PSA_ALG_GCM"},
57
58 {"PSA_KEY_TYPE_CAMELLIA","PSA_ALG_CBC_MAC"},
59 {"PSA_KEY_TYPE_CAMELLIA","PSA_ALG_CMAC"},
60 {"PSA_KEY_TYPE_CAMELLIA","PSA_ALG_CTR"},
61 {"PSA_KEY_TYPE_CAMELLIA","PSA_ALG_CFB"},
62 {"PSA_KEY_TYPE_CAMELLIA","PSA_ALG_OFB"},
63 {"PSA_KEY_TYPE_CAMELLIA","PSA_ALG_CBC_NO_PADDING"},
64 {"PSA_KEY_TYPE_CAMELLIA","PSA_ALG_CBC_PKCS7"},
65 {"PSA_KEY_TYPE_CAMELLIA","PSA_ALG_ECB_NO_PADDING"},
66 {"PSA_KEY_TYPE_CAMELLIA","PSA_ALG_CCM"},
67 {"PSA_KEY_TYPE_CAMELLIA","PSA_ALG_GCM"},
68
69 {"PSA_KEY_TYPE_CHACHA20","PSA_ALG_STREAM_CIPHER"},
70 {"PSA_KEY_TYPE_CHACHA20","PSA_ALG_CHACHA20_POLY1305"},
71
72 {"PSA_KEY_TYPE_DES","PSA_ALG_CMAC"},
73 {"PSA_KEY_TYPE_DES","PSA_ALG_CTR"},
74 {"PSA_KEY_TYPE_DES","PSA_ALG_CFB"},
75 {"PSA_KEY_TYPE_DES","PSA_ALG_OFB"},
76 {"PSA_KEY_TYPE_DES","PSA_ALG_CBC_NO_PADDING"},
77 {"PSA_KEY_TYPE_DES","PSA_ALG_CBC_PKCS7"},
78 {"PSA_KEY_TYPE_DES","PSA_ALG_ECB_NO_PADDING"},
79
80 {"PSA_KEY_TYPE_HMAC","PSA_ALG_HMAC"},
81
82 {"PSA_KEY_TYPE_DERIVE","PSA_ALG_HKDF"},
83 {"PSA_KEY_TYPE_DERIVE","PSA_ALG_TLS12_PRF"},
84 {"PSA_KEY_TYPE_DERIVE","PSA_ALG_TLS12_PSK_TO_MS"},
85
86 {"PSA_KEY_TYPE_PASSWORD_HASH","PSA_ALG_PBKDF2_HMAC"},
87 {"PSA_KEY_TYPE_PASSWORD_HASH","PSA_ALG_PBKDF2_AES_CMAC_PRF_128"},
88
89 {"PSA_KEY_TYPE_PASSWORD","PSA_ALG_PBKDF2_HMAC"},
90 {"PSA_KEY_TYPE_PASSWORD","PSA_ALG_PBKDF2_AES_CMAC_PRF_128"},
91
92 {"PSA_KEY_TYPE_PEPPER","PSA_ALG_PBKDF2_HMAC"},
93 {"PSA_KEY_TYPE_PEPPER","PSA_ALG_PBKDF2_AES_CMAC_PRF_128"},
94
95 {"PSA_KEY_TYPE_RAW_DATA","PSA_ALG_HKDF"},
96 {"PSA_KEY_TYPE_RAW_DATA","PSA_ALG_TLS12_PRF"},
97 {"PSA_KEY_TYPE_RAW_DATA","PSA_ALG_TLS12_PSK_TO_MS"},
98
99 {"PSA_KEY_TYPE_RSA_KEY_PAIR","PSA_ALG_RSA_OAEP"},
100 {"PSA_KEY_TYPE_RSA_KEY_PAIR","PSA_ALG_RSA_PKCS1V15_CRYPT"},
101 {"PSA_KEY_TYPE_RSA_KEY_PAIR","PSA_ALG_RSA_PKCS1V15_SIGN"},
102 {"PSA_KEY_TYPE_RSA_KEY_PAIR","PSA_ALG_RSA_PKCS1V15_SIGN_RAW"},
103
104 {"PSA_KEY_TYPE_RSA_PUBLIC_KEY","PSA_ALG_RSA_OAEP"},
105 {"PSA_KEY_TYPE_RSA_PUBLIC_KEY","PSA_ALG_RSA_PKCS1V15_CRYPT"},
106 {"PSA_KEY_TYPE_RSA_PUBLIC_KEY","PSA_ALG_RSA_PKCS1V15_SIGN"},
107 {"PSA_KEY_TYPE_RSA_PUBLIC_KEY","PSA_ALG_RSA_PKCS1V15_SIGN_RAW"},
108};
109
110// See tf-m/lib/ext/mbed-crypto/mbed_crypto_config
111const std::vector<string> disabled_key_types = {
112 "PSA_KEY_TYPE_ARIA",
113 "PSA_KEY_TYPE_ARC4",
114 "PSA_KEY_TYPE_CAMELLIA",
115 "PSA_KEY_TYPE_CHACHA20",
116 "PSA_KEY_TYPE_DES"
117};
118
119// See tf-m/lib/ext/mbed-crypto/mbed_crypto_config
120const std::vector<string> disabled_algorithms = {
121 "PSA_ALG_CBC_MAC",
122 "PSA_ALG_CHACHA20_POLY1305",
123 "PSA_WANT_ALG_ECB_NO_PADDING",
124 "PSA_ALG_MD5",
125 "PSA_ALG_OFB",
126 "PSA_ALG_SHA_1",
127 "PSA_ALG_PBKDF2_HMAC",
128 "PSA_ALG_RIPEMD160",
129 "PSA_ALG_STREAM_CIPHER",
130};
131
132// for readability
133const bool doesnt_require_hash = false;
134const bool requires_hash = true;
135const bool hash_alg = true;
136const bool not_hash_alg = false;
137
138void crypto_model::init_crypto_model(void) {
139
140 // Key type definitions.
141
142 define_key_type("PSA_KEY_TYPE_AES", {128, 192, 256}, MAX_KEY_SIZE,
143 MIN_KEY_SIZE);
144 define_key_type("PSA_KEY_TYPE_ARC4", {},40,2048);
145 define_key_type("PSA_KEY_TYPE_CAMELLIA", {128, 192, 256}, MAX_KEY_SIZE,
146 MIN_KEY_SIZE);
147 define_key_type("PSA_KEY_TYPE_CHACHA20", {256}, 256, 256);
148 define_key_type("PSA_KEY_TYPE_DES", {64, 128, 192}, MAX_KEY_SIZE,
149 MIN_KEY_SIZE);
150 define_key_type("PSA_KEY_TYPE_DERIVE", {}, MAX_KEY_SIZE, MIN_KEY_SIZE);
151 define_key_type("PSA_KEY_TYPE_HMAC", {}, MAX_KEY_SIZE, MIN_KEY_SIZE);
152 define_key_type("PSA_KEY_TYPE_RAW_DATA", {}, MAX_KEY_SIZE, MIN_KEY_SIZE);
153 define_key_type("PSA_KEY_TYPE_PASSWORD", {}, MAX_KEY_SIZE, MIN_KEY_SIZE);
154 define_key_type("PSA_KEY_TYPE_PASSWORD_HASH", {}, MAX_KEY_SIZE,
155 MIN_KEY_SIZE);
156
157 define_key_type("PSA_KEY_TYPE_PEPPER", {}, MAX_KEY_SIZE, MIN_KEY_SIZE);
158 define_key_type("PSA_KEY_TYPE_RSA_KEY_PAIR", {}, RSA_KEY_MAX_SIZE,
159 RSA_KEY_MIN_SIZE);
160
161 define_key_type("PSA_KEY_TYPE_RSA_PUBLIC_KEY", {}, RSA_KEY_MAX_SIZE,
162 RSA_KEY_MIN_SIZE);
163
164 // Algorithm definitions
165 define_algorithm("PSA_ALG_CCM",not_hash_alg,doesnt_require_hash);
166 define_algorithm("PSA_ALG_GCM",not_hash_alg,doesnt_require_hash);
167 define_algorithm("PSA_ALG_CHACHA20_POLY1305",not_hash_alg,doesnt_require_hash);
168 define_algorithm("PSA_ALG_RSA_PKCS1V15_CRYPT",not_hash_alg,doesnt_require_hash);
169 define_algorithm("PSA_ALG_RSA_OAEP", not_hash_alg, requires_hash);
170 define_algorithm("PSA_ALG_RSA_PKCS1V15_SIGN", not_hash_alg, requires_hash);
171 define_algorithm("PSA_ALG_RSA_PKCS1V15_SIGN_RAW", not_hash_alg, doesnt_require_hash);
172 define_algorithm("PSA_ALG_STREAM_CIPHER", not_hash_alg, doesnt_require_hash);
173 define_algorithm("PSA_ALG_CTR", not_hash_alg, doesnt_require_hash);
174 define_algorithm("PSA_ALG_CCM_STAR_NO_TAG", not_hash_alg, doesnt_require_hash);
175 define_algorithm("PSA_ALG_CFB", not_hash_alg, doesnt_require_hash);
176 define_algorithm("PSA_ALG_OFB", not_hash_alg, doesnt_require_hash);
177 define_algorithm("PSA_ALG_ECB_NO_PADDING", not_hash_alg, doesnt_require_hash);
178 define_algorithm("PSA_ALG_CBC_NO_PADDING", not_hash_alg, doesnt_require_hash);
179 define_algorithm("PSA_ALG_CBC_PKCS7", not_hash_alg, doesnt_require_hash);
180
181 define_algorithm("PSA_ALG_MD5",hash_alg,doesnt_require_hash);
182 define_algorithm("PSA_ALG_RIPEMD160",hash_alg,doesnt_require_hash);
183 define_algorithm("PSA_ALG_SHA_1",hash_alg,doesnt_require_hash);
184 define_algorithm("PSA_ALG_SHA_224",hash_alg,doesnt_require_hash);
185 define_algorithm("PSA_ALG_SHA_256",hash_alg,doesnt_require_hash);
186 define_algorithm("PSA_ALG_SHA_384",hash_alg,doesnt_require_hash);
187 define_algorithm("PSA_ALG_SHA_512",hash_alg,doesnt_require_hash);
188 define_algorithm("PSA_ALG_SHA_512_224",hash_alg,doesnt_require_hash);
189 define_algorithm("PSA_ALG_SHA_512_256",hash_alg,doesnt_require_hash);
190 define_algorithm("PSA_ALG_SHA3_224",hash_alg,doesnt_require_hash);
191 define_algorithm("PSA_ALG_SHA3_256",hash_alg,doesnt_require_hash);
192 define_algorithm("PSA_ALG_SHA3_384",hash_alg,doesnt_require_hash);
193 define_algorithm("PSA_ALG_SHA3_512",hash_alg,doesnt_require_hash);
194 define_algorithm("PSA_ALG_SHA3_512",hash_alg,doesnt_require_hash);
195
196 define_algorithm("PSA_ALG_FFDH",not_hash_alg,doesnt_require_hash);
197 define_algorithm("PSA_ALG_ECDH",not_hash_alg,doesnt_require_hash);
198
199 define_algorithm("PSA_ALG_HKDF",not_hash_alg,requires_hash);
200 define_algorithm("PSA_ALG_TLS12_PRF",not_hash_alg,requires_hash);
201 define_algorithm("PSA_ALG_TLS12_PSK_TO_MS",not_hash_alg,requires_hash);
202 define_algorithm("PSA_ALG_HKDF_EXTRACT",not_hash_alg,requires_hash);
203 define_algorithm("PSA_ALG_HKDF_EXPAND",not_hash_alg,requires_hash);
204 define_algorithm("PSA_ALG_TLS12_ECJPAKE_TO_PMS",not_hash_alg,doesnt_require_hash);
205 define_algorithm("PSA_ALG_PBKDF2_HMAC",not_hash_alg,requires_hash);
206 define_algorithm("PSA_ALG_PBKDF2_AES_CMAC_PRF_128",not_hash_alg,doesnt_require_hash);
207
208 define_algorithm("PSA_ALG_HMAC",not_hash_alg,requires_hash);
209 define_algorithm("PSA_ALG_CBC_MAC",not_hash_alg,doesnt_require_hash);
210 define_algorithm("PSA_ALG_CMAC",not_hash_alg,doesnt_require_hash);
211
212 // Load the data tables into the right places
213 for (auto &kt: disabled_key_types) {
214 key_types[kt].enabled = false;
215 }
216
217 for (auto &alg: disabled_algorithms) {
218 algorithms[alg].enabled = false;
219 }
220
221 for (auto pair: key_type_allowed_with_algorithm) {
222 key_type &kt = key_types[pair.first];
223 algorithm &alg = algorithms[pair.second];
224
225 if (!kt.is_enabled() || !alg.is_enabled()) {
226 continue;
227 }
228
229 alg.allowed_key_types.push_back(kt.get_string());
230 kt.allowed_algorithms.push_back(alg.get_string());
231 }
232
233}
234
235void crypto_model::internal::define_key_type(
236 std::string name, std::vector<uint> allowed_key_sizes_bits,
237 uint max_key_size_bits, uint min_key_size_bits) {
238
239 key_type kt;
240 kt.name = name;
241 kt.allowed_key_sizes_bits = allowed_key_sizes_bits;
242 kt.max_key_size_bits = max_key_size_bits;
243 kt.min_key_size_bits = min_key_size_bits;
244
245 key_types[name] = kt;
246}
247
248void crypto_model::internal::define_algorithm(std::string name,
249 bool is_hash_algorithm,
250 bool requires_hash) {
251 algorithm a;
252 a.name = name;
253 a.is_hash_algorithm_flag = is_hash_algorithm;
254 a.requires_hash_flag = requires_hash;
255
256 if (is_hash_algorithm) {
257 hash_algorithms.push_back(name);
258 }
259
260 algorithms[name] = a;
261}
262
263namespace crypto_model {
264
265uint get_random_key_size() {
266 int lower = std::floor(MIN_KEY_SIZE/ 8);
267 int higher = std::floor(MAX_KEY_SIZE/8);
268 return ((rand() % (higher - lower)) + lower) * 8;
269}
270
271algorithm& get_algorithm(std::string name) {
272
273 // turn hash algs of form PSA_ALG_FOO(PSA_ALG_BAR) into PSA_ALG_FOO.
274 int index = name.find("(");
275 if (index != string::npos) {
276 name = name.substr(index);
277 }
278
279 return algorithms[name];
280}
281
282
283key_type& get_key_type(std::string name) {
284 return key_types[name];
285}
286
287algorithm& get_random_algorithm() {
288 // to randomise:
289 // get random index.
290 // if it is a disabled alg, repeat
291 std::vector<int> v(algorithms.size());
292 std::iota(v.begin(),v.end(),0);
293 std::random_shuffle(v.begin(),v.end());
294 auto it = algorithms.begin();
295 for (int i:v) {
296 auto it = algorithms.begin();
297 std::advance(it,i);
298 algorithm& alg = it->second;
299 if (alg.is_enabled()) {
300 return alg;
301 }
302 }
303 throw std::logic_error("No enabled algorithms");
304}
305
306key_type& get_random_key_type() {
307 // to randomise:
308 // get random index.
309 // if it is a disabled key type, repeat
310 std::vector<int> v(key_types.size());
311 std::iota(v.begin(),v.end(),0);
312 std::random_shuffle(v.begin(),v.end());
313 auto it = key_types.begin();
314 for (int i:v) {
315 auto it = key_types.begin();
316 std::advance(it,i);
317 key_type& kt = it->second;
318 if (kt.is_enabled()) {
319 return kt;
320 }
321 }
322 throw std::logic_error("No enabled key types");
323}
324
325algorithm& get_random_hash_algorithm() {
326 std::random_shuffle(hash_algorithms.begin(),hash_algorithms.end());
327 for (int i=0;i<hash_algorithms.size();i++) {
328 if (algorithms[hash_algorithms[i]].is_enabled()) {
329 return algorithms[hash_algorithms[i]];
330 }
331 }
332
333 throw std::logic_error("No enabled hash algorithms");
334}
335
336algorithm::algorithm() {
337
338};
339
340algorithm::~algorithm() {
341
342};
343
344string algorithm::get_string() {
345 return name;
346};
347
348bool algorithm::is_enabled() {
349 return enabled;
350}
351
352std::string algorithm::get_string_with_hash() {
353 string out = name;
354 if (requires_hash()) {
355 algorithm& hash_alg = get_random_hash_algorithm();
356 out += "(";
357 out += hash_alg.name;
358 out += ")";
359 }
360
361 return out;
362}
363
364bool algorithm::valid_for_key_type(key_type& kt) {
365 if (std::find(allowed_key_types.begin(),allowed_key_types.end(),kt.get_string()) != allowed_key_types.end()) {
366 return true;
367 }
368 return false;
369}
370
371bool algorithm::requires_hash() {
372 return requires_hash_flag;
373}
374
375bool algorithm::is_hash_algorithm() {
376 return is_hash_algorithm_flag;
377}
378
379key_type& algorithm::random_valid_key_type() {
380 if (allowed_key_types.size() == 0) {
381 throw std::logic_error("No allowed key types for algorithm");
382 }
383 std::random_shuffle(allowed_key_types.begin(),allowed_key_types.end());
384 return key_types[allowed_key_types[0]];
385
386}
387key_type::key_type() {
388
389};
390
391key_type::~key_type() {
392
393};
394
395string key_type::get_string() {
396 return name;
397}
398
399bool key_type::is_enabled() {
400 return enabled;
401}
402
403algorithm& key_type::random_allowed_algorithm() {
404 if (allowed_algorithms.size() == 0) {
405 throw std::logic_error("Key type has no allowed algorithms");
406 }
407 std::random_shuffle(allowed_algorithms.begin(),allowed_algorithms.end());
408 return algorithms[allowed_algorithms[0]];
409
410}
411
412bool key_type::is_allowed_algorithm(algorithm& algorithm) {
413 if (std::find(allowed_algorithms.begin(),allowed_algorithms.end(),algorithm.get_string()) != allowed_algorithms.end()) {
414 return true;
415 }
416 return false;
417}
418
419bool key_type::is_valid_key_size(uint size) {
420 // (MbedTLS): size is always byte aligned
421 if (size % 8 != 0) {
422 return false;
423 }
424
425 if (size > max_key_size_bits) {
426 return false;
427 }
428
429 if (size < min_key_size_bits) {
430 return false;
431 }
432
433 // some keys only allow a fixed set of values
434 if (!allowed_key_sizes_bits.empty()) {
435 if (std::find(allowed_key_sizes_bits.begin(),
436 allowed_key_sizes_bits.end(),
437 size) == allowed_key_sizes_bits.end()) {
438 return false;
439 }
440 }
441 return true;
442}
443
444uint key_type::get_random_valid_key_size() {
445 if (!allowed_key_sizes_bits.empty()) {
446 std::random_shuffle(allowed_key_sizes_bits.begin(),allowed_key_sizes_bits.end());
447 return allowed_key_sizes_bits[0];
448 }
449
450 int lower = floor(min_key_size_bits/ 8);
451 int higher = floor(max_key_size_bits/8);
452
453 return ((rand() % (higher - lower)) + lower) * 8;
454}
455
456} // namespace crypto_model