blob: 589f3b6959088e41bb44d6c6d26d20611cc8d901 [file] [log] [blame]
Julian Hall38c729b2020-11-23 18:23:03 +01001/*
Balint Dobszay3c52ce62021-05-10 16:27:18 +02002 * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
Julian Hall38c729b2020-11-23 18:23:03 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <cstdio>
8#include <cstring>
9#include <unistd.h>
10#include <service/crypto/client/cpp/crypto_client.h>
11#include "ts-demo.h"
12
13class ts_demo {
14public:
15 ts_demo(crypto_client *crypto_client, bool is_verbose) :
16 m_crypto_client(crypto_client),
Balint Dobszay3c52ce62021-05-10 16:27:18 +020017 m_signing_key_id(0),
18 m_encryption_key_id(0),
Julian Hall38c729b2020-11-23 18:23:03 +010019 m_verbose(is_verbose),
20 m_all_ok(true) {
21
22 }
23
24 ~ts_demo() {
25
26 }
27
28 bool is_all_ok() const {
29 return m_all_ok;
30 }
31
32 void print_intro() {
33
34 if (m_verbose) {
35 printf("\nDemonstrates use of trusted services from an application");
36 printf("\n---------------------------------------------------------");
37 printf("\nA client requests a set of crypto operations performed by");
38 printf("\nthe Crypto service. Key storage for persistent keys is");
39 printf("\nprovided by the Secure Storage service via the ITS client.\n");
40 printf("\n");
41 }
42 }
43
44 void wait(int seconds) {
45
46 if (m_verbose) sleep(seconds);
47 }
48
49 void print_status(psa_status_t status) {
50
51 if (m_verbose) {
52
53 if (status == PSA_SUCCESS) {
54 printf("\n\tOperation successful\n");
55 }
56 else {
57 printf("\n\tOperation failed. op error: %d RPC call status %d\n",
58 status, m_crypto_client->err_rpc_status());
59 }
60 }
61 }
62
63 void print_byte_array(const uint8_t *array, size_t len)
64 {
65 size_t count = 0;
66 size_t column = 0;
67
68 while (count < len) {
69
70 if (column == 0) printf("\n\t\t");
71 else printf(" ");
72
73 printf("%02X", array[count]);
74
75 ++count;
76 column = (column +1) % 8;
77 }
78
79 printf("\n");
80 }
81
82 void generate_signing_key()
83 {
84 psa_status_t status;
85 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
86
87 psa_set_key_id(&attributes, SIGNING_KEY_ID);
88 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH);
89 psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
Balint Dobszay3c52ce62021-05-10 16:27:18 +020090 psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
Julian Hall38c729b2020-11-23 18:23:03 +010091 psa_set_key_bits(&attributes, 256);
92
93 if (m_verbose) printf("Generating ECC signing key");
94
Balint Dobszay3c52ce62021-05-10 16:27:18 +020095 status = m_crypto_client->generate_key(&attributes, &m_signing_key_id);
Julian Hall38c729b2020-11-23 18:23:03 +010096 psa_reset_key_attributes(&attributes);
97
98 print_status(status);
99
100 m_all_ok &= (status == PSA_SUCCESS);
101 }
102
103 void sign_and_verify_message(const char *message)
104 {
105
106 psa_status_t status;
107 uint8_t hash[100];
108 size_t hash_len = strlen(message) + 1;
109
110 if (hash_len > sizeof(hash)) hash_len = sizeof(hash) - 1;
111
112 memset(hash, 0, sizeof(hash));
113 memcpy(hash, message, hash_len);
114
115 /* Sign message */
116 uint8_t signature[PSA_SIGNATURE_MAX_SIZE];
117 size_t signature_length;
118
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200119 if (m_verbose) printf("Signing message: \"%s\" using key: %d", hash, m_signing_key_id);
Julian Hall38c729b2020-11-23 18:23:03 +0100120
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200121 status = m_crypto_client->sign_hash(m_signing_key_id,
Julian Hall38c729b2020-11-23 18:23:03 +0100122 PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), hash, hash_len,
123 signature, sizeof(signature), &signature_length);
124
125 print_status(status);
126
127 if (m_verbose && (status == PSA_SUCCESS)) {
128 printf("\tSignature bytes: ");
129 print_byte_array(signature, signature_length);
130 }
131
132 m_all_ok &= (status == PSA_SUCCESS);
133
134 /* Verify signature against original message */
135 if (m_verbose) printf("Verify signature using original message: \"%s\"", hash);
136
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200137 status = m_crypto_client->verify_hash(m_signing_key_id,
Julian Hall38c729b2020-11-23 18:23:03 +0100138 PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), hash, hash_len,
139 signature, signature_length);
140
141 print_status(status);
142
143 m_all_ok &= (status == PSA_SUCCESS);
144
145 /* Verify signature against modified message */
146 hash[0] = '!';
147 if (m_verbose) printf("Verify signature using modified message: \"%s\"", hash);
148
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200149 status = m_crypto_client->verify_hash(m_signing_key_id,
Julian Hall38c729b2020-11-23 18:23:03 +0100150 PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), hash, hash_len,
151 signature, signature_length);
152
153 if (status == PSA_ERROR_INVALID_SIGNATURE) {
154 if (m_verbose) printf("\n\tSuccessfully detected modified message\n");
155 }
156 else {
157 print_status(status);
158 }
159
160 m_all_ok &= (status != PSA_SUCCESS);
161 }
162
163 void generate_asymmetric_encryption_key()
164 {
165 psa_status_t status;
166 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
167
168 psa_set_key_id(&attributes, ENCRYPTION_KEY_ID);
169 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
170 psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT);
171 psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
Imre Kis8a86a002024-01-22 15:43:11 +0100172 psa_set_key_bits(&attributes, 1024);
Julian Hall38c729b2020-11-23 18:23:03 +0100173
174 if (m_verbose) printf("Generating RSA encryption key");
175
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200176 status = m_crypto_client->generate_key(&attributes, &m_encryption_key_id);
Julian Hall38c729b2020-11-23 18:23:03 +0100177 psa_reset_key_attributes(&attributes);
178
179 print_status(status);
180
181 m_all_ok &= (status == PSA_SUCCESS);
182 }
183
184 void encrypt_add_decrypt_message(const char *message)
185 {
186 psa_status_t status;
187 size_t message_len = strlen(message) + 1;
188
189 /* Encrypt a message */
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200190 if (m_verbose) printf("Encrypting message: \"%s\" using RSA key: %d", message, m_encryption_key_id);
Julian Hall38c729b2020-11-23 18:23:03 +0100191
192 uint8_t ciphertext[256];
193 size_t ciphertext_len = 0;
194
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200195 status = m_crypto_client->asymmetric_encrypt(m_encryption_key_id, PSA_ALG_RSA_PKCS1V15_CRYPT,
Julian Hall38c729b2020-11-23 18:23:03 +0100196 (const uint8_t*)message, message_len, NULL, 0,
197 ciphertext, sizeof(ciphertext), &ciphertext_len);
198 print_status(status);
199
200 if (m_verbose && (status == PSA_SUCCESS)) {
201 printf("\tEncrypted message: ");
202 print_byte_array(ciphertext, ciphertext_len);
203 }
204
205 m_all_ok &= (status == PSA_SUCCESS);
206
207 /* Decrypt it */
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200208 if (m_verbose) printf("Decrypting message using RSA key: %d", m_encryption_key_id);
Julian Hall38c729b2020-11-23 18:23:03 +0100209
210 uint8_t plaintext[256];
211 size_t plaintext_len = 0;
212
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200213 status = m_crypto_client->asymmetric_decrypt(m_encryption_key_id, PSA_ALG_RSA_PKCS1V15_CRYPT,
Julian Hall38c729b2020-11-23 18:23:03 +0100214 ciphertext, ciphertext_len, NULL, 0,
215 plaintext, sizeof(plaintext), &plaintext_len);
216 print_status(status);
217
218 if (m_verbose && (status == PSA_SUCCESS)) {
219
220 if ((plaintext_len == message_len) &&
221 (memcmp(message, plaintext, plaintext_len) == 0)) {
222 if (m_verbose) printf("\tDecrypted message: \"%s\"\n", plaintext);
223 }
224 else {
225 printf("\tDecrypted message is different from original!: ");
226 print_byte_array(plaintext, plaintext_len);
227 }
228 }
229
230 m_all_ok &= (status == PSA_SUCCESS);
231 }
232
233 void export_public_key()
234 {
235 psa_status_t status;
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200236 uint8_t key_buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
Julian Hall38c729b2020-11-23 18:23:03 +0100237 size_t key_len = 0;
238
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200239 if (m_verbose) printf("Exporting public key: %d", m_signing_key_id);
Julian Hall38c729b2020-11-23 18:23:03 +0100240
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200241 status = m_crypto_client->export_public_key(m_signing_key_id, key_buf, sizeof(key_buf), &key_len);
Julian Hall38c729b2020-11-23 18:23:03 +0100242
243 print_status(status);
244
245 if (m_verbose && (status == PSA_SUCCESS)) {
246 printf("\tPublic key bytes: ");
247 print_byte_array(key_buf, key_len);
248 }
249
250 m_all_ok &= (status == PSA_SUCCESS);
251 }
252
253 void generate_random_number(size_t length)
254 {
255 psa_status_t status;
256 uint8_t buffer[length];
257
258 if (m_verbose) printf("Generating random bytes length: %ld", length);
259
260 status = m_crypto_client->generate_random(buffer, length);
261
262 print_status(status);
263
264 if (m_verbose && (status == PSA_SUCCESS)) {
265 printf("\tRandom bytes: ");
266 print_byte_array(buffer, length);
267 }
268
269 m_all_ok &= (status == PSA_SUCCESS);
270 }
271
272 void destroy_keys()
273 {
274 psa_status_t status;
275
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200276 if (m_verbose) printf("Destroying signing key: %d", m_signing_key_id);
277 status = m_crypto_client->destroy_key(m_signing_key_id);
Julian Hall38c729b2020-11-23 18:23:03 +0100278 print_status(status);
279 m_all_ok &= (status == PSA_SUCCESS);
280
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200281 if (m_verbose) printf("Destroying encryption key: %d", m_encryption_key_id);
282 status = m_crypto_client->destroy_key(m_encryption_key_id);
Julian Hall38c729b2020-11-23 18:23:03 +0100283 print_status(status);
284 m_all_ok &= (status == PSA_SUCCESS);
285 }
286
287private:
288
289 static const psa_key_id_t SIGNING_KEY_ID = 0x100;
290 static const psa_key_id_t ENCRYPTION_KEY_ID = 0x101;
291
292 crypto_client *m_crypto_client;
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200293 psa_key_id_t m_signing_key_id;
294 psa_key_id_t m_encryption_key_id;
Julian Hall38c729b2020-11-23 18:23:03 +0100295
296 bool m_verbose;
297 bool m_all_ok;
298};
299
300
301int run_ts_demo(crypto_client *crypto_client, bool is_verbose) {
302
303 ts_demo demo(crypto_client, is_verbose);
304
305 demo.print_intro();
306 demo.wait(1);
307 demo.generate_random_number(1);
308 demo.wait(1);
309 demo.generate_random_number(7);
310 demo.wait(1);
311 demo.generate_random_number(128);
312 demo.wait(1);
313 demo.generate_signing_key();
314 demo.wait(2);
315 demo.sign_and_verify_message("The quick brown fox");
316 demo.wait(3);
317 demo.sign_and_verify_message("jumps over the lazy dog");
318 demo.wait(3);
319 demo.generate_asymmetric_encryption_key();
320 demo.wait(2);
321 demo.encrypt_add_decrypt_message("Top secret");
322 demo.wait(3);
323 demo.export_public_key();
324 demo.wait(2);
325 demo.destroy_keys();
326 demo.wait(2);
327
328 return demo.is_all_ok() ? 0 : -1;
329}