#ifndef _CRYPT_H_ #define _CRYPT_H_ #include #include #include #define CRYPT_KX_PKEY_LEN crypto_kx_PUBLICKEYBYTES #define CRYPT_KX_SKEY_LEN crypto_kx_SECRETKEYBYTES #define CRYPT_SIGN_PKEY_LEN crypto_sign_PUBLICKEYBYTES #define CRYPT_SIGN_SKEY_LEN crypto_sign_SECRETKEYBYTES #define CRYPT_SIGN_LEN crypto_sign_BYTES #define CRYPT_SESS_KEY_LEN crypto_kx_SESSIONKEYBYTES #define CRYPT_NONCE_LEN crypto_aead_aegis256_NPUBBYTES #define CRYPT_NONCEHALF_LEN (CRYPT_NONCE_LEN/2) #define CRYPT_HELLO_LEN (CRYPT_PKEY_HEXLEN + CRYPT_SIGN_LEN + (CRYPT_NONCEHALF_LEN)) #define CRYPT_PKEY_HEXLEN ((CRYPT_KX_PKEY_LEN + CRYPT_SIGN_PKEY_LEN) * 2) #define CRYPT_SKEY_HEXLEN ((CRYPT_SIGN_PKEY_LEN + CRYPT_SIGN_SKEY_LEN) * 2) // Stores the public and secret keys used in a key exchange and for signing. typedef struct crypt_key_t { unsigned char kx_pub[crypto_kx_PUBLICKEYBYTES]; unsigned char kx_sec[crypto_kx_SECRETKEYBYTES]; unsigned char sign_pub[crypto_sign_PUBLICKEYBYTES]; unsigned char sign_sec[crypto_sign_SECRETKEYBYTES]; bool hasSecKey; } crypt_key_t; // Generates the new pairs of a key exchange and sign keys. int crypt_key_gen(crypt_key_t *const k); // Initialise a crypt_key_t with a provided hex representaions of public and secret keys. int crypt_key_from_hex(crypt_key_t *const k, const char phex[CRYPT_PKEY_HEXLEN], const char shex[CRYPT_SKEY_HEXLEN]); // Initialise a crypt_key_t with a provided hex representaion of just a public key. Used for remote keys. int crypt_key_from_hex_public(crypt_key_t *const k, const char phex[CRYPT_PKEY_HEXLEN]); // Securely erase the fields of a crypt_key_t struct. void crypt_key_destroy(crypt_key_t *const k); // Export a public sign and key exchange keys as a hex string. int crypt_key_export_public(const crypt_key_t *const k, char hex[CRYPT_PKEY_HEXLEN]); // Export a secret sign and key exchange keys as a hex string. int crypt_key_export_secret(const crypt_key_t *const k, char hex[CRYPT_SKEY_HEXLEN]); // Load the sign and key exchange keys in a hex representaion from files // and initialise a crypt_key_t. int crypt_load_key(crypt_key_t *const k, FILE *const pub, FILE *const sec); // Store a hex representaion of the sign and key exchange keys into files // that are corresponding to a public and a secret parts. int crypt_store_key(const crypt_key_t *const k, FILE *const pub, FILE *const sec); // Returns a hello packet consisting of a public key and its sign. // The packet is of CRYPT_SIGN_LEN long. unsigned char *crypt_hello(const crypt_key_t *const own); // Verify a hello message. It only shows that a remote public key's sign is ok. int crypt_hello_verify(const unsigned char *const hello, crypt_key_t *const remote); // Combines own and remote halves of a nonce depending in a connection direction and returns it. // It will be of CRYPT_NONCE_LEN length. const unsigned char *crypt_hello_get_nonce(const unsigned char *const own_hello, const unsigned char *const remote_hello, bool is_client); // Stores symmetric keys used for a data encryption in both directions // and a remote public key. typedef struct crypt_session_t { unsigned char rx[CRYPT_SESS_KEY_LEN]; unsigned char tx[CRYPT_SESS_KEY_LEN]; unsigned char nonce[CRYPT_NONCE_LEN]; crypt_key_t *remote_key; } crypt_session_t; // Derives the symmetric keys for a data encryption using own public and secret and remote's public keys. // // is_client should be set to true if you are the one establishing the connection. int crypt_session_init(crypt_session_t *const s, const crypt_key_t *const own, crypt_key_t *const remote, const unsigned char *const nonce, bool is_client); unsigned char *crypt_session_encrypt(crypt_session_t *const s, const unsigned char *const m, unsigned long long mlen, unsigned long long *clen); unsigned char *crypt_session_decrypt(crypt_session_t *const s, const unsigned char *const c, unsigned long long clen, unsigned long long *mlen); // Securely erase the fields of a crypt_session_t struct. void crypt_session_destroy(crypt_session_t *const s); #endif /* _CRYPT_H_ */