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