]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added gnutls_record_overhead_size() and Added gnutls_record_overhead_size2().
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Mon, 10 Jun 2013 17:22:32 +0000 (19:22 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Mon, 10 Jun 2013 17:22:32 +0000 (19:22 +0200)
NEWS
lib/gnutls_dtls.c
lib/includes/gnutls/gnutls.h.in
lib/libgnutls.map

diff --git a/NEWS b/NEWS
index c08b6bba075d82202340166138ea22c57e4b076f..1c1c760fa7aa7fd90e08302ec800ee60908ed944 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,8 @@ subsystems.
 gnutls_certificate_set_trust_list: Added
 gnutls_cipher_get_tag_size: Added
 gnutls_record_disable_replay_protection: Added
+gnutls_record_overhead_size: Added
+gnutls_record_overhead_size2: Added
 
 
 * Version 3.2.1 (released 2013-06-01)
index bf76521a6980f0729d4dc8337109b945adaf1461..9455ee7189060f6b1b19829042ce919b2db32945 100644 (file)
@@ -581,6 +581,98 @@ void gnutls_dtls_set_mtu (gnutls_session_t session, unsigned int mtu)
   session->internals.dtls.mtu  = mtu;
 }
 
+static int record_overhead(const cipher_entry_st* cipher, const mac_entry_st* mac, 
+        gnutls_compression_method_t comp,
+       unsigned new_padding)
+{
+int total = 0;
+int t, ret;
+
+  if (_gnutls_cipher_is_block (cipher) == CIPHER_BLOCK)
+    {
+      t = _gnutls_cipher_get_iv_size(cipher);
+      total += t;
+
+      /* padding */
+      t = _gnutls_cipher_get_block_size(cipher);
+      if (new_padding == 0)
+        total += t;
+    }
+
+  if (mac->id == GNUTLS_MAC_AEAD)
+    {
+      t = _gnutls_cipher_get_iv_size(cipher);
+      total += t;
+
+      total += _gnutls_cipher_get_tag_size(cipher);
+    }
+  else
+    {
+      ret = _gnutls_mac_get_algo_len(mac);
+      if (unlikely(ret < 0))
+        return 0;
+
+      total+=ret;
+    }
+
+  if (new_padding != 0)
+    total += 2;
+
+  if (comp != GNUTLS_COMP_NULL)
+    total += EXTRA_COMP_SIZE;
+
+  return total;
+}  
+
+/**
+ * gnutls_record_overhead_size2:
+ * @version: is a #gnutls_protocol_t value
+ * @cipher: is a #gnutls_cipher_algorithm_t value
+ * @mac: is a #gnutls_mac_algorithm_t value
+ * @comp: is a #gnutls_compression_method_t value
+ * @flags: must be zero
+ *
+ * This function will return the set size in bytes of the overhead
+ * due to TLS (or DTLS) per record.
+ *
+ * Note that this function may not provide inacurate values because
+ * of the many options that may be negotiated in TLS/DTLS. An more accurate
+ * value can be obtained using gnutls_record_overhead_size() after
+ * a completed handshake.
+ *
+ * Since: 3.2.2
+ **/
+size_t gnutls_record_overhead_size2 (gnutls_protocol_t version, gnutls_cipher_algorithm_t cipher,
+                                    gnutls_mac_algorithm_t mac, gnutls_compression_method_t comp, 
+                                    unsigned int flags)
+{
+const cipher_entry_st *c;
+const mac_entry_st *m;
+const version_entry_st* v;
+size_t total = 0;
+
+       c = cipher_to_entry(cipher);
+       if (c == NULL)
+               return 0;
+
+       m = mac_to_entry(mac);
+       if (m == NULL)
+               return 0;
+       
+       v = version_to_entry(version);
+       if (v == NULL)
+               return 0;
+       
+       if (v->transport == GNUTLS_STREAM)
+               total = TLS_RECORD_HEADER_SIZE;
+       else
+               total = DTLS_RECORD_HEADER_SIZE;
+       
+       total += record_overhead(c, m, comp, 0);
+       
+       return total;
+}
+
 /* returns overhead imposed by the record layer (encryption/compression)
  * etc. It does not include the record layer headers, since the caller
  * needs to cope with rounding to multiples of blocksize, and the header
@@ -590,10 +682,10 @@ void gnutls_dtls_set_mtu (gnutls_session_t session, unsigned int mtu)
  *
  * It may return a negative error code on error.
  */
-static int record_overhead_rt(gnutls_session_t session, unsigned int *blocksize)
+static int record_overhead_rt(gnutls_session_t session)
 {
 record_parameters_st *params;
-int total = 0, ret, iv_size;
+int ret;
 
   if (session->internals.initial_negotiation_completed == 0)
     return GNUTLS_E_INVALID_REQUEST;
@@ -603,46 +695,35 @@ int total = 0, ret, iv_size;
     return gnutls_assert_val(ret);
 
   /* requires padding */
+  return record_overhead(params->cipher, params->mac, params->compression_algorithm, 
+       session->security_parameters.new_record_padding);
+}
 
-  if (_gnutls_cipher_is_block (params->cipher) == CIPHER_BLOCK)
-    {
-      iv_size = _gnutls_cipher_get_iv_size(params->cipher);
-      total += iv_size;
-      *blocksize = iv_size; /* in block ciphers */
-
-      /* We always pad with at least one byte; never 0. */
-      if (session->security_parameters.new_record_padding == 0)
-        total++;
-    }
-  else
-    {
-      *blocksize = 1;
-    }
-
-  if (session->security_parameters.new_record_padding != 0)
-    total += 2;
-  
-  if (params->mac->id == GNUTLS_MAC_AEAD)
-    {
-      iv_size = _gnutls_cipher_get_iv_size(params->cipher);
-      total += iv_size;
+/**
+ * gnutls_record_overhead_size:
+ * @session: is #gnutls_session_t
+ *
+ * This function will return the set size in bytes of the overhead
+ * due to TLS (or DTLS) per record.
+ *
+ * Since: 3.2.2
+ **/
+size_t gnutls_record_overhead_size (gnutls_session_t session)
+{
+const version_entry_st* v = get_version(session);
+size_t total;
 
-      total += _gnutls_cipher_get_tag_size(params->cipher);
-    }
-  else
-    {
-      ret = _gnutls_mac_get_algo_len(params->mac);
-      if (ret < 0)
-        return gnutls_assert_val(ret);
+       if (v->transport == GNUTLS_STREAM)
+               total = TLS_RECORD_HEADER_SIZE;
+       else
+               total = DTLS_RECORD_HEADER_SIZE;
+       
+       total += record_overhead_rt(session);
 
-      total+=ret;
-    }
+       return total;
+}
 
-  if (params->compression_algorithm != GNUTLS_COMP_NULL)
-    total += EXTRA_COMP_SIZE;
 
-  return total;
-}
 
 /**
  * gnutls_dtls_get_data_mtu:
@@ -659,18 +740,14 @@ int total = 0, ret, iv_size;
 unsigned int gnutls_dtls_get_data_mtu (gnutls_session_t session)
 {
 int mtu = session->internals.dtls.mtu;
-unsigned int blocksize = 1;
 int overhead;
  
   mtu -= RECORD_HEADER_SIZE(session);
 
-  overhead = record_overhead_rt(session, &blocksize);
+  overhead = record_overhead_rt(session);
   if (overhead < 0)
     return mtu;
 
-  if (blocksize)
-    mtu -= mtu % blocksize;
-
   return mtu - overhead;
 }
 
@@ -696,8 +773,7 @@ int overhead;
  **/
 int gnutls_dtls_set_data_mtu (gnutls_session_t session, unsigned int mtu)
 {
-  unsigned int blocksize;
-  int overhead = record_overhead_rt(session, &blocksize);
+  int overhead = record_overhead_rt(session);
 
   /* You can't call this until the session is actually running */
   if (overhead < 0)
@@ -706,13 +782,6 @@ int gnutls_dtls_set_data_mtu (gnutls_session_t session, unsigned int mtu)
   /* Add the overhead inside the encrypted part */
   mtu += overhead;
 
-  /* Round it up to the next multiple of blocksize */
-  if (blocksize > 1) 
-    {
-      mtu += blocksize - 1;
-      mtu -= mtu % blocksize;
-    }
-
   /* Add the *unencrypted header size */
   mtu += RECORD_HEADER_SIZE(session);
 
index ba4497bd0edda8b1318b3a3a222e5eed2b76ce6f..7010cf01b62df0ab9808c6ddff66487932ecca11 100644 (file)
@@ -929,6 +929,14 @@ gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t session);
   ssize_t gnutls_record_recv_seq (gnutls_session_t session, void *data, size_t data_size,
     unsigned char *seq);
 
+  size_t gnutls_record_overhead_size (gnutls_session_t session);
+
+  size_t gnutls_record_overhead_size2 (gnutls_protocol_t version, 
+                                      gnutls_cipher_algorithm_t cipher,
+                                      gnutls_mac_algorithm_t mac, 
+                                      gnutls_compression_method_t comp, 
+                                      unsigned int flags);
+
   void gnutls_session_enable_compatibility_mode (gnutls_session_t session);
   void gnutls_record_set_max_empty_records (gnutls_session_t session, const unsigned int i);
 
index 4a385674f4f2f4049e177e141f45104544f65cc5..bcee7d447c28b2b138613d94c924727d8ff40256 100644 (file)
@@ -914,6 +914,8 @@ GNUTLS_3_1_0 {
        gnutls_certificate_set_trust_list;
        gnutls_cipher_get_tag_size;
        gnutls_record_disable_replay_protection;
+       gnutls_record_overhead_size;
+       gnutls_record_overhead_size2;
 } GNUTLS_3_0_0;
 
 GNUTLS_PRIVATE {