blob: 43b3adbfbe50e6c09021d82d85795a7b595a7a7e [file] [log] [blame]
Gabor Toth70cb3c62023-05-10 12:40:24 +02001/*
2 * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include "ts-demo.h"
8
9#include <psa/crypto.h>
10#include <stdbool.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <unistd.h>
15
16static const psa_key_id_t SIGNING_KEY_ID = 0x100;
17static const psa_key_id_t ENCRYPTION_KEY_ID = 0x101;
18
19bool m_verbose = true;
20
21void print_intro(void)
22{
23 if (m_verbose) {
24 printf("\nDemonstrates use of trusted services from an application");
25 printf("\n---------------------------------------------------------");
26 printf("\nA client requests a set of crypto operations performed by");
27 printf("\nthe Crypto service. Key storage for persistent keys is");
28 printf("\nprovided by the Secure Storage service via the ITS client.\n");
29 printf("\n");
30 }
31}
32
33void wait(int seconds)
34{
35 if (m_verbose)
36 sleep(seconds);
37}
38
39void print_status(psa_status_t status)
40{
41 if (m_verbose) {
42 if (status == PSA_SUCCESS)
43 printf("\n\tOperation successful\n");
44 else
45 printf("\n\tOperation failed. op error: %d\n", status);
46 }
47}
48
49void print_byte_array(const uint8_t *array, size_t len)
50{
51 size_t count = 0;
52 size_t column = 0;
53
54 while (count < len) {
55 if (column == 0)
56 printf("\n\t\t");
57 else
58 printf(" ");
59
60 printf("%02X", array[count]);
61
62 ++count;
63 column = (column + 1) % 8;
64 }
65
66 printf("\n");
67}
68
69bool generate_signing_key(psa_key_id_t *signing_key_id)
70{
71 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
72 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
73
74 psa_set_key_id(&attributes, SIGNING_KEY_ID);
75 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH);
76 psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
77 psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
78 psa_set_key_bits(&attributes, 256);
79
80 if (m_verbose)
81 printf("Generating ECC signing key");
82
83 status = psa_generate_key(&attributes, signing_key_id);
84 psa_reset_key_attributes(&attributes);
85
86 print_status(status);
87
88 return (status != PSA_SUCCESS);
89}
90
91bool sign_and_verify_message(const char *message, psa_key_id_t signing_key_id)
92{
93 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
94 bool error = false;
95 uint8_t message_buffer[100];
96 size_t message_len = strlen(message) + 1;
97
98 if (message_len > sizeof(message_buffer))
99 message_len = sizeof(message_buffer) - 1;
100
101 memset(message_buffer, 0, sizeof(message_buffer));
102 memcpy(message_buffer, message, message_len);
103
104 /* Sign message */
105 uint8_t signature[PSA_SIGNATURE_MAX_SIZE];
106 size_t signature_length;
107
108 if (m_verbose)
109 printf("Signing message: \"%s\" using key: %d", message_buffer, signing_key_id);
110
111 status = psa_sign_hash(signing_key_id, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256),
112 message_buffer, message_len, signature, sizeof(signature),
113 &signature_length);
114
115 print_status(status);
116
117 if (m_verbose && (status == PSA_SUCCESS)) {
118 printf("\tSignature bytes: ");
119 print_byte_array(signature, signature_length);
120 }
121
122 error |= (status != PSA_SUCCESS);
123
124 /* Verify signature against original message */
125 if (m_verbose)
126 printf("Verify signature using original message: \"%s\"", message_buffer);
127
128 status = psa_verify_hash(signing_key_id, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256),
129 message_buffer, message_len, signature, signature_length);
130
131 print_status(status);
132
133 error |= (status != PSA_SUCCESS);
134
135 /* Verify signature against modified message */
136 message_buffer[0] = '!';
137 if (m_verbose)
138 printf("Verify signature using modified message: \"%s\"", message_buffer);
139
140 status = psa_verify_hash(signing_key_id, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256),
141 message_buffer, message_len, signature, signature_length);
142
143 if (status == PSA_ERROR_INVALID_SIGNATURE) {
144 if (m_verbose)
145 printf("\n\tSuccessfully detected modified message\n");
146 } else {
147 print_status(status);
148 }
149
150 error |= (status == PSA_SUCCESS);
151
152 return error;
153}
154
155bool generate_asymmetric_encryption_key(psa_key_id_t *encryption_key_id)
156{
157 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
158 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
159
160 psa_set_key_id(&attributes, ENCRYPTION_KEY_ID);
161 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
162 psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT);
163 psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
164 psa_set_key_bits(&attributes, 1024);
165
166 if (m_verbose)
167 printf("Generating RSA encryption key");
168
169 status = psa_generate_key(&attributes, encryption_key_id);
170 psa_reset_key_attributes(&attributes);
171
172 print_status(status);
173
174 return (status != PSA_SUCCESS);
175}
176
177bool encrypt_add_decrypt_message(const char *message, psa_key_id_t encryption_key_id)
178{
179 bool error = false;
180 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
181 size_t message_len = strlen(message) + 1;
182
183 /* Encrypt a message */
184 if (m_verbose)
185 printf("Encrypt message: \"%s\" using RSA key: %d", message, encryption_key_id);
186
187 uint8_t ciphertext[256];
188 size_t ciphertext_len = 0;
189
190 status = psa_asymmetric_encrypt(encryption_key_id, PSA_ALG_RSA_PKCS1V15_CRYPT,
191 (const uint8_t *)message, message_len, NULL, 0, ciphertext,
192 sizeof(ciphertext), &ciphertext_len);
193 print_status(status);
194
195 if (m_verbose && (status == PSA_SUCCESS)) {
196 printf("\tEncrypted message: ");
197 print_byte_array(ciphertext, ciphertext_len);
198 }
199
200 error |= (status != PSA_SUCCESS);
201
202 /* Decrypt it */
203 if (m_verbose)
204 printf("Decrypting message using RSA key: %d", encryption_key_id);
205
206 uint8_t plaintext[256];
207 size_t plaintext_len = 0;
208
209 status = psa_asymmetric_decrypt(encryption_key_id, PSA_ALG_RSA_PKCS1V15_CRYPT, ciphertext,
210 ciphertext_len, NULL, 0, plaintext, sizeof(plaintext),
211 &plaintext_len);
212 print_status(status);
213
214 if (m_verbose && (status == PSA_SUCCESS)) {
215 if ((plaintext_len == message_len) &&
216 (memcmp(message, plaintext, plaintext_len) == 0)) {
217 printf("\tDecrypted message: \"%s\"\n", plaintext);
218 } else {
219 printf("\tDecrypted message is different from original!: ");
220 print_byte_array(plaintext, plaintext_len);
221 }
222 }
223
224 error |= (status != PSA_SUCCESS);
225
226 return error;
227}
228
229bool export_public_key(psa_key_id_t signing_key_id)
230{
231 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
232 uint8_t key_buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
233 size_t key_len = 0;
234
235 if (m_verbose)
236 printf("Exporting public key: %d", signing_key_id);
237
238 status = psa_export_public_key(signing_key_id, key_buf, sizeof(key_buf), &key_len);
239
240 print_status(status);
241
242 if (m_verbose && (status == PSA_SUCCESS)) {
243 printf("\tPublic key bytes: ");
244 print_byte_array(key_buf, key_len);
245 }
246
247 return (status != PSA_SUCCESS);
248}
249
250bool generate_random_number(size_t length)
251{
252 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
253 uint8_t *buffer = (uint8_t *)malloc(length);
254
255 if (m_verbose)
256 printf("Generating random bytes length: %lu", length);
257
258 status = psa_generate_random(buffer, length);
259
260 print_status(status);
261
262 if (m_verbose && (status == PSA_SUCCESS)) {
263 printf("\tRandom bytes: ");
264 print_byte_array(buffer, length);
265 }
266
267 return (status != PSA_SUCCESS);
268}
269
270bool destroy_keys(psa_key_id_t signing_key_id, psa_key_id_t encryption_key_id)
271{
272 bool error = false;
273 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
274
275 if (m_verbose)
276 printf("Destroying signing key: %d", signing_key_id);
277
278 status = psa_destroy_key(signing_key_id);
279 print_status(status);
280 error |= (status != PSA_SUCCESS);
281
282 if (m_verbose)
283 printf("Destroying encryption key: %d", encryption_key_id);
284
285 status = psa_destroy_key(encryption_key_id);
286 print_status(status);
287 error |= (status != PSA_SUCCESS);
288
289 return error;
290}
291
292bool run_ts_demo(bool is_verbose)
293{
294 psa_key_id_t signing_key_id = 0;
295 psa_key_id_t encryption_key_id = 0;
296 bool error = false;
297
298 m_verbose = is_verbose;
299 print_intro();
300 wait(1);
301 psa_crypto_init();
302 wait(1);
303 error |= generate_random_number(1);
304 wait(1);
305 error |= generate_random_number(7);
306 wait(1);
307 error |= generate_random_number(128);
308 wait(1);
309 error |= generate_signing_key(&signing_key_id);
310 wait(2);
311 error |= sign_and_verify_message("The quick brown fox", signing_key_id);
312 wait(3);
313 error |= sign_and_verify_message("jumps over the lazy dog", signing_key_id);
314 wait(3);
315 error |= generate_asymmetric_encryption_key(&encryption_key_id);
316 wait(2);
317 error |= encrypt_add_decrypt_message("Top secret", encryption_key_id);
318 wait(3);
319 error |= export_public_key(signing_key_id);
320 wait(2);
321 error |= destroy_keys(signing_key_id, encryption_key_id);
322 wait(2);
323
324 return error;
325}