1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (C) Foundries Ltd. 2022. 4 * Author: Jorge Ramirez <jorge@foundries.io> 5 */ 6 7 #include <crypto/crypto_impl.h> 8 #include <drvcrypt.h> 9 #include <drvcrypt_acipher.h> 10 #include <ecc.h> 11 #include <ipi.h> 12 #include <mm/core_memprot.h> 13 #include <kernel/panic.h> 14 #include <string.h> 15 #include <tee/cache.h> 16 #include <tee/tee_cryp_utl.h> 17 #include <util.h> 18 19 /* AMD/Xilinx Versal's Known Answer Tests */ 20 #define XSECURE_ECC_PRIME 0 21 #define XSECURE_ECC_BINARY 1 22 23 enum versal_ecc_err { 24 KAT_KEY_NOTVALID_ERROR = 0xC0, 25 KAT_FAILED_ERROR, 26 NON_SUPPORTED_CURVE, 27 KEY_ZERO, 28 KEY_WRONG_ORDER, 29 KEY_NOT_ON_CURVE, 30 BAD_SIGN, 31 GEN_SIGN_INCORRECT_HASH_LEN, 32 VER_SIGN_INCORRECT_HASH_LEN, 33 GEN_SIGN_BAD_RAND_NUM, 34 GEN_KEY_ERR, 35 INVALID_PARAM, 36 VER_SIGN_R_ZERO, 37 VER_SIGN_S_ZERO, 38 VER_SIGN_R_ORDER_ERROR, 39 VER_SIGN_S_ORDER_ERROR, 40 KAT_INVLD_CRV_ERROR, 41 }; 42 43 #define VERSAL_ECC_ERROR(m) { .error = (m), .name = TO_STR(m) } 44 45 static const char *versal_ecc_error(uint8_t err) 46 { 47 struct { 48 enum versal_ecc_err error; 49 const char *name; 50 } elist[] = { 51 VERSAL_ECC_ERROR(KAT_KEY_NOTVALID_ERROR), 52 VERSAL_ECC_ERROR(KAT_FAILED_ERROR), 53 VERSAL_ECC_ERROR(NON_SUPPORTED_CURVE), 54 VERSAL_ECC_ERROR(KEY_ZERO), 55 VERSAL_ECC_ERROR(KEY_WRONG_ORDER), 56 VERSAL_ECC_ERROR(KEY_NOT_ON_CURVE), 57 VERSAL_ECC_ERROR(BAD_SIGN), 58 VERSAL_ECC_ERROR(GEN_SIGN_INCORRECT_HASH_LEN), 59 VERSAL_ECC_ERROR(VER_SIGN_INCORRECT_HASH_LEN), 60 VERSAL_ECC_ERROR(GEN_SIGN_BAD_RAND_NUM), 61 VERSAL_ECC_ERROR(GEN_KEY_ERR), 62 VERSAL_ECC_ERROR(INVALID_PARAM), 63 VERSAL_ECC_ERROR(VER_SIGN_R_ZERO), 64 VERSAL_ECC_ERROR(VER_SIGN_S_ZERO), 65 VERSAL_ECC_ERROR(VER_SIGN_R_ORDER_ERROR), 66 VERSAL_ECC_ERROR(VER_SIGN_S_ORDER_ERROR), 67 VERSAL_ECC_ERROR(KAT_INVLD_CRV_ERROR), 68 }; 69 70 if (err <= KAT_INVLD_CRV_ERROR && err >= KAT_KEY_NOTVALID_ERROR) { 71 if (elist[err - KAT_KEY_NOTVALID_ERROR].name) 72 return elist[err - KAT_KEY_NOTVALID_ERROR].name; 73 74 return "Invalid"; 75 } 76 77 return "Unknown"; 78 } 79 80 static TEE_Result ecc_get_key_size(uint32_t curve, size_t *bytes, size_t *bits) 81 { 82 switch (curve) { 83 case TEE_ECC_CURVE_NIST_P256: 84 *bits = 256; 85 *bytes = 32; 86 break; 87 case TEE_ECC_CURVE_NIST_P384: 88 *bits = 384; 89 *bytes = 48; 90 break; 91 case TEE_ECC_CURVE_NIST_P521: 92 *bits = 521; 93 *bytes = 66; 94 break; 95 default: 96 return TEE_ERROR_NOT_SUPPORTED; 97 } 98 99 return TEE_SUCCESS; 100 } 101 102 static void memcpy_swp(uint8_t *to, const uint8_t *from, size_t len) 103 { 104 size_t i = 0; 105 106 for (i = 0; i < len; i++) 107 to[i] = from[len - 1 - i]; 108 } 109 110 static void crypto_bignum_bn2bin_eswap(uint32_t curve, 111 struct bignum *from, uint8_t *to) 112 { 113 uint8_t pad[66] = { 0 }; 114 size_t len = crypto_bignum_num_bytes(from); 115 size_t bytes = 0; 116 size_t bits = 0; 117 118 if (ecc_get_key_size(curve, &bytes, &bits)) 119 panic(); 120 121 crypto_bignum_bn2bin(from, pad + bytes - len); 122 memcpy_swp(to, pad, bytes); 123 } 124 125 static TEE_Result ecc_prepare_msg(uint32_t algo, const uint8_t *msg, 126 size_t msg_len, struct versal_mbox_mem *p) 127 { 128 uint8_t swp[TEE_SHA512_HASH_SIZE + 2] = { 0 }; 129 size_t len = 0; 130 131 if (msg_len > TEE_SHA512_HASH_SIZE + 2) 132 return TEE_ERROR_BAD_PARAMETERS; 133 134 if (algo == TEE_ALG_ECDSA_SHA256) 135 len = TEE_SHA256_HASH_SIZE; 136 else if (algo == TEE_ALG_ECDSA_SHA384) 137 len = TEE_SHA384_HASH_SIZE; 138 else if (algo == TEE_ALG_ECDSA_SHA512) 139 len = TEE_SHA512_HASH_SIZE + 2; 140 else 141 return TEE_ERROR_NOT_SUPPORTED; 142 143 /* Swap the hash/message and pad if necessary */ 144 memcpy_swp(swp, msg, msg_len); 145 return versal_mbox_alloc(len, swp, p); 146 } 147 148 TEE_Result versal_ecc_verify(uint32_t algo, struct ecc_public_key *key, 149 const uint8_t *msg, size_t msg_len, 150 const uint8_t *sig, size_t sig_len) 151 { 152 TEE_Result ret = TEE_SUCCESS; 153 struct versal_ecc_verify_param *cmd = NULL; 154 struct versal_cmd_args arg = { }; 155 struct versal_mbox_mem x = { }; 156 struct versal_mbox_mem s = { }; 157 struct versal_mbox_mem p = { }; 158 struct versal_mbox_mem cmd_buf = { }; 159 uint32_t err = 0; 160 size_t bytes = 0; 161 size_t bits = 0; 162 163 if (sig_len % 2) 164 return TEE_ERROR_SIGNATURE_INVALID; 165 166 ret = ecc_get_key_size(key->curve, &bytes, &bits); 167 if (ret) 168 return ret; 169 170 ret = ecc_prepare_msg(algo, msg, msg_len, &p); 171 if (ret) 172 return ret; 173 174 ret = versal_mbox_alloc(bytes * 2, NULL, &x); 175 if (ret) 176 goto out; 177 178 crypto_bignum_bn2bin_eswap(key->curve, key->x, x.buf); 179 crypto_bignum_bn2bin_eswap(key->curve, key->y, 180 (uint8_t *)x.buf + bytes); 181 /* Validate the public key for the curve */ 182 arg.data[0] = key->curve; 183 arg.dlen = 1; 184 arg.ibuf[0].mem = x; 185 if (versal_crypto_request(VERSAL_ELLIPTIC_VALIDATE_PUBLIC_KEY, 186 &arg, &err)) { 187 EMSG("Versal ECC: %s", versal_ecc_error(err)); 188 ret = TEE_ERROR_GENERIC; 189 goto out; 190 } 191 memset(&arg, 0, sizeof(arg)); 192 193 ret = versal_mbox_alloc(sig_len, NULL, &s); 194 if (ret) 195 goto out; 196 197 /* Swap the {R,S} components */ 198 memcpy_swp(s.buf, sig, sig_len / 2); 199 memcpy_swp((uint8_t *)s.buf + sig_len / 2, sig + sig_len / 2, 200 sig_len / 2); 201 202 ret = versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf); 203 if (ret) 204 goto out; 205 206 cmd = cmd_buf.buf; 207 cmd->signature_addr = virt_to_phys(s.buf); 208 cmd->pub_key_addr = virt_to_phys(x.buf); 209 cmd->hash_addr = virt_to_phys(p.buf); 210 cmd->hash_len = p.len; 211 cmd->curve = key->curve; 212 213 arg.ibuf[0].mem = cmd_buf; 214 arg.ibuf[1].mem = p; 215 arg.ibuf[1].only_cache = true; 216 arg.ibuf[2].mem = x; 217 arg.ibuf[3].mem = s; 218 219 if (versal_crypto_request(VERSAL_ELLIPTIC_VERIFY_SIGN, &arg, &err)) { 220 EMSG("Versal ECC: %s", versal_ecc_error(err)); 221 ret = TEE_ERROR_GENERIC; 222 } 223 224 out: 225 versal_mbox_free(&cmd_buf); 226 versal_mbox_free(&s); 227 versal_mbox_free(&x); 228 versal_mbox_free(&p); 229 230 return ret; 231 } 232 233 TEE_Result versal_ecc_sign(uint32_t algo, struct ecc_keypair *key, 234 const uint8_t *msg, size_t msg_len, 235 uint8_t *sig, size_t *sig_len) 236 { 237 struct versal_ecc_sign_param *cmd = NULL; 238 struct versal_mbox_mem cmd_buf = { }; 239 struct ecc_keypair ephemeral = { }; 240 struct versal_cmd_args arg = { }; 241 struct versal_mbox_mem p = { }; 242 struct versal_mbox_mem k = { }; 243 struct versal_mbox_mem d = { }; 244 struct versal_mbox_mem s = { }; 245 TEE_Result ret = TEE_SUCCESS; 246 uint32_t err = 0; 247 size_t bytes = 0; 248 size_t bits = 0; 249 250 ret = ecc_get_key_size(key->curve, &bytes, &bits); 251 if (ret) 252 return ret; 253 254 /* Hash and update the length */ 255 ret = ecc_prepare_msg(algo, msg, msg_len, &p); 256 if (ret) 257 return ret; 258 259 /* Ephemeral private key */ 260 ret = drvcrypt_asym_alloc_ecc_keypair(&ephemeral, 261 TEE_TYPE_ECDSA_KEYPAIR, bits); 262 if (ret) { 263 EMSG("Versal, can't allocate the ephemeral key"); 264 goto out; 265 } 266 267 ephemeral.curve = key->curve; 268 ret = crypto_acipher_gen_ecc_key(&ephemeral, bits); 269 if (ret) { 270 EMSG("Versal, can't generate the ephemeral key"); 271 goto out; 272 } 273 274 ret = versal_mbox_alloc(bytes, NULL, &k); 275 if (ret) 276 goto out; 277 278 crypto_bignum_bn2bin_eswap(key->curve, ephemeral.d, k.buf); 279 280 /* Private key*/ 281 ret = versal_mbox_alloc(bytes, NULL, &d); 282 if (ret) 283 goto out; 284 285 crypto_bignum_bn2bin_eswap(key->curve, key->d, d.buf); 286 287 /* Signature */ 288 ret = versal_mbox_alloc(*sig_len, NULL, &s); 289 if (ret) 290 goto out; 291 292 /* IPI command */ 293 ret = versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf); 294 if (ret) 295 goto out; 296 297 cmd = cmd_buf.buf; 298 cmd->priv_key_addr = virt_to_phys(d.buf); 299 cmd->epriv_key_addr = virt_to_phys(k.buf); 300 cmd->hash_addr = virt_to_phys(p.buf); 301 cmd->hash_len = p.len; 302 cmd->curve = key->curve; 303 304 arg.ibuf[0].mem = cmd_buf; 305 arg.ibuf[1].mem = s; 306 arg.ibuf[2].mem = k; 307 arg.ibuf[3].mem = d; 308 arg.ibuf[4].mem = p; 309 310 if (versal_crypto_request(VERSAL_ELLIPTIC_GENERATE_SIGN, &arg, &err)) { 311 EMSG("Versal ECC: %s", versal_ecc_error(err)); 312 ret = TEE_ERROR_GENERIC; 313 goto out; 314 } 315 316 *sig_len = 2 * bytes; 317 318 /* Swap the {R,S} components */ 319 memcpy_swp(sig, s.buf, *sig_len / 2); 320 memcpy_swp(sig + *sig_len / 2, (uint8_t *)s.buf + *sig_len / 2, 321 *sig_len / 2); 322 323 out: 324 versal_mbox_free(&cmd_buf); 325 versal_mbox_free(&s); 326 versal_mbox_free(&d); 327 versal_mbox_free(&k); 328 329 crypto_bignum_free(&ephemeral.d); 330 crypto_bignum_free(&ephemeral.x); 331 crypto_bignum_free(&ephemeral.y); 332 333 versal_mbox_free(&p); 334 335 return ret; 336 } 337 338 TEE_Result versal_ecc_gen_keypair(struct ecc_keypair *s __maybe_unused) 339 { 340 return TEE_ERROR_NOT_SUPPORTED; 341 } 342 343 TEE_Result versal_ecc_kat_test(void) 344 { 345 struct versal_cmd_args arg = { }; 346 uint32_t err = 0; 347 348 arg.data[arg.dlen++] = VERSAL_ELLIPTIC_SIGN_GEN_KAT; 349 arg.data[arg.dlen++] = XSECURE_ECC_PRIME; 350 if (versal_crypto_request(VERSAL_KAT, &arg, &err)) { 351 EMSG("Versal KAT ECC SignGen: %s", versal_ecc_error(err)); 352 return TEE_ERROR_GENERIC; 353 } 354 355 /* Clean previous request */ 356 arg.dlen = 0; 357 358 arg.data[arg.dlen++] = VERSAL_ELLIPTIC_SIGN_VERIFY_KAT; 359 arg.data[arg.dlen++] = XSECURE_ECC_PRIME; 360 if (versal_crypto_request(VERSAL_KAT, &arg, &err)) { 361 EMSG("Versal KAT ECC SignVerify: %s", versal_ecc_error(err)); 362 return TEE_ERROR_GENERIC; 363 } 364 365 return TEE_SUCCESS; 366 } 367 368 TEE_Result versal_ecc_hw_init(void) 369 { 370 return TEE_SUCCESS; 371 } 372