1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
|
/* 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);
|