1 /*
2  *  Copyright The Mbed TLS Contributors
3  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
4  */
5 
6 #include "psa/crypto.h"
7 /*
8  * Temporary hack: psasim’s Makefile only does:
9  *  -Itests/psa-client-server/psasim/include
10  *  -I$(MBEDTLS_ROOT_PATH)/include
11  *  -I$(MBEDTLS_ROOT_PATH)/tf-psa-crypto/include
12  *  -I$(MBEDTLS_ROOT_PATH)/tf-psa-crypto/drivers/builtin/include
13  * None of those cover tf-psa-crypto/core, so we rely on the
14  * “-I$(MBEDTLS_ROOT_PATH)/include” entry plus a parent-relative
15  * include "../tf-psa-crypto/core/tf_psa_crypto_common.h" in order to pull in tf_psa_crypto_common.h here,
16  * which in turn gets MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING (to silence the
17  * new GCC-15 unterminated-string-initialization warning).
18  * See GitHub issue #10223 for the proper long-term fix.
19  * https://github.com/Mbed-TLS/mbedtls/issues/10223
20  */
21 #include "../tf-psa-crypto/core/tf_psa_crypto_common.h"
22 #include <string.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 
26 #define BUFFER_SIZE 500
27 
print_bytestr(const uint8_t * bytes,size_t len)28 static void print_bytestr(const uint8_t *bytes, size_t len)
29 {
30     for (unsigned int idx = 0; idx < len; idx++) {
31         printf("%02X", bytes[idx]);
32     }
33 }
34 
psa_aead_encrypt_decrypt_main(void)35 int psa_aead_encrypt_decrypt_main(void)
36 {
37     psa_status_t status;
38     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
39     psa_key_id_t key_id = 0;
40     uint8_t encrypt[BUFFER_SIZE] = { 0 };
41     uint8_t decrypt[BUFFER_SIZE] = { 0 };
42     const uint8_t plaintext[] = "Hello World!";
43     /* We need to tell the compiler that we meant to leave out the null character. */
44     const uint8_t key_bytes[32] MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING =
45         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
46     uint8_t nonce[PSA_AEAD_NONCE_LENGTH(PSA_KEY_TYPE_AES, PSA_ALG_CCM)];
47     size_t nonce_length = sizeof(nonce);
48     size_t ciphertext_length;
49     size_t plaintext_length;
50 
51     status = psa_crypto_init();
52     if (status != PSA_SUCCESS) {
53         printf("psa_crypto_init failed\n");
54         return EXIT_FAILURE;
55     }
56 
57     psa_set_key_usage_flags(&attributes,
58                             PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
59     psa_set_key_algorithm(&attributes, PSA_ALG_CCM);
60     psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
61     psa_set_key_bits(&attributes, 256);
62 
63     status = psa_import_key(&attributes, key_bytes, sizeof(key_bytes), &key_id);
64     if (status != PSA_SUCCESS) {
65         printf("psa_import_key failed\n");
66         return EXIT_FAILURE;
67     }
68 
69     status = psa_generate_random(nonce, nonce_length);
70     if (status != PSA_SUCCESS) {
71         printf("psa_generate_random failed\n");
72         return EXIT_FAILURE;
73     }
74 
75     status = psa_aead_encrypt(key_id,                            // key
76                               PSA_ALG_CCM,                       // algorithm
77                               nonce, nonce_length,               // nonce
78                               NULL, 0,                           // additional data
79                               plaintext, sizeof(plaintext),      // plaintext
80                               encrypt, sizeof(encrypt),          // ciphertext
81                               &ciphertext_length);               // length of output
82     if (status != PSA_SUCCESS) {
83         printf("psa_aead_encrypt failed\n");
84         return EXIT_FAILURE;
85     }
86 
87     printf("AES-CCM encryption:\n");
88     printf("- Plaintext: '%s':\n", plaintext);
89     printf("- Key: ");
90     print_bytestr(key_bytes, sizeof(key_bytes));
91     printf("\n- Nonce: ");
92     print_bytestr(nonce, nonce_length);
93     printf("\n- No additional data\n");
94     printf("- Ciphertext:\n");
95 
96     for (size_t j = 0; j < ciphertext_length; j++) {
97         if (j % 8 == 0) {
98             printf("\n    ");
99         }
100         printf("%02x ", encrypt[j]);
101     }
102 
103     printf("\n");
104 
105     status = psa_aead_decrypt(key_id,                       // key
106                               PSA_ALG_CCM,                  // algorithm
107                               nonce, nonce_length,          // nonce
108                               NULL, 0,                      // additional data
109                               encrypt, ciphertext_length,   // ciphertext
110                               decrypt, sizeof(decrypt),     // plaintext
111                               &plaintext_length);           // length of output
112     if (status != PSA_SUCCESS) {
113         printf("psa_aead_decrypt failed\n");
114         return EXIT_FAILURE;
115     }
116 
117     if (memcmp(plaintext, decrypt, sizeof(plaintext)) != 0) {
118         printf("\nEncryption/Decryption failed!\n");
119     } else {
120         printf("\nEncryption/Decryption successful!\n");
121     }
122 
123     psa_destroy_key(key_id);
124     mbedtls_psa_crypto_free();
125     return 0;
126 }
127