static int gen_auth_key(mbedtls_ecdh_context *key, const char *tempKey, const char *salt, unsigned char *buf, size_t bufLen) { int ret = 0; size_t olen = 0; if ((errno = dslink_base64_url_decode(buf, bufLen, &olen, (unsigned char *) tempKey, strlen(tempKey))) != 0) { ret = DSLINK_CRYPT_BASE64_URL_DECODE_ERR; goto exit; } if ((errno = mbedtls_ecp_point_read_binary(&key->grp, &key->Qp, buf, olen)) != 0) { ret = DSLINK_HANDSHAKE_INVALID_TMP_KEY; goto exit; } if ((errno = mbedtls_ecdh_calc_secret(key, &olen, buf, bufLen, NULL, NULL)) != 0) { ret = DSLINK_HANDSHAKE_INVALID_TMP_KEY; goto exit; } { size_t saltLen = strlen(salt); size_t len = saltLen + olen; char *in = malloc(len + 1); if (!in) { ret = DSLINK_ALLOC_ERR; goto exit; } memcpy(in, salt, saltLen); memcpy(in + saltLen, (char *) buf, olen); *(in + len) = '\0'; unsigned char auth[32]; mbedtls_sha256((unsigned char *) in, len, auth, 0); free(in); if ((errno = dslink_base64_url_encode(buf, bufLen, &olen, auth, sizeof(auth))) != 0) { ret = DSLINK_CRYPT_BASE64_URL_ENCODE_ERR; } } exit: return ret; }
TEE_Result crypto_acipher_ecc_shared_secret(struct ecc_keypair *private_key, struct ecc_public_key *public_key, void *secret, unsigned long *secret_len) { TEE_Result res = TEE_SUCCESS; int lmd_res = 0; uint8_t one[1] = { 1 }; mbedtls_ecdh_context ecdh; size_t out_len = 0; memset(&ecdh, 0, sizeof(ecdh)); mbedtls_ecdh_init(&ecdh); lmd_res = mbedtls_ecp_group_load(&ecdh.grp, private_key->curve); if (lmd_res != 0) { res = TEE_ERROR_NOT_SUPPORTED; goto out; } ecdh.d = *(mbedtls_mpi *)private_key->d; ecdh.Qp.X = *(mbedtls_mpi *)public_key->x; ecdh.Qp.Y = *(mbedtls_mpi *)public_key->y; mbedtls_mpi_read_binary(&ecdh.Qp.Z, one, sizeof(one)); lmd_res = mbedtls_ecdh_calc_secret(&ecdh, &out_len, secret, *secret_len, mbd_rand, NULL); if (lmd_res != 0) { res = get_tee_result(lmd_res); goto out; } *secret_len = out_len; out: /* Reset mpi to skip freeing here, those mpis will be freed with key */ mbedtls_mpi_init(&ecdh.d); mbedtls_mpi_init(&ecdh.Qp.X); mbedtls_mpi_init(&ecdh.Qp.Y); mbedtls_ecdh_free(&ecdh); return res; }