1 /*
2 crypto.h
3 Copyright (C) 2016  Belledonne Communications SARL
4 
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 */
19 #ifndef BCTBX_CRYPTO_H
20 #define BCTBX_CRYPTO_H
21 
22 #include <bctoolbox/port.h>
23 
24 
25 /* DHM settings defines */
26 #define BCTBX_DHM_UNSET	0
27 #define BCTBX_DHM_2048	1
28 #define BCTBX_DHM_3072	2
29 
30 /* SSL settings defines */
31 #define BCTBX_SSL_UNSET -1
32 
33 #define BCTBX_SSL_IS_CLIENT 0
34 #define BCTBX_SSL_IS_SERVER 1
35 
36 #define BCTBX_SSL_TRANSPORT_STREAM 0
37 #define BCTBX_SSL_TRANSPORT_DATAGRAM 1
38 
39 #define BCTBX_SSL_VERIFY_NONE 0
40 #define BCTBX_SSL_VERIFY_OPTIONAL 1
41 #define BCTBX_SSL_VERIFY_REQUIRED 2
42 
43 /* Encryption/decryption defines */
44 #define BCTBX_GCM_ENCRYPT     1
45 #define BCTBX_GCM_DECRYPT     0
46 
47 /* Error codes : All error codes are negative and defined  on 32 bits on format -0x7XXXXXXX
48  * in order to be sure to not overlap on crypto librairy (polarssl or mbedtls for now) which are defined on 16 bits 0x[7-0]XXX */
49 #define BCTBX_ERROR_UNSPECIFIED_ERROR			-0x70000000
50 #define BCTBX_ERROR_OUTPUT_BUFFER_TOO_SMALL		-0x70001000
51 #define BCTBX_ERROR_INVALID_BASE64_INPUT		-0x70002000
52 #define BCTBX_ERROR_INVALID_INPUT_DATA			-0x70004000
53 #define BCTBX_ERROR_UNAVAILABLE_FUNCTION		-0x70008000
54 
55 /* key related */
56 #define BCTBX_ERROR_UNABLE_TO_PARSE_KEY		-0x70010000
57 
58 /* Certificate related */
59 #define BCTBX_ERROR_INVALID_CERTIFICATE			-0x70020000
60 #define BCTBX_ERROR_CERTIFICATE_GENERATION_FAIL	-0x70020001
61 #define BCTBX_ERROR_CERTIFICATE_WRITE_PEM		-0x70020002
62 #define BCTBX_ERROR_CERTIFICATE_PARSE_PEM		-0x70020004
63 #define BCTBX_ERROR_UNSUPPORTED_HASH_FUNCTION	-0x70020008
64 
65 /* SSL related */
66 #define BCTBX_ERROR_INVALID_SSL_CONFIG		-0x70030001
67 #define BCTBX_ERROR_INVALID_SSL_TRANSPORT	-0x70030002
68 #define BCTBX_ERROR_INVALID_SSL_ENDPOINT	-0x70030004
69 #define BCTBX_ERROR_INVALID_SSL_AUTHMODE	-0x70030008
70 #define BCTBX_ERROR_INVALID_SSL_CONTEXT		-0x70030010
71 
72 #define BCTBX_ERROR_NET_WANT_READ			-0x70032000
73 #define BCTBX_ERROR_NET_WANT_WRITE			-0x70034000
74 #define BCTBX_ERROR_SSL_PEER_CLOSE_NOTIFY	-0x70038000
75 #define BCTBX_ERROR_NET_CONN_RESET			-0x70030000
76 
77 /* Symmetric ciphers related */
78 #define BCTBX_ERROR_AUTHENTICATION_FAILED	-0x70040000
79 
80 /* certificate verification flags codes */
81 #define BCTBX_CERTIFICATE_VERIFY_ALL_FLAGS				0xFFFFFFFF
82 #define BCTBX_CERTIFICATE_VERIFY_BADCERT_EXPIRED		0x01  /**< The certificate validity has expired. */
83 #define BCTBX_CERTIFICATE_VERIFY_BADCERT_REVOKED		0x02  /**< The certificate has been revoked (is on a CRL). */
84 #define BCTBX_CERTIFICATE_VERIFY_BADCERT_CN_MISMATCH	0x04  /**< The certificate Common Name (CN) does not match with the expected CN. */
85 #define BCTBX_CERTIFICATE_VERIFY_BADCERT_NOT_TRUSTED	0x08  /**< The certificate is not correctly signed by the trusted CA. */
86 #define BCTBX_CERTIFICATE_VERIFY_BADCERT_MISSING		0x10  /**< Certificate was missing. */
87 #define BCTBX_CERTIFICATE_VERIFY_BADCERT_SKIP_VERIFY	0x20  /**< Certificate verification was skipped. */
88 #define BCTBX_CERTIFICATE_VERIFY_BADCERT_OTHER			0x0100  /**< Other reason (can be used by verify callback) */
89 #define BCTBX_CERTIFICATE_VERIFY_BADCERT_FUTURE			0x0200  /**< The certificate validity starts in the future. */
90 #define BCTBX_CERTIFICATE_VERIFY_BADCERT_KEY_USAGE      0x0400  /**< Usage does not match the keyUsage extension. */
91 #define BCTBX_CERTIFICATE_VERIFY_BADCERT_EXT_KEY_USAGE  0x0800  /**< Usage does not match the extendedKeyUsage extension. */
92 #define BCTBX_CERTIFICATE_VERIFY_BADCERT_NS_CERT_TYPE   0x1000  /**< Usage does not match the nsCertType extension. */
93 #define BCTBX_CERTIFICATE_VERIFY_BADCERT_BAD_MD         0x2000  /**< The certificate is signed with an unacceptable hash. */
94 #define BCTBX_CERTIFICATE_VERIFY_BADCERT_BAD_PK         0x4000  /**< The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA). */
95 #define BCTBX_CERTIFICATE_VERIFY_BADCERT_BAD_KEY        0x8000  /**< The certificate is signed with an unacceptable key (eg bad curve, RSA too short). */
96 
97 #define BCTBX_CERTIFICATE_VERIFY_BADCRL_FUTURE			0x10000  /**< The CRL is from the future */
98 #define BCTBX_CERTIFICATE_VERIFY_BADCRL_NOT_TRUSTED		0x20000  /**< CRL is not correctly signed by the trusted CA. */
99 #define BCTBX_CERTIFICATE_VERIFY_BADCRL_EXPIRED			0x40000  /**< CRL is expired. */
100 #define BCTBX_CERTIFICATE_VERIFY_BADCRL_BAD_MD          0x80000  /**< The CRL is signed with an unacceptable hash. */
101 #define BCTBX_CERTIFICATE_VERIFY_BADCRL_BAD_PK          0x100000  /**< The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA). */
102 #define BCTBX_CERTIFICATE_VERIFY_BADCRL_BAD_KEY         0x200000  /**< The CRL is signed with an unacceptable key (eg bad curve, RSA too short). */
103 
104 
105 /* Hash functions type */
106 typedef enum bctbx_md_type {
107 	BCTBX_MD_UNDEFINED,
108 	BCTBX_MD_SHA1,
109 	BCTBX_MD_SHA224,
110 	BCTBX_MD_SHA256,
111 	BCTBX_MD_SHA384,
112 	BCTBX_MD_SHA512} bctbx_md_type_t;
113 
114 /* Dtls srtp protection profile */
115 typedef enum bctbx_srtp_profile {
116 	BCTBX_SRTP_UNDEFINED,
117 	BCTBX_SRTP_AES128_CM_HMAC_SHA1_80,
118 	BCTBX_SRTP_AES128_CM_HMAC_SHA1_32,
119 	BCTBX_SRTP_NULL_HMAC_SHA1_80,
120 	BCTBX_SRTP_NULL_HMAC_SHA1_32
121 } bctbx_dtls_srtp_profile_t;
122 
123 
124 #ifdef __cplusplus
125 extern "C"{
126 #endif
127 
128 /*****************************************************************************/
129 /****** Utils                                                           ******/
130 /*****************************************************************************/
131 /**
132  * @brief Return a string translation of an error code
133  * PolarSSL and mbedTLS error codes are on 16 bits always negatives, and these are forwarded to the crypto library error to string translation
134  * Specific bctoolbox error code are on 32 bits, all in the form -0x7XXX XXXX
135  * Output string is truncated if the buffer is too small and always include a null termination char
136  *
137  * @param[in]		error_code		The error code
138  * @param[in/out]	buffer			Buffer to place error string representation
139  * @param[in]		buffer_length	Size of the buffer in bytes.
140  */
141 BCTBX_PUBLIC void bctbx_strerror(int32_t error_code, char *buffer, size_t buffer_length);
142 
143 /**
144  * @brief Encode a buffer into base64 format
145  * @param[out]		output			base64 encoded buffer
146  * @param[in/out]	output_length	output buffer max size and actual size of buffer after encoding
147  * @param[in]		input			source plain buffer
148  * @param[in]		input_length	Length in bytes of plain buffer to be encoded
149  *
150  * @return 0 if success or BCTBX_ERROR_OUTPUT_BUFFER_TOO_SMALL if the output buffer cannot contain the encoded data
151  *
152  * @note If the function is called with *output_length=0, set the requested buffer size in output_length
153  */
154 BCTBX_PUBLIC int32_t bctbx_base64_encode(unsigned char *output, size_t *output_length, const unsigned char *input, size_t input_length);
155 
156 /**
157  * @brief Decode a base64 formatted buffer.
158  * @param[out]		output			plain buffer
159  * @param[in/out]	output_length	output buffer max size and actual size of buffer after decoding
160  * @param[in]		input			source base64 encoded buffer
161  * @param[in]		input_length	Length in bytes of base64 buffer to be decoded
162  *
163  * @return 0 if success, BCTBX_ERROR_OUTPUT_BUFFER_TOO_SMALL if the output buffer cannot contain the decoded data
164  * or BCTBX_ERROR_INVALID_BASE64_INPUT if encoded buffer was incorrect base64 data
165  *
166  * @note If the function is called with *output_length=0, set the requested buffer size in output_length
167  */
168 BCTBX_PUBLIC int32_t bctbx_base64_decode(unsigned char *output, size_t *output_length, const unsigned char *input, size_t input_length);
169 
170 /*****************************************************************************/
171 /****** Random Number Generation                                        ******/
172 /*****************************************************************************/
173 /** @brief An opaque structure used to store RNG context
174  * Instanciate pointers only and allocate them using the bctbx_rng_context_new() function
175  */
176 typedef struct bctbx_rng_context_struct bctbx_rng_context_t;
177 
178 /**
179  * @brief Create and initialise the Random Number Generator context
180  * @return a pointer to the RNG context
181  */
182 BCTBX_PUBLIC bctbx_rng_context_t *bctbx_rng_context_new(void);
183 
184 /**
185  * @brief Get some random material
186  *
187  * @param[in/out]	context			The RNG context to be used
188  * @param[out]		output			A destination buffer for the random material generated
189  * @param[in]		output_length	Size in bytes of the output buffer and requested random material
190  *
191  * @return 0 on success
192  */
193 BCTBX_PUBLIC int32_t bctbx_rng_get(bctbx_rng_context_t *context, unsigned char*output, size_t output_length);
194 
195 /**
196  * @brief Clear the RNG context and free internal buffer
197  *
198  * @param[in]	context		The RNG context to clear
199  */
200 BCTBX_PUBLIC void bctbx_rng_context_free(bctbx_rng_context_t *context);
201 
202 /*****************************************************************************/
203 /***** Signing key                                                       *****/
204 /*****************************************************************************/
205 /** @brief An opaque structure used to store the signing key context
206  * Instanciate pointers only and allocate them using the bctbx_signing_key_new() function
207  */
208 typedef struct bctbx_signing_key_struct bctbx_signing_key_t;
209 
210 /**
211  * @brief Create and initialise a signing key context
212  * @return a pointer to the signing key context
213  */
214 BCTBX_PUBLIC bctbx_signing_key_t *bctbx_signing_key_new(void);
215 
216 /**
217  * @brief Clear the signing key context and free internal buffer
218  *
219  * @param[in]	key		The signing key context to clear
220  */
221 BCTBX_PUBLIC void  bctbx_signing_key_free(bctbx_signing_key_t *key);
222 
223 /**
224  * @brief	Write the key in a buffer as a PEM string
225  *
226  * @param[in]	key		The signing key to be extracted in PEM format
227  *
228  * @return a pointer to a null terminated string containing the key in PEM format. This buffer must then be freed by caller. NULL on failure.
229  */
230 BCTBX_PUBLIC char *bctbx_signing_key_get_pem(bctbx_signing_key_t *key);
231 
232 /**
233  * @brief Parse signing key in PEM format from a null terminated string buffer
234  *
235  * @param[in/out]	key				An already initialised signing key context
236  * @param[in]		buffer			The input buffer containing a PEM format key in a null terminated string
237  * @param[in]		buffer_length	The length of input buffer, including the NULL termination char
238  * @param[in]		password		Password for decryption(may be NULL)
239  * @param[in]		passzord_length	size of password
240  *
241  * @return 0 on success
242  */
243 BCTBX_PUBLIC int32_t bctbx_signing_key_parse(bctbx_signing_key_t *key, const char *buffer, size_t buffer_length, const unsigned char *password, size_t password_length);
244 
245 /**
246  * @brief Parse signing key from a file
247  *
248  * @param[in/out]	key				An already initialised signing key context
249  * @param[in]		path			filename to read the key from
250  * @param[in]		password		Password for decryption(may be NULL)
251  *
252  * @return 0 on success
253  */
254 BCTBX_PUBLIC int32_t bctbx_signing_key_parse_file(bctbx_signing_key_t *key, const char *path, const char *password);
255 
256 /*****************************************************************************/
257 /***** X509 Certificate                                                  *****/
258 /*****************************************************************************/
259 /** @brief An opaque structure used to store the certificate context
260  * Instanciate pointers only and allocate them using the bctbx_x509_certificate_new() function
261  */
262 typedef struct bctbx_x509_certificate_struct bctbx_x509_certificate_t;
263 
264 /**
265  * @brief Create and initialise a x509 certificate context
266  * @return a pointer to the certificate context
267  */
268 BCTBX_PUBLIC bctbx_x509_certificate_t *bctbx_x509_certificate_new(void);
269 
270 /**
271  * @brief Clear the certificate context and free internal buffer
272  *
273  * @param[in]	cert		The x509 certificate context to clear
274  */
275 BCTBX_PUBLIC void  bctbx_x509_certificate_free(bctbx_x509_certificate_t *cert);
276 
277 /**
278  * @brief	Write the certificate in a buffer as a PEM string
279  *
280  * @param[in]	cert	The certificate to be extracted in PEM format
281  *
282  * @return a pointer to a null terminated string containing the certificate in PEM format. This buffer must then be freed by caller. NULL on failure.
283  */
284 BCTBX_PUBLIC char *bctbx_x509_certificates_chain_get_pem(bctbx_x509_certificate_t *cert);
285 
286 /**
287  * @brief	Return an informational string about the certificate
288  *
289  * @param[out]	buf	Buffer to receive the output
290  * @param[in]	size	Maximum output buffer size
291  * @param[in]	prefix	A line prefix
292  * @param[in]	cert	The x509 certificate
293  *
294  * @return	The length of the string written or a negative error code
295  */
296 BCTBX_PUBLIC int32_t bctbx_x509_certificate_get_info_string(char *buf, size_t size, const char *prefix, const bctbx_x509_certificate_t *cert);
297 
298 /**
299  * @brief Parse an x509 certificate in PEM format from a null terminated string buffer
300  *
301  * @param[in/out]	cert		An already initialised x509 certificate context
302  * @param[in]		buffer		The input buffer containing a PEM format certificate in a null terminated string
303  * @param[in]		buffer_length	The length of input buffer, including the NULL termination char
304  *
305  * @return	0 on success, negative error code otherwise
306  */
307 BCTBX_PUBLIC int32_t bctbx_x509_certificate_parse(bctbx_x509_certificate_t *cert, const char *buffer, size_t buffer_length);
308 
309 /**
310  * @brief Load one or more certificates and add them to the chained list
311  *
312  * @param[in/out]	cert	points to the start of the chain, can be an empty initialised certificate context
313  * @param[in]		path	filename to read the certificate from
314  *
315  * @return	0 on success, negative error code otherwise
316  */
317 BCTBX_PUBLIC int32_t bctbx_x509_certificate_parse_file(bctbx_x509_certificate_t *cert, const char *path);
318 
319 /**
320  * @brief Load one or more certificates files from a path and add them to the chained list
321  *
322  * @param[in/out]	cert	points to the start of the chain, can be an empty initialised certificate context
323  * @param[in]		path	directory to read certicates files from
324  *
325  * @return	0 on success, negative error code otherwise
326  */
327 BCTBX_PUBLIC int32_t bctbx_x509_certificate_parse_path(bctbx_x509_certificate_t *cert, const char *path);
328 
329 /**
330  * @brief Get the length in bytes of a certifcate chain in DER format
331  *
332  * @param[in]	cert	The certificate chain
333  *
334  * @return	The length in bytes of the certificate buffer in DER format, 0 if no certificate found
335  */
336 BCTBX_PUBLIC int32_t bctbx_x509_certificate_get_der_length(bctbx_x509_certificate_t *cert);
337 
338 /**
339  * @brief	Get the certificate in DER format in a null terminated string
340  *
341  * @param[in]		cert		The certificate chain
342  * @param[in/out]	buffer		The buffer to hold the certificate
343  * @param[in]		buffer_length	Maximum output buffer size
344  *
345  * @return 0 on success, negative error code otherwise
346  */
347 BCTBX_PUBLIC int32_t bctbx_x509_certificate_get_der(bctbx_x509_certificate_t *cert, unsigned char *buffer, size_t buffer_length);
348 
349 /**
350  * @brief Store the certificate subject DN in printable form into buf
351  *
352  * @param[in]		cert		The x509 certificate
353  * @param[in/out]	dn		A buffer to store the DN string
354  * @param[in]		dn_length	Maximum size to be written in buffer
355  *
356  * @return The length of the string written (not including the terminated nul byte), or a negative error code
357  */
358 BCTBX_PUBLIC int32_t bctbx_x509_certificate_get_subject_dn(bctbx_x509_certificate_t *cert, char *dn, size_t dn_length);
359 
360 /**
361  * @brief Generate certificate fingerprint (hash of the DER format certificate) hexadecimal format in a null terminated string
362  *
363  * @param[in]		cert			The x509 certificate
364  * @param[in/out]	fingerprint		The buffer to hold the fingerprint(null terminated string in hexadecimal)
365  * @param[in]		fingerprint_length	Maximum length of the fingerprint buffer
366  * @param[in]		hash_algorithm		set to BCTBX_MD_UNDEFINED to use the hash used in certificate signature(recommended)
367  *						or specify an other hash algorithm(BCTBX_MD_SHA1, BCTBX_MD_SHA224, BCTBX_MD_SHA256, BCTBX_MD_SHA384, BCTBX_MD_SHA512)
368  * @return length of written on success, negative error code otherwise
369  */
370 BCTBX_PUBLIC int32_t bctbx_x509_certificate_get_fingerprint(const bctbx_x509_certificate_t *cert, char *fingerprint, size_t fingerprint_length, bctbx_md_type_t hash_algorithm);
371 
372 /**
373  * @brief Retrieve the certificate signature hash function
374  *
375  * @param[in]	cert		The x509 certificate
376  * @param[out]	hash_algorithm	The hash algorithm used for the certificate signature or BCTBX_MD_UNDEFINED if unable to retrieve it
377  *
378  * @return 0 on success, negative error code otherwise
379  */
380 BCTBX_PUBLIC int32_t bctbx_x509_certificate_get_signature_hash_function(const bctbx_x509_certificate_t *certificate, bctbx_md_type_t *hash_algorithm);
381 
382 /**
383  * @brief Generate a self-signed certificate using RSA 3072 bits signature algorithm
384  *
385  * @param[in]		subject		The certificate subject
386  * @param[in/out]	certificate	An empty intialised certificate pointer to hold the generated certificate
387  * @param[in/out]	pkey		An empty initialised signing key pointer to hold the key generated and used to sign the certificate (RSA 3072 bits)
388  * @param[out]		pem		If not null, a buffer to hold a PEM string of the certificate and key
389  * @param[in]		pem_length	pem buffer length
390  *
391  * @return 0 on success, negative error code otherwise
392  */
393 BCTBX_PUBLIC int32_t bctbx_x509_certificate_generate_selfsigned(const char *subject, bctbx_x509_certificate_t *certificate, bctbx_signing_key_t *pkey, char *pem, size_t pem_length);
394 
395 /**
396  * @brief Convert underlying crypto library certificate flags into a printable string
397  *
398  * @param[out]	buffer		a buffer to hold the output string
399  * @param[in]	buffer_size	maximum buffer size
400  * @param[in]	flags		The flags from the underlying crypto library, provided in callback functions
401  *
402  * @return 0 on success, negative error code otherwise
403  */
404 BCTBX_PUBLIC int32_t bctbx_x509_certificate_flags_to_string(char *buffer, size_t buffer_size, uint32_t flags);
405 
406 /**
407  * @brief Set a certificate flags (using underlying crypto library defines)
408  *
409  * @param[in/out]	flags		The certificate flags holder directly provided by crypto library in a callback function
410  * @param[in]		flags_to_set	Flags to be set, bctoolbox defines
411  *
412  * @return 0 on success, negative error code otherwise
413  */
414 BCTBX_PUBLIC int32_t bctbx_x509_certificate_set_flag(uint32_t *flags, uint32_t flags_to_set);
415 
416 /**
417  * @brief convert certificate flags from underlying crypto library defines to bctoolbox ones
418  *
419  * @param[in]	flags	certificate flags provided by the crypto library in a callback function
420  *
421  * @return same flag but using the bctoolbox API definitions
422  */
423 BCTBX_PUBLIC uint32_t bctbx_x509_certificate_remap_flag(uint32_t flags);
424 
425 /**
426  * @brief Unset a certificate flags (using underlying crypto library defines)
427  *
428  * @param[in/out]	flags		The certificate flags holder directly provided by crypto library in a callback function
429  * @param[in]		flags_to_set	Flags to be unset, bctoolbox defines
430  *
431  * @return 0 on success, negative error code otherwise
432  */
433 BCTBX_PUBLIC int32_t bctbx_x509_certificate_unset_flag(uint32_t *flags, uint32_t flags_to_unset);
434 
435 
436 /*****************************************************************************/
437 /***** SSL                                                               *****/
438 /*****************************************************************************/
439 typedef struct bctbx_ssl_context_struct bctbx_ssl_context_t;
440 typedef struct bctbx_ssl_config_struct bctbx_ssl_config_t;
441 BCTBX_PUBLIC bctbx_ssl_context_t *bctbx_ssl_context_new(void);
442 BCTBX_PUBLIC void bctbx_ssl_context_free(bctbx_ssl_context_t *ssl_ctx);
443 BCTBX_PUBLIC int32_t bctbx_ssl_context_setup(bctbx_ssl_context_t *ssl_ctx, bctbx_ssl_config_t *ssl_config);
444 
445 BCTBX_PUBLIC int32_t bctbx_ssl_close_notify(bctbx_ssl_context_t *ssl_ctx);
446 BCTBX_PUBLIC int32_t bctbx_ssl_session_reset(bctbx_ssl_context_t *ssl_ctx);
447 BCTBX_PUBLIC int32_t bctbx_ssl_read(bctbx_ssl_context_t *ssl_ctx, unsigned char *buf, size_t buf_length);
448 BCTBX_PUBLIC int32_t bctbx_ssl_write(bctbx_ssl_context_t *ssl_ctx, const unsigned char *buf, size_t buf_length);
449 BCTBX_PUBLIC int32_t bctbx_ssl_set_hostname(bctbx_ssl_context_t *ssl_ctx, const char *hostname);
450 BCTBX_PUBLIC int32_t bctbx_ssl_handshake(bctbx_ssl_context_t *ssl_ctx);
451 BCTBX_PUBLIC int32_t bctbx_ssl_set_hs_own_cert(bctbx_ssl_context_t *ssl_ctx, bctbx_x509_certificate_t *cert, bctbx_signing_key_t *key);
452 BCTBX_PUBLIC void bctbx_ssl_set_io_callbacks(bctbx_ssl_context_t *ssl_ctx, void *callback_data,
453 		int(*callback_send_function)(void *, const unsigned char *, size_t), /* callbacks args are: callback data, data buffer to be send, size of data buffer */
454 		int(*callback_recv_function)(void *, unsigned char *, size_t)); /* args: callback data, data buffer to be read, size of data buffer */
455 BCTBX_PUBLIC const bctbx_x509_certificate_t *bctbx_ssl_get_peer_certificate(bctbx_ssl_context_t *ssl_ctx);
456 BCTBX_PUBLIC const char *bctbx_ssl_get_ciphersuite(bctbx_ssl_context_t *ssl_ctx);
457 BCTBX_PUBLIC const char *bctbx_ssl_get_version(bctbx_ssl_context_t *ssl_ctx);
458 
459 BCTBX_PUBLIC bctbx_ssl_config_t *bctbx_ssl_config_new(void);
460 BCTBX_PUBLIC int32_t bctbx_ssl_config_set_crypto_library_config(bctbx_ssl_config_t *ssl_config, void *internal_config);
461 BCTBX_PUBLIC void bctbx_ssl_config_free(bctbx_ssl_config_t *ssl_config);
462 BCTBX_PUBLIC int32_t bctbx_ssl_config_defaults(bctbx_ssl_config_t *ssl_config, int endpoint, int transport);
463 BCTBX_PUBLIC int32_t bctbx_ssl_config_set_endpoint(bctbx_ssl_config_t *ssl_config, int endpoint);
464 BCTBX_PUBLIC int32_t bctbx_ssl_config_set_transport (bctbx_ssl_config_t *ssl_config, int transport);
465 BCTBX_PUBLIC int32_t bctbx_ssl_config_set_authmode(bctbx_ssl_config_t *ssl_config, int authmode);
466 BCTBX_PUBLIC int32_t bctbx_ssl_config_set_rng(bctbx_ssl_config_t *ssl_config, int(*rng_function)(void *, unsigned char *, size_t), void *rng_context);
467 BCTBX_PUBLIC int32_t bctbx_ssl_config_set_callback_verify(bctbx_ssl_config_t *ssl_config, int(*callback_function)(void *, bctbx_x509_certificate_t *, int, uint32_t *), void *callback_data);
468 BCTBX_PUBLIC int32_t bctbx_ssl_config_set_callback_cli_cert(bctbx_ssl_config_t *ssl_config, int(*callback_function)(void *, bctbx_ssl_context_t *, unsigned char *, size_t), void *callback_data);
469 BCTBX_PUBLIC int32_t bctbx_ssl_config_set_ca_chain(bctbx_ssl_config_t *ssl_config, bctbx_x509_certificate_t *ca_chain);
470 BCTBX_PUBLIC int32_t bctbx_ssl_config_set_own_cert(bctbx_ssl_config_t *ssl_config, bctbx_x509_certificate_t *cert, bctbx_signing_key_t *key);
471 
472 /***** DTLS-SRTP functions *****/
473 BCTBX_PUBLIC bctbx_dtls_srtp_profile_t bctbx_ssl_get_dtls_srtp_protection_profile(bctbx_ssl_context_t *ssl_ctx);
474 BCTBX_PUBLIC int32_t bctbx_ssl_config_set_dtls_srtp_protection_profiles(bctbx_ssl_config_t *ssl_config, const bctbx_dtls_srtp_profile_t *profiles, size_t profiles_number);
475 BCTBX_PUBLIC int32_t bctbx_ssl_get_dtls_srtp_key_material(bctbx_ssl_context_t *ssl_ctx, char *output, size_t *output_length);
476 BCTBX_PUBLIC uint8_t bctbx_dtls_srtp_supported(void);
477 
478 
479 /*****************************************************************************/
480 /***** Diffie-Hellman-Merkle key exchange                                *****/
481 /*****************************************************************************/
482 /**
483  * @brief Context for the Diffie-Hellman-Merkle key exchange
484  *	Use RFC3526 values for G and P
485  */
486 typedef struct bctbx_DHMContext_struct {
487 	uint8_t algo; /**< Algorithm used for the key exchange mapped to an int: BCTBX_DHM_2048, BCTBX_DHM_3072 */
488 	uint16_t primeLength; /**< Prime number length in bytes(256 or 384)*/
489 	uint8_t *secret; /**< the random secret (X), this field may not be used if the crypto module implementation already store this value in his context */
490 	uint8_t secretLength; /**< in bytes */
491 	uint8_t *key; /**< the key exchanged (G^Y)^X mod P */
492 	uint8_t *self; /**< this side of the public exchange G^X mod P */
493 	uint8_t *peer; /**< the other side of the public exchange G^Y mod P */
494 	void *cryptoModuleData; /**< a context needed by the crypto implementation */
495 }bctbx_DHMContext_t;
496 
497 /**
498  *
499  * @brief Create a context for the DHM key exchange
500  * 	This function will also instantiate the context needed by the actual implementation of the crypto module
501  *
502  * @param[in] DHMAlgo		The algorithm type(BCTBX_DHM_2048 or BCTBX_DHM_3072)
503  * @param[in] secretLength	The length in byte of the random secret(X).
504  *
505  * @return The initialised context for the DHM calculation(must then be freed calling the destroyDHMContext function), NULL on error
506  *
507  */
508 BCTBX_PUBLIC bctbx_DHMContext_t *bctbx_CreateDHMContext(uint8_t DHMAlgo, uint8_t secretLength);
509 
510 /**
511  *
512  * @brief Generate the private secret X and compute the public value G^X mod P
513  * G, P and X length have been set by previous call to DHM_CreateDHMContext
514  *
515  * @param[in/out] 	context		DHM context, will store the public value in ->self after this call
516  * @param[in] 		rngFunction	pointer to a random number generator used to create the secret X
517  * @param[in]		rngContext	pointer to the rng context if neeeded
518  *
519  */
520 BCTBX_PUBLIC void bctbx_DHMCreatePublic(bctbx_DHMContext_t *context, int (*rngFunction)(void *, uint8_t *, size_t), void *rngContext);
521 
522 /**
523  *
524  * @brief Compute the secret key G^X^Y mod p
525  * G^X mod P has been computed in previous call to DHMCreatePublic
526  * G^Y mod P must have been set in context->peer
527  *
528  * @param[in/out] 	context		Read the public values from context, export the key to context->key
529  * @param[in]		rngFunction	Pointer to a random number generation function, used for blinding countermeasure, may be NULL
530  * @param[in]		rngContext	Pointer to the RNG function context
531  *
532  */
533 BCTBX_PUBLIC void bctbx_DHMComputeSecret(bctbx_DHMContext_t *context, int (*rngFunction)(void *, uint8_t *, size_t), void *rngContext);
534 
535 /**
536  *
537  * @brief Clean DHM context. Secret and key, if present, are erased from memory(set to 0)
538  *
539  * @param	context	The context to deallocate
540  *
541  */
542 BCTBX_PUBLIC void bctbx_DestroyDHMContext(bctbx_DHMContext_t *context);
543 
544 /*****************************************************************************/
545 /***** Hashing                                                           *****/
546 /*****************************************************************************/
547 /**
548  * @brief HMAC-SHA256 wrapper
549  * @param[in] 	key			HMAC secret key
550  * @param[in] 	keyLength	HMAC key length in bytes
551  * @param[in]	input 		Input data buffer
552  * @param[in]   inputLength	Input data length in bytes
553  * @param[in]	hmacLength	Length of output required in bytes, HMAC output is truncated to the hmacLength left bytes. 32 bytes maximum
554  * @param[out]	output		Output data buffer.
555  *
556  */
557 BCTBX_PUBLIC void bctbx_hmacSha256(const uint8_t *key,
558 		size_t keyLength,
559 		const uint8_t *input,
560 		size_t inputLength,
561 		uint8_t hmacLength,
562 		uint8_t *output);
563 
564 /**
565  * @brief SHA256 wrapper
566  * @param[in]	input 		Input data buffer
567  * @param[in]   inputLength	Input data length in bytes
568  * @param[in]	hmacLength	Length of output required in bytes, SHA256 output is truncated to the hashLength left bytes. 32 bytes maximum
569  * @param[out]	output		Output data buffer.
570  *
571  */
572 BCTBX_PUBLIC void bctbx_sha256(const uint8_t *input,
573 		size_t inputLength,
574 		uint8_t hashLength,
575 		uint8_t *output);
576 
577 /**
578  * @brief HMAC-SHA1 wrapper
579  * @param[in] 	key			HMAC secret key
580  * @param[in] 	keyLength	HMAC key length
581  * @param[in]	input 		Input data buffer
582  * @param[in]   inputLength	Input data length
583  * @param[in]	hmacLength	Length of output required in bytes, HMAC output is truncated to the hmacLength left bytes. 20 bytes maximum
584  * @param[out]	output		Output data buffer
585  *
586  */
587 BCTBX_PUBLIC void bctbx_hmacSha1(const uint8_t *key,
588 		size_t keyLength,
589 		const uint8_t *input,
590 		size_t inputLength,
591 		uint8_t hmacLength,
592 		uint8_t *output);
593 
594 /**
595  * @brief MD5 wrapper
596  * output = md5(input)
597  * @param[in]	input 		Input data buffer
598  * @param[in]   inputLength	Input data length in bytes
599  * @param[out]	output		Output data buffer.
600  *
601  */
602 BCTBX_PUBLIC void bctbx_md5(const uint8_t *input,
603 		size_t inputLength,
604 		uint8_t output[16]);
605 
606 
607 /*****************************************************************************/
608 /***** Encryption/Decryption                                             *****/
609 /*****************************************************************************/
610 typedef struct bctbx_aes_gcm_context_struct bctbx_aes_gcm_context_t;
611 /**
612  * @Brief AES-GCM encrypt and tag buffer
613  *
614  * @param[in]	key							Encryption key
615  * @param[in]	keyLength					Key buffer length, in bytes, must be 16,24 or 32
616  * @param[in]	plainText					buffer to be encrypted
617  * @param[in]	plainTextLength				Length in bytes of buffer to be encrypted
618  * @param[in]	authenticatedData			Buffer holding additional data to be used in tag computation
619  * @param[in]	authenticatedDataLength		Additional data length in bytes
620  * @param[in]	initializationVector		Buffer holding the initialisation vector
621  * @param[in]	initializationVectorLength	Initialisation vector length in bytes
622  * @param[out]	tag							Buffer holding the generated tag
623  * @param[in]	tagLength					Requested length for the generated tag
624  * @param[out]	output						Buffer holding the output, shall be at least the length of plainText buffer
625  *
626  * @return 0 on success, crypto library error code otherwise
627  */
628 BCTBX_PUBLIC int32_t bctbx_aes_gcm_encrypt_and_tag(const uint8_t *key, size_t keyLength,
629 		const uint8_t *plainText, size_t plainTextLength,
630 		const uint8_t *authenticatedData, size_t authenticatedDataLength,
631 		const uint8_t *initializationVector, size_t initializationVectorLength,
632 		uint8_t *tag, size_t tagLength,
633 		uint8_t *output);
634 
635 /**
636  * @Brief AES-GCM decrypt, compute authentication tag and compare it to the one provided
637  *
638  * @param[in]	key							Encryption key
639  * @param[in]	keyLength					Key buffer length, in bytes, must be 16,24 or 32
640  * @param[in]	cipherText					Buffer to be decrypted
641  * @param[in]	cipherTextLength			Length in bytes of buffer to be decrypted
642  * @param[in]	authenticatedData			Buffer holding additional data to be used in auth tag computation
643  * @param[in]	authenticatedDataLength		Additional data length in bytes
644  * @param[in]	initializationVector		Buffer holding the initialisation vector
645  * @param[in]	initializationVectorLength	Initialisation vector length in bytes
646  * @param[in]	tag							Buffer holding the authentication tag
647  * @param[in]	tagLength					Length in bytes for the authentication tag
648  * @param[out]	output						Buffer holding the output, shall be at least the length of cipherText buffer
649  *
650  * @return 0 on succes, BCTBX_ERROR_AUTHENTICATION_FAILED if tag doesn't match or crypto library error code
651  */
652 BCTBX_PUBLIC int32_t bctbx_aes_gcm_decrypt_and_auth(const uint8_t *key, size_t keyLength,
653 		const uint8_t *cipherText, size_t cipherTextLength,
654 		const uint8_t *authenticatedData, size_t authenticatedDataLength,
655 		const uint8_t *initializationVector, size_t initializationVectorLength,
656 		const uint8_t *tag, size_t tagLength,
657 		uint8_t *output);
658 
659 /**
660  * @Brief create and initialise an AES-GCM encryption context
661  *
662  * @param[in]	key							encryption key
663  * @param[in]	keyLength					key buffer length, in bytes, must be 16,24 or 32
664  * @param[in]	authenticatedData			Buffer holding additional data to be used in tag computation
665  * @param[in]	authenticatedDataLength		additional data length in bytes
666  * @param[in]	initializationVector		Buffer holding the initialisation vector
667  * @param[in]	initializationVectorLength	Initialisation vector length in bytes
668  * @param[in]	mode						Operation mode : BCTBX_GCM_ENCRYPT or BCTBX_GCM_DECRYPT
669  *
670  * @return a pointer to the created context, to be freed using bctbx_aes_gcm_finish()
671  */
672 BCTBX_PUBLIC bctbx_aes_gcm_context_t *bctbx_aes_gcm_context_new(const uint8_t *key, size_t keyLength,
673 		const uint8_t *authenticatedData, size_t authenticatedDataLength,
674 		const uint8_t *initializationVector, size_t initializationVectorLength,
675 		uint8_t mode);
676 
677 /**
678  * @Brief AES-GCM encrypt or decrypt a chunk of data
679  *
680  * @param[in/out]	context			a context already initialized using bctbx_aes_gcm_context_new
681  * @param[in]		input			buffer holding the input data
682  * @param[in]		inputLength		lenght of the input data
683  * @param[out]		output			buffer to store the output data (same length as input one)
684  *
685  * @return 0 on success, crypto library error code otherwise
686  */
687 BCTBX_PUBLIC int32_t bctbx_aes_gcm_process_chunk(bctbx_aes_gcm_context_t *context,
688 		const uint8_t *input, size_t inputLength,
689 		uint8_t *output);
690 
691 /**
692  * @Brief Conclude a AES-GCM encryption stream, generate tag if requested, free resources
693  *
694  * @param[in/out]	context			a context already initialized using bctbx_aes_gcm_context_new
695  * @param[out]		tag				a buffer to hold the authentication tag. Can be NULL if tagLength is 0
696  * @param[in]		tagLength		length of reqested authentication tag, max 16
697  *
698  * @return 0 on success, crypto library error code otherwise
699  */
700 BCTBX_PUBLIC int32_t bctbx_aes_gcm_finish(bctbx_aes_gcm_context_t *context,
701 		uint8_t *tag, size_t tagLength);
702 
703 
704 /**
705  * @brief Wrapper for AES-128 in CFB128 mode encryption
706  * Both key and IV must be 16 bytes long
707  *
708  * @param[in]	key			encryption key, 128 bits long
709  * @param[in]	IV			Initialisation vector, 128 bits long, is not modified by this function.
710  * @param[in]	input		Input data buffer
711  * @param[in]	inputLength	Input data length
712  * @param[out]	output		Output data buffer
713  *
714  */
715 BCTBX_PUBLIC void bctbx_aes128CfbEncrypt(const uint8_t *key,
716 		const uint8_t *IV,
717 		const uint8_t *input,
718 		size_t inputLength,
719 		uint8_t *output);
720 
721 /**
722  * @brief Wrapper for AES-128 in CFB128 mode decryption
723  * Both key and IV must be 16 bytes long
724  *
725  * @param[in]	key			decryption key, 128 bits long
726  * @param[in]	IV			Initialisation vector, 128 bits long, is not modified by this function.
727  * @param[in]	input		Input data buffer
728  * @param[in]	inputLength	Input data length
729  * @param[out]	output		Output data buffer
730  *
731  */
732 BCTBX_PUBLIC void bctbx_aes128CfbDecrypt(const uint8_t *key,
733 		const uint8_t *IV,
734 		const uint8_t *input,
735 		size_t inputLength,
736 		uint8_t *output);
737 
738 /**
739  * @brief Wrapper for AES-256 in CFB128 mode encryption
740  * The key must be 32 bytes long and the IV must be 16 bytes long
741  *
742  * @param[in]	key			encryption key, 256 bits long
743  * @param[in]	IV			Initialisation vector, 128 bits long, is not modified by this function.
744  * @param[in]	input		Input data buffer
745  * @param[in]	inputLength	Input data length
746  * @param[out]	output		Output data buffer
747  *
748  */
749 BCTBX_PUBLIC void bctbx_aes256CfbEncrypt(const uint8_t *key,
750 		const uint8_t *IV,
751 		const uint8_t *input,
752 		size_t inputLength,
753 		uint8_t *output);
754 
755 /**
756  * @brief Wrapper for AES-256 in CFB128 mode decryption
757  * The key must be 32 bytes long and the IV must be 16 bytes long
758  *
759  * @param[in]	key			decryption key, 256 bits long
760  * @param[in]	IV			Initialisation vector, 128 bits long, is not modified by this function.
761  * @param[in]	input		Input data buffer
762  * @param[in]	inputLength	Input data length
763  * @param[out]	output		Output data buffer
764  *
765  */
766 BCTBX_PUBLIC void bctbx_aes256CfbDecrypt(const uint8_t *key,
767 		const uint8_t *IV,
768 		const uint8_t *input,
769 		size_t inputLength,
770 		uint8_t *output);
771 
772 #ifdef __cplusplus
773 }
774 #endif
775 
776 #endif /* BCTBX_CRYPTO_H */
777