/* SPDX-License-Identifier: GPL-2.0 */ /** \file crypt.h Crypto API. * * The API consists of the following independent parts: the asymmetric public * key cryptosystem (functions whose name starts with apc_), the stream * cipher API (prefix sc_), the hash function API, and a function to fill a * buffer with random data (\ref get_random_bytes_or_die()). APC is just RSA, * but this is a hidden implementation detail. * * The source tree contains two interchangeable implementations, \ref openssl.c * and \ref gcrypt.c, which are based on the corresponding crypto libraries. At * most one of these two source files is compiled in. The configure script * picks one or the other, depending on the outcome of the header and library * checks which are performed when the package is configured. Some related * helper functions which are independent of the crypto library are defined * in \ref crypt_common.c. The file \ref crypt_backend.h declares additional * helpers which are not supposed to be called by users of the crypto API * but only by the two implementations. * * The users of the crypto API are para_server(1), para_audiod(1) and * para_client(1), which employ the API to authenticate connections and * to encrypt the network traffic. Additionally, the audio file selector * of para_server(1) uses hashing to identify audio files and to detect * content changes. */ /** The size of the challenge sent to the client. */ #define APC_CHALLENGE_SIZE 64 /** Opaque structure for public and private keys. */ struct asymmetric_key; /** * Encrypt a buffer using asymmetric keys. * * \param pub: The public key. * \param inbuf The input buffer. * \param len The length of the input buffer. * \param outbuf The output buffer will be allocated by the callee. * * \return The size of the encrypted data on success, negative on errors. */ int apc_pub_encrypt(struct asymmetric_key *pub, unsigned char *inbuf, unsigned len, unsigned char **outbuf); /** * Decrypt a buffer using a private key. * * \param key_file Full path of the key. * \param outbuf The output buffer is allocated by the callee. * \param inbuf The encrypted input buffer. * \param inlen The length of inbuf. * * The output buffer must be large enough to hold at least 512 bytes. * * \return The size of the recovered plaintext on success, negative on errors. */ int apc_priv_decrypt(const char *key_file, unsigned char **outbuf, unsigned char *inbuf, int inlen); /** * Read an asymmetric key from a file. * * \param key_file The file containing the key. * \param result The key structure is returned here. * * \return The size of the key in bytes on success, negative on errors. */ int apc_get_pubkey(const char *key_file, struct asymmetric_key **result); /** * Deallocate a public key. * * \param key Pointer to the key structure to free. * * This should be called for keys obtained by \ref apc_get_pubkey() if the key is no * longer needed. */ void apc_free_pubkey(struct asymmetric_key *key); /** * Fill a buffer with random content. * * \param buf The buffer to fill. * \param num The buffer size in bytes. * * This function puts num cryptographically strong pseudo-random bytes into * buf. If it can not guarantee an unpredictable byte sequence (for example * because the PRNG has not been seeded with enough randomness) the function * logs an error message and calls exit(). */ void get_random_bytes_or_die(unsigned char *buf, int num); /** * Initialize the crypto backend. * * This function initializes the crypto library and seeds the pseudo random * number generator used by random() with a random seed obtained from the * crypto implementation. On errors, an error message is logged and the * function calls exit(). * * \sa \ref get_random_bytes_or_die(), srandom(3), random(3), \ref * para_random(). */ void crypt_init(void); /** Allocate all resources of the crypto backend. */ void crypt_shutdown(void); /** Opaque structure for stream ciphers. */ struct stream_cipher; /** Number of bytes of the session key for stream ciphers. */ #define SESSION_KEY_LEN 32 /** * Used for client-server communication encryption. * * The traffic between (the forked child of) para_server and the remote * client process is encrypted by a symmetric session key. This structure * contains the keys for the stream cipher and the file descriptor for which * these keys should be used. */ struct stream_cipher_context { /** The socket file descriptor. */ int fd; /** Key used for receiving data. */ struct stream_cipher *recv; /** Key used for sending data. */ struct stream_cipher *send; }; /** * Allocate and initialize an aes_ctr128 stream cipher structure. * * \param data The key. * \param len The size of the key. * * \return A new stream cipher structure. */ struct stream_cipher *sc_new(const unsigned char *data, int len); /** * Encrypt or decrypt a buffer using a stream cipher. * * \param sc Crypto key. * \param src The source buffer and length. * \param dst The destination buffer and length, filled out by the function. * * It is up to the implementation to decide whether the crypt operation is * performed in place. The caller can tell by looking if the buffers given by * src and dst coincide after the call. If (and only if) the crypt * operation was not performed in place, the function allocated a new buffer * for the result, so dst->iov_base is different from src->iov_base. In this * case, the destination buffer must be freed by the caller when it is no * longer needed. */ void sc_crypt(struct stream_cipher *sc, struct iovec *src, struct iovec *dst); /** * Wrapper for \ref sc_crypt() that can be used as a sideband transformation. * * \param src Passed verbatim to \ref sc_crypt(). * \param dst Passed verbatim to \ref sc_crypt(). * \param trafo_context Must point to an initialized stream cipher. */ _static_inline_ void sc_trafo(struct iovec *src, struct iovec *dst, void *trafo_context) { sc_crypt(trafo_context, src, dst); } /** * Deallocate a stream cipher structure. * * \param sc A stream cipher previously obtained by \ref sc_new(). */ void sc_free(struct stream_cipher *sc); /** Size of the hash value in bytes. */ #define HASH_SIZE 32 /** * Compute the hash of the given input data. * * \param data Pointer to the data to compute the hash value from. * \param len The length of data in bytes. * \param hash Result pointer. * * The function writes exactly HASH_SIZE bytes, hence the memory area for * the result must be at least this large. * * \sa sha(3), openssl(1). * */ void hash_function(const char *data, unsigned long len, unsigned char *hash); /** * Convert a hash value to ascii format. * * \param hash the hash value. * \param asc Result pointer. * * The function writes exactly 2 * HASH_SIZE + 1 bytes to fill the result * buffer with the ascii representation of the hash value and a terminating * NUL byte. */ void hash_to_asc(const unsigned char *hash, char *asc); /** * Compare two hashes. * * \param h1 Pointer to the first hash value. * \param h2 Pointer to the second hash value. * * \return 1, -1, or zero, depending on whether h1 is greater than, less * than or equal to h2, respectively. */ int hash_compare(const unsigned char *h1, const unsigned char *h2);