I want to collect certain data from my application using the driver and transfer it to the server to check its integrity. And I want to sign these packages using TPM to avoid forgery. However, a user can trick my program by writing a similar driver and intercepting, for example, messages to and from the server, replacing them with their own. What can I do? Is it possible to defend against this?
You can't. You're running into a classic problem: the user has physical access and there's absolutely nothing you can do to concretely prevent them from modifying things.
You can certainly make it harder for them to attack, for example by using HTTPS with certificate pinning for your network communications so that they can't simply man-in-the-middle the traffic, but if the user writes their own driver to mess with your driver you really can't do much about it.
The strongest protection I can think of on a modern x86 system would be for your to get your code running in an SGX enclave, but this is a rather complicated task that requires a lot of development effort. The sensitive parts of your driver code would run inside of the enclave and a regular kernel-mode driver would talk to it through ECALLs/OCALLs. This doesn't prevent the user from blocking the driver from running though, nor does it prevent the user from reverse engineering the executables on disk and writing their own tool or driver to send requests to your server.
If your goal is to prevent the user from modifying something, then you need to have more privileges and access than they do. But in the case of your code running on their computer, they always have more privileges and access than you do, by design. You can't work around this.