On 05/10/16 15:37, David Woodhouse wrote:
> On Wed, 2016-10-05 at 14:40 +0100, David Woodhouse wrote:
>> How's this for a start...
> 
> Now I think I have it right for CCM too, although having to use
> strstr() for that makes me *very* sad. Next up, Chacha20-Poly1305...
> and then maybe I can stop worrying about new modes and ciphersuites
> because those won't be added in OpenSSL 1.1 and we can get OpenSSL do
> to this for itself before 1.2? :)

Or even 1.1.1! Why don't you pull this together into a github PR?

Matt


> 
> /* sets the DTLS MTU and returns the actual tunnel MTU */
> unsigned dtls_set_mtu(struct openconnect_info *vpninfo, unsigned mtu)
> {
>       int tun_mtu;
>       int ivlen, maclen, blocksize = 1, pad = 0;
> 
> #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
>       /* OpenSSL <= 1.0.2 only supports CBC ciphers with PSK */
>       ivlen = 
> EVP_CIPHER_iv_length(EVP_CIPHER_CTX_cipher(vpninfo->dtls_ssl->enc_write_ctx));
>       maclen = EVP_MD_CTX_size(vpninfo->dtls_ssl->write_hash);
>       blocksize = ivlen;
>       pad = 1;
> #else
>       /* Now it gets more fun... */
>       const SSL_CIPHER *s_ciph = SSL_get_current_cipher(vpninfo->dtls_ssl);
>       const EVP_CIPHER *e_ciph;
>       const EVP_MD *e_md;
>       char wtf[128];
> 
>       e_ciph = EVP_get_cipherbynid(SSL_CIPHER_get_cipher_nid(s_ciph));
> 
>       switch (EVP_CIPHER_mode(e_ciph)) {
>       case EVP_CIPH_GCM_MODE:
>               ivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
>               maclen = EVP_GCM_TLS_TAG_LEN;
>               blocksize = 1;
>               pad = 0;
>               break;
> 
>       case EVP_CIPH_CCM_MODE:
>               ivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN;
>               SSL_CIPHER_description(s_ciph, wtf, sizeof(wtf));
>               if (strstr(wtf, "CCM8"))
>                       maclen = 8;
>               else
>                       maclen = 16;
>               blocksize = 1;
>               pad = 0;
>               break;
> 
>       case EVP_CIPH_CBC_MODE:
>               e_md = EVP_get_digestbynid(SSL_CIPHER_get_digest_nid(s_ciph));
>               blocksize = EVP_CIPHER_block_size(e_ciph);
>               ivlen = EVP_CIPHER_iv_length(e_ciph);
>               pad = 1;
>               maclen = EVP_MD_size(e_md);
>               break;
> 
>       case EVP_CIPH_STREAM_CIPHER:
>               /* Seen with PSK-CHACHA20-POLY1305 */
>       default:
>               printf("wtf mode %d\n", EVP_CIPHER_mode(e_ciph));
>               // XXX
>               ;
>       }
> #endif
> 
> 
>       /* Take off the explicit IV and the MAC (XXX: overflow!) */
>       printf("iv %d mac %d blk %d\n", ivlen, maclen, blocksize);
>       tun_mtu = mtu - DTLS1_RT_HEADER_LENGTH - ivlen - maclen;
>       /* For block cipher modes round down to blocksize */
>       printf("tun %d & 0x%x == %d\n", tun_mtu, ~(blocksize-1), tun_mtu & 
> (~(blocksize-1)));
>       tun_mtu -= tun_mtu % blocksize;
>       /* ... and CBC modes require at least one byte to indicate padding 
> length */
>       tun_mtu -= pad;
> 
>       DTLS_set_link_mtu(vpninfo->dtls_ssl, mtu);
> 
>       /* We already set the link MTU, but hopefully by the time we
>        * finish it, this function will be better at working out the
>        * actual tunnel MTU than OpenSSL is. So do that too... */
>       SSL_set_mtu(vpninfo->dtls_ssl, tun_mtu);
> 
>       return tun_mtu;
> }
> 
-- 
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev

Reply via email to