1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (C) 2024, Institute of Information Security (IISEC)
4 */
5
6 #include <crypto/crypto.h>
7 #include <crypto/crypto_impl.h>
8 #include <stdlib_ext.h>
9 #include <string.h>
10 #include <utee_defines.h>
11
12 #include "sign.h"
13
14 #define KEY_SIZE 32
15 #define KEY_SIZE_BIT (KEY_SIZE * 8)
16
17 static struct ecc_keypair *key;
18 static struct ecc_public_key *pubkey;
19
20 #ifdef CFG_VERAISON_ATTESTATION_PTA_TEST_KEY
21 /*
22 * FIXME: Currently, keys are directly embedded within the code. From a security
23 * standpoint these keys should be stored in a secure location and properly
24 * loaded during program execution in a production environment.
25 * The key information has been extracted using the command:
26 * $ echo "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4=" | base64 -d | xxd -p
27 * (and similar steps for obtaining the x, y, d values).
28 *
29 * {
30 * "kty": "EC",
31 * "crv": "P-256",
32 * "x": "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4",
33 * "y": "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM",
34 * "d": "870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE"
35 * }
36 */
37
38 /* clang-format off */
39 #define PUBLIC_KEY_X { \
40 0x30, 0xa0, 0x42, 0x4c, 0xd2, 0x1c, 0x29, 0x44, \
41 0x83, 0x8a, 0x2d, 0x75, 0xc9, 0x2b, 0x37, 0xe7, \
42 0x6e, 0xa2, 0x0d, 0x9f, 0x00, 0x89, 0x3a, 0x3b, \
43 0x4e, 0xee, 0x8a, 0x3c, 0x0a, 0xaf, 0xec, 0x3e \
44 }
45 #define PUBLIC_KEY_Y { \
46 0xe0, 0x4b, 0x65, 0xe9, 0x24, 0x56, 0xd9, 0x88, \
47 0x8b, 0x52, 0xb3, 0x79, 0xbd, 0xfb, 0xd5, 0x1e, \
48 0xe8, 0x69, 0xef, 0x1f, 0x0f, 0xc6, 0x5b, 0x66, \
49 0x59, 0x69, 0x5b, 0x6c, 0xce, 0x08, 0x17, 0x23 \
50 }
51 #define PRIVATE_KEY { \
52 0xf3, 0xbd, 0x0c, 0x07, 0xa8, 0x1f, 0xb9, 0x32, \
53 0x78, 0x1e, 0xd5, 0x27, 0x52, 0xf6, 0x0c, 0xc8, \
54 0x9a, 0x6b, 0xe5, 0xe5, 0x19, 0x34, 0xfe, 0x01, \
55 0x93, 0x8d, 0xdb, 0x55, 0xd8, 0xf7, 0x78, 0x01 \
56 }
57 /* clang-format on */
58 #else
59 #error "This is experimental code, requires " \
60 "CFG_VERAISON_ATTESTATION_PTA_TEST_KEY=y"
61 #endif
62
hash_sha256(const uint8_t * msg,size_t msg_len,uint8_t * hash)63 static TEE_Result hash_sha256(const uint8_t *msg, size_t msg_len, uint8_t *hash)
64 {
65 TEE_Result res = TEE_SUCCESS;
66 void *ctx = NULL;
67
68 res = crypto_hash_alloc_ctx(&ctx, TEE_ALG_SHA256);
69 if (res != TEE_SUCCESS)
70 return res;
71 res = crypto_hash_init(ctx);
72 if (res != TEE_SUCCESS)
73 goto out;
74 res = crypto_hash_update(ctx, msg, msg_len);
75 if (res != TEE_SUCCESS)
76 goto out;
77 res = crypto_hash_final(ctx, hash, TEE_SHA256_HASH_SIZE);
78
79 out:
80 crypto_hash_free_ctx(ctx);
81 return res;
82 }
83
free_keypair(void)84 static void free_keypair(void)
85 {
86 if (!key)
87 return;
88
89 crypto_bignum_free(&key->d);
90 crypto_bignum_free(&key->x);
91 crypto_bignum_free(&key->y);
92
93 free_wipe(key);
94 key = NULL;
95 }
96
free_pubkey(void)97 static void free_pubkey(void)
98 {
99 if (!pubkey)
100 return;
101
102 crypto_bignum_free(&pubkey->x);
103 crypto_bignum_free(&pubkey->y);
104
105 free_wipe(pubkey);
106 pubkey = NULL;
107 }
108
generate_key(void)109 static TEE_Result generate_key(void)
110 {
111 TEE_Result res = TEE_SUCCESS;
112 const uint8_t private_key[] = PRIVATE_KEY;
113 const uint8_t public_key_x[] = PUBLIC_KEY_X;
114 const uint8_t public_key_y[] = PUBLIC_KEY_Y;
115
116 /* Allocate a private key storage */
117 assert(!key);
118 key = calloc(1, sizeof(*key));
119 if (!key)
120 return TEE_ERROR_OUT_OF_MEMORY;
121 res = crypto_acipher_alloc_ecc_keypair(key, TEE_TYPE_ECDSA_KEYPAIR,
122 KEY_SIZE_BIT);
123 if (res != TEE_SUCCESS)
124 goto free_keypair;
125 key->curve = TEE_ECC_CURVE_NIST_P256;
126
127 /* Copy the private key */
128 res = crypto_bignum_bin2bn(private_key, KEY_SIZE, key->d);
129 if (res != TEE_SUCCESS)
130 goto free_keypair;
131
132 /* Allocate a public key storage */
133 assert(!pubkey);
134 pubkey = calloc(1, sizeof(*pubkey));
135 if (!pubkey) {
136 res = TEE_ERROR_OUT_OF_MEMORY;
137 goto free_keypair;
138 }
139 res = crypto_acipher_alloc_ecc_public_key(pubkey,
140 TEE_TYPE_ECDSA_PUBLIC_KEY,
141 KEY_SIZE_BIT);
142 if (res != TEE_SUCCESS)
143 goto free_pubkey;
144 pubkey->curve = TEE_ECC_CURVE_NIST_P256;
145
146 /* Copy the public key */
147 res = crypto_bignum_bin2bn(public_key_x, KEY_SIZE, pubkey->x);
148 if (res != TEE_SUCCESS)
149 goto free_pubkey;
150
151 res = crypto_bignum_bin2bn(public_key_y, KEY_SIZE, pubkey->y);
152 if (res != TEE_SUCCESS)
153 goto free_pubkey;
154
155 return TEE_SUCCESS;
156
157 free_pubkey:
158 free_pubkey();
159 free_keypair:
160 free_keypair();
161
162 return res;
163 }
164
sign_ecdsa_sha256(const uint8_t * msg,size_t msg_len,uint8_t * sig,size_t * sig_len)165 TEE_Result sign_ecdsa_sha256(const uint8_t *msg, size_t msg_len, uint8_t *sig,
166 size_t *sig_len)
167 {
168 TEE_Result res = TEE_SUCCESS;
169 uint8_t hash_msg[TEE_SHA256_HASH_SIZE] = { };
170
171 /* Allocate the key pair*/
172 res = generate_key();
173 if (res != TEE_SUCCESS)
174 return res;
175
176 /* Hash the msg */
177 res = hash_sha256(msg, msg_len, hash_msg);
178 if (res != TEE_SUCCESS)
179 goto free;
180
181 /* Sign the hashed msg by the key pair*/
182 res = crypto_acipher_ecc_sign(TEE_ALG_ECDSA_SHA256, key, hash_msg,
183 TEE_SHA256_HASH_SIZE, sig, sig_len);
184 if (res != TEE_SUCCESS)
185 goto free;
186
187 /* Verify the signature */
188 res = crypto_acipher_ecc_verify(TEE_ALG_ECDSA_SHA256, pubkey, hash_msg,
189 TEE_SHA256_HASH_SIZE, sig, *sig_len);
190 if (res == TEE_SUCCESS)
191 DMSG("Success to verify");
192 else
193 DMSG("Failed to verify");
194
195 free:
196 free_pubkey();
197 assert(!pubkey);
198 free_keypair();
199 assert(!key);
200
201 return res;
202 }
203