aboutsummaryrefslogtreecommitdiffstats
path: root/ssl/ssl_ciph.c
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2016-10-06 00:44:59 +0100
committerMatt Caswell <matt@openssl.org>2016-11-02 14:00:10 +0000
commit045bd04706d2a798d5fb4b3ccf7fd56e6e09b082 (patch)
treef9ada1f08e5d69c3d760f96d945dcddc1ca28b6a /ssl/ssl_ciph.c
parentca0b75ade0e89d1d3782ed6b1a4ae0fab72251ec (diff)
downloadopenssl-045bd04706d2a798d5fb4b3ccf7fd56e6e09b082.tar.gz
Add DTLS_get_data_mtu() function
We add ssl_cipher_get_overhead() as an internal function, to avoid having too much ciphersuite-specific knowledge in DTLS_get_data_mtu() itself. It's going to need adjustment for TLSv1.3... but then again, so is fairly much *all* of the SSL_CIPHER handling. This bit is in the noise. Reviewed-by: Rich Salz <rsalz@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org>
Diffstat (limited to 'ssl/ssl_ciph.c')
-rw-r--r--ssl/ssl_ciph.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index adccbfc4d8..acc1840ee1 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -1947,3 +1947,55 @@ int SSL_CIPHER_is_aead(const SSL_CIPHER *c)
{
return (c->algorithm_mac & SSL_AEAD) ? 1 : 0;
}
+
+int ssl_cipher_get_overhead(const SSL_CIPHER *c, size_t *mac_overhead,
+ size_t *int_overhead, size_t *blocksize,
+ size_t *ext_overhead)
+{
+ size_t mac = 0, in = 0, blk = 0, out = 0;
+
+ /* Some hard-coded numbers for the CCM/Poly1305 MAC overhead
+ * because there are no handy #defines for those. */
+ if (c->algorithm_enc & SSL_AESGCM) {
+ out = EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
+ } else if (c->algorithm_enc & (SSL_AES128CCM | SSL_AES256CCM)) {
+ out = EVP_CCM_TLS_EXPLICIT_IV_LEN + 16;
+ } else if (c->algorithm_enc & (SSL_AES128CCM8 | SSL_AES256CCM8)) {
+ out = EVP_CCM_TLS_EXPLICIT_IV_LEN + 8;
+ } else if (c->algorithm_enc & SSL_CHACHA20POLY1305) {
+ out = 16;
+ } else if (c->algorithm_mac & SSL_AEAD) {
+ /* We're supposed to have handled all the AEAD modes above */
+ return 0;
+ } else {
+ /* Non-AEAD modes. Calculate MAC/cipher overhead separately */
+ int digest_nid = SSL_CIPHER_get_digest_nid(c);
+ const EVP_MD *e_md = EVP_get_digestbynid(digest_nid);
+
+ if (e_md == NULL)
+ return 0;
+
+ mac = EVP_MD_size(e_md);
+ if (c->algorithm_enc != SSL_eNULL) {
+ int cipher_nid = SSL_CIPHER_get_cipher_nid(c);
+ const EVP_CIPHER *e_ciph = EVP_get_cipherbynid(cipher_nid);
+
+ /* If it wasn't AEAD or SSL_eNULL, we expect it to be a
+ known CBC cipher. */
+ if (e_ciph == NULL ||
+ EVP_CIPHER_mode(e_ciph) != EVP_CIPH_CBC_MODE)
+ return 0;
+
+ in = 1; /* padding length byte */
+ out = EVP_CIPHER_iv_length(e_ciph);
+ blk = EVP_CIPHER_block_size(e_ciph);
+ }
+ }
+
+ *mac_overhead = mac;
+ *int_overhead = in;
+ *blocksize = blk;
+ *ext_overhead = out;
+
+ return 1;
+}