diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2016-10-06 00:44:59 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2016-11-02 14:00:10 +0000 |
commit | 045bd04706d2a798d5fb4b3ccf7fd56e6e09b082 (patch) | |
tree | f9ada1f08e5d69c3d760f96d945dcddc1ca28b6a /ssl/ssl_ciph.c | |
parent | ca0b75ade0e89d1d3782ed6b1a4ae0fab72251ec (diff) |
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.c | 52 |
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; +} |