1 /*
2 * Copyright The Mbed TLS Contributors
3 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
4 */
5
6
7 #include "psa/crypto.h"
8 #include <string.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include "mbedtls/build_info.h"
12 #include "mbedtls/debug.h"
13 #include "mbedtls/platform.h"
14
15 #define BUFFER_SIZE 500
16
17 #define SERVER_PK_VALUE { \
18 0x04, 0xde, 0xa5, 0xe4, 0x5d, 0x0e, 0xa3, 0x7f, 0xc5, \
19 0x66, 0x23, 0x2a, 0x50, 0x8f, 0x4a, 0xd2, 0x0e, 0xa1, \
20 0x3d, 0x47, 0xe4, 0xbf, 0x5f, 0xa4, 0xd5, 0x4a, 0x57, \
21 0xa0, 0xba, 0x01, 0x20, 0x42, 0x08, 0x70, 0x97, 0x49, \
22 0x6e, 0xfc, 0x58, 0x3f, 0xed, 0x8b, 0x24, 0xa5, 0xb9, \
23 0xbe, 0x9a, 0x51, 0xde, 0x06, 0x3f, 0x5a, 0x00, 0xa8, \
24 0xb6, 0x98, 0xa1, 0x6f, 0xd7, 0xf2, 0x9b, 0x54, 0x85, \
25 0xf3, 0x20 \
26 }
27
28 #define KEY_BITS 256
29
psa_key_agreement_main(void)30 int psa_key_agreement_main(void)
31 {
32 psa_status_t status;
33 psa_key_attributes_t client_attributes = PSA_KEY_ATTRIBUTES_INIT;
34 psa_key_attributes_t server_attributes = PSA_KEY_ATTRIBUTES_INIT;
35 psa_key_attributes_t check_attributes = PSA_KEY_ATTRIBUTES_INIT;
36 psa_key_id_t client_key_id = 0;
37 psa_key_id_t server_key_id = 0;
38 uint8_t client_pk[BUFFER_SIZE] = { 0 };
39 size_t client_pk_len;
40 size_t key_bits;
41 psa_key_type_t key_type;
42
43 const uint8_t server_pk[] = SERVER_PK_VALUE;
44 uint8_t derived_key[BUFFER_SIZE] = { 0 };
45 size_t derived_key_len;
46
47 status = psa_crypto_init();
48 if (status != PSA_SUCCESS) {
49 mbedtls_printf("psa_crypto_init failed\n");
50 return EXIT_FAILURE;
51 }
52
53 psa_set_key_usage_flags(&client_attributes, PSA_KEY_USAGE_DERIVE);
54 psa_set_key_algorithm(&client_attributes, PSA_ALG_ECDH);
55 psa_set_key_type(&client_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
56 psa_set_key_bits(&client_attributes, KEY_BITS);
57
58 /* Generate ephemeral key pair */
59 status = psa_generate_key(&client_attributes, &client_key_id);
60 if (status != PSA_SUCCESS) {
61 mbedtls_printf("psa_generate_key failed\n");
62 return EXIT_FAILURE;
63 }
64 status = psa_export_public_key(client_key_id,
65 client_pk, sizeof(client_pk),
66 &client_pk_len);
67 if (status != PSA_SUCCESS) {
68 mbedtls_printf("psa_export_public_key failed\n");
69 return EXIT_FAILURE;
70 }
71
72 mbedtls_printf("Client Public Key (%" MBEDTLS_PRINTF_SIZET " bytes):\n", client_pk_len);
73
74 for (size_t j = 0; j < client_pk_len; j++) {
75 if (j % 8 == 0) {
76 mbedtls_printf("\n ");
77 }
78 mbedtls_printf("%02x ", client_pk[j]);
79 }
80 mbedtls_printf("\n\n");
81
82 psa_set_key_usage_flags(&server_attributes, PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT);
83 psa_set_key_algorithm(&server_attributes, PSA_ALG_ECDSA_ANY);
84 psa_set_key_type(&server_attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1));
85
86 /* Import server public key */
87 status = psa_import_key(&server_attributes, server_pk, sizeof(server_pk), &server_key_id);
88 if (status != PSA_SUCCESS) {
89 mbedtls_printf("psa_import_key failed\n");
90 return EXIT_FAILURE;
91 }
92
93 status = psa_get_key_attributes(server_key_id, &check_attributes);
94 if (status != PSA_SUCCESS) {
95 mbedtls_printf("psa_get_key_attributes failed\n");
96 return EXIT_FAILURE;
97 }
98
99 key_bits = psa_get_key_bits(&check_attributes);
100 if (key_bits != 256) {
101 mbedtls_printf("Incompatible key size!\n");
102 return EXIT_FAILURE;
103 }
104
105 key_type = psa_get_key_type(&check_attributes);
106 if (key_type != PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1)) {
107 mbedtls_printf("Unsupported key type!\n");
108 return EXIT_FAILURE;
109 }
110
111 mbedtls_printf("Server Public Key (%" MBEDTLS_PRINTF_SIZET " bytes):\n", sizeof(server_pk));
112
113 for (size_t j = 0; j < sizeof(server_pk); j++) {
114 if (j % 8 == 0) {
115 mbedtls_printf("\n ");
116 }
117 mbedtls_printf("%02x ", server_pk[j]);
118 }
119 mbedtls_printf("\n\n");
120
121 /* Generate ECDHE derived key */
122 status = psa_raw_key_agreement(PSA_ALG_ECDH, // algorithm
123 client_key_id, // client secret key
124 server_pk, sizeof(server_pk), // server public key
125 derived_key, sizeof(derived_key), // buffer to store derived key
126 &derived_key_len);
127 if (status != PSA_SUCCESS) {
128 mbedtls_printf("psa_raw_key_agreement failed\n");
129 return EXIT_FAILURE;
130 }
131
132 mbedtls_printf("Derived Key (%" MBEDTLS_PRINTF_SIZET " bytes):\n", derived_key_len);
133
134 for (size_t j = 0; j < derived_key_len; j++) {
135 if (j % 8 == 0) {
136 mbedtls_printf("\n ");
137 }
138 mbedtls_printf("%02x ", derived_key[j]);
139 }
140 mbedtls_printf("\n");
141
142 psa_destroy_key(server_key_id);
143 psa_destroy_key(client_key_id);
144 mbedtls_psa_crypto_free();
145 return EXIT_SUCCESS;
146 }
147