int _gnutls_cipher_is_ok (gnutls_cipher_algorithm_t algorithm);
int _gnutls_cipher_get_iv_size (gnutls_cipher_algorithm_t algorithm);
int _gnutls_cipher_get_export_flag (gnutls_cipher_algorithm_t algorithm);
+/* at least for now iv_size == tag_size */
+#define _gnutls_cipher_get_tag_size _gnutls_cipher_get_iv_size
/* Functions for key exchange. */
int _gnutls_kx_needs_dh_params (gnutls_kx_algorithm_t algorithm);
int ver = gnutls_protocol_get_version (session);
int explicit_iv = _gnutls_version_has_explicit_iv (session->security_parameters.version);
int auth_cipher = _gnutls_auth_cipher_is_aead(¶ms->write.cipher_state);
- int random_pad = (session->internals.priorities.no_padding == 0) ? 1 : 0;
+ int random_pad;
+
+ /* We don't use long padding if requested or if we are in DTLS.
+ */
+ if (session->internals.priorities.no_padding == 0 && (!IS_DTLS(session)))
+ random_pad = 1;
+ else
+ random_pad = 0;
_gnutls_hard_log("ENC[%p]: cipher: %s, MAC: %s, Epoch: %u\n",
session, gnutls_cipher_get_name(params->cipher_algorithm), gnutls_mac_get_name(params->mac_algorithm),
#include <gnutls_mbuffers.h>
#include <gnutls_buffers.h>
#include <gnutls_constate.h>
+#include <gnutls_state.h>
#include <gnutls/dtls.h>
**/
unsigned int gnutls_dtls_get_mtu (gnutls_session_t session)
{
- return session->internals.dtls.mtu - RECORD_HEADER_SIZE(session);
+int ret;
+
+ ret = _gnutls_record_overhead_rt(session);
+ if (ret >= 0)
+ return session->internals.dtls.mtu - ret;
+ else
+ return session->internals.dtls.mtu - RECORD_HEADER_SIZE(session);
}
#define MAX_RECORD_HEADER_SIZE DTLS_RECORD_HEADER_SIZE
#define MAX_RECORD_SEND_SIZE(session) (IS_DTLS(session)?((size_t)session->internals.dtls.mtu-DTLS_RECORD_HEADER_SIZE):(size_t)session->security_parameters.max_record_send_size)
-#define MAX_RECORD_RECV_SIZE(session) (size_t)session->security_parameters.max_record_recv_size
+#define MAX_RECORD_RECV_SIZE(session) ((size_t)session->security_parameters.max_record_recv_size)
#define MAX_PAD_SIZE 255
#define EXTRA_COMP_SIZE 2048
-#define MAX_RECORD_OVERHEAD (MAX_CIPHER_BLOCK_SIZE/*iv*/+MAX_PAD_SIZE+EXTRA_COMP_SIZE)
+#define MAX_RECORD_OVERHEAD (MAX_CIPHER_BLOCK_SIZE/*iv*/+MAX_PAD_SIZE+EXTRA_COMP_SIZE+MAX_HASH_SIZE/*MAC*/)
+#define MAX_RECORD_OVERHEAD_RT(session) (2*MAX_CIPHER_BLOCK_SIZE/*iv+pad*/+MAX_HASH_SIZE)
#define MAX_RECV_SIZE(session) (MAX_RECORD_OVERHEAD+MAX_RECORD_RECV_SIZE(session)+RECORD_HEADER_SIZE(session))
#define TLS_HANDSHAKE_HEADER_SIZE 4
*/
uint16_t srp_prime_bits;
+ /* A handshake process has been completed */
int initial_negotiation_completed:1;
struct
return 0;
}
+
+/* returns overhead imposed by the record layer (encryption/compression)
+ * etc. It does include the record layer headers.
+ *
+ * It may return a negative value on error.
+ */
+int _gnutls_record_overhead_rt(gnutls_session_t session)
+{
+record_parameters_st *params;
+int total = 0, ret, iv_size;
+
+ if (session->internals.initial_negotiation_completed == 0)
+ return 0;
+
+ ret = _gnutls_epoch_get (session, EPOCH_WRITE_CURRENT, ¶ms);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ /* requires padding */
+ iv_size = _gnutls_cipher_get_iv_size(params->cipher_algorithm);
+ total += iv_size;
+
+ if (_gnutls_cipher_is_block (params->cipher_algorithm) == CIPHER_BLOCK)
+ {
+ if (!IS_DTLS(session))
+ total += MAX_PAD_SIZE;
+ else
+ total += iv_size; /* iv_size == block_size */
+ }
+
+ if (params->mac_algorithm == GNUTLS_MAC_AEAD)
+ total += _gnutls_cipher_get_tag_size(params->cipher_algorithm);
+ else
+ {
+ ret = _gnutls_hmac_get_algo_len(params->mac_algorithm);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+ total+=ret;
+ }
+
+ if (params->compression_algorithm != GNUTLS_COMP_NULL)
+ total += EXTRA_COMP_SIZE;
+
+ total += RECORD_HEADER_SIZE(session);
+
+ return total;
+}
_gnutls_record_set_default_version (gnutls_session_t session,
unsigned char major, unsigned char minor);
+int _gnutls_record_overhead_rt(gnutls_session_t session);
+
#include <gnutls_auth.h>
#define CHECK_AUTH(auth, ret) if (gnutls_auth_get_type(session) != auth) { \