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 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 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 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 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 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