Is it safe to send IV in plain text for every request? Currently, I am creating a project with an IoT device. This is an offline device which shows a QR code which can be scanned by a mobile device, which sends this code to a server. The server handles data but does not send anything back.

The plaintext data part of the QR code needs to be encrypted and should not be changed, nor intercepted, so I made the following protocol:


The IoT device generates a new EC keypair at every boot;
The server has a permanent EC keypair. The server public key is stored in the firmware of the IoT device;
When creating a QR-code, the IoT device calculates a DH agreement with the server's public key and the private key of the IoT device;
The IoT device creates an IV from an incremented nonce (8 bytes array);
The data gets encrypted using chacha20 with the calculated agreement;


The QR code is then generated using the following format: (IoT public key) + (iv) + (ciphertext).

The server is then able to decrypt the ciphertext by using the IoT public key, which can be used for calculating the agreement and the IV for decrypting the ciphertext.

Now I have several concerns since I am new to crypto and I am almost sure that my protocol is not safe enough.


Is it safe to embed and send the IV in plain text in every QR-code?
When using the same nonce, decryption will still work, what is the purpose or misuse of the nonce here?
Should I use chacha20 at all? Or is there a much better encryption/decryption method to use here?
I need to keep my server's public key secret and only in the firmware of the IoT device, to prevent 'fake devices' generating valid but fake QR codes, which sounds bad.
Is it safe to send the IV in plain text in every QR code request?
  


IV is not secret and never meant to be, it can be sent as it is. See the CBC mode from the Wikipedia.


  
  When using the same nonce, decryption will still work, what is the purpose or misuse of the nonce here?
  


Nonce (in Cryptography) means number used once. The IV in the CBC mode cannot be nonce. The aim of IV is randomizing the encryptions. Using the same IV again turns the CBC mode into the ECB mode. This has catastrophic results, see the penguin from Wikipedia in or look at frequency attack. 

For the difference of IV and Nonce please see Difference between a nonce and IV


  
  Should I use chacha20 at all? Or is there a much more better encryption/decryption method to use here?
  


You need authenticated encryption which simultaneously give authenticity and integrity. You may choose ChaCha20Poly1305 or AES-GCM.


  
  I need to keep my server's public key secret and only in the firmware of the IoT device, to prevent 'fake devices' generating valid but fake QR codes, which sounds bad.
  


Public keys are not created to be kept secret. The more important is the ID of the IoT that should be sent during the data transmission so that the server can accept the result. Therefore the server must store the ID's beforehand. In the current design, the server is going to accept any message.

Note: You will also need to authenticate the mobile device, otherwise any mobile device can be used to attack. 

Note 2: IV should not be predictable.

Note 3: You don't need to generate if from a nonce. A good random source should be enough. See  Best way to generate a IV for AES-CBC when encrypting files?