From 4380f347b2fff4af10537930400b68df61bee442 Mon Sep 17 00:00:00 2001 From: Frantisek Krenzelok Date: Thu, 1 Dec 2022 15:37:33 +0100 Subject: [PATCH 1/2] KTLS: add ciphersuites * TLS_AES_128_CCM_SHA256 * TLS_CHACHA20_POLY1305_SHA256 Signed-off-by: Frantisek Krenzelok --- lib/system/ktls.c | 159 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 153 insertions(+), 6 deletions(-) diff --git a/lib/system/ktls.c b/lib/system/ktls.c index 703775960..792d09ccf 100644 --- a/lib/system/ktls.c +++ b/lib/system/ktls.c @@ -86,7 +86,7 @@ int _gnutls_ktls_set_keys(gnutls_session_t session, gnutls_transport_ktls_enable gnutls_datum_t mac_key; gnutls_datum_t iv; gnutls_datum_t cipher_key; - unsigned char seq_number[8]; + unsigned char seq_number[12]; int sockin, sockout; int ret; @@ -97,7 +97,9 @@ int _gnutls_ktls_set_keys(gnutls_session_t session, gnutls_transport_ktls_enable int version = gnutls_protocol_get_version(session); if ((version != GNUTLS_TLS1_3 && version != GNUTLS_TLS1_2) || (gnutls_cipher_get(session) != GNUTLS_CIPHER_AES_128_GCM && - gnutls_cipher_get(session) != GNUTLS_CIPHER_AES_256_GCM)) { + gnutls_cipher_get(session) != GNUTLS_CIPHER_AES_256_GCM && + gnutls_cipher_get(session) != GNUTLS_CIPHER_AES_128_CCM && + gnutls_cipher_get(session) != GNUTLS_CIPHER_CHACHA20_POLY1305)) { return GNUTLS_E_UNIMPLEMENTED_FEATURE; } @@ -114,7 +116,7 @@ int _gnutls_ktls_set_keys(gnutls_session_t session, gnutls_transport_ktls_enable case GNUTLS_CIPHER_AES_128_GCM: { struct tls12_crypto_info_aes_gcm_128 crypto_info; - memset(&crypto_info, 0, sizeof(crypto_info)); + memset(&crypto_info, 0, sizeof (crypto_info)); crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_128; assert(cipher_key.size == TLS_CIPHER_AES_GCM_128_KEY_SIZE); @@ -150,7 +152,7 @@ int _gnutls_ktls_set_keys(gnutls_session_t session, gnutls_transport_ktls_enable case GNUTLS_CIPHER_AES_256_GCM: { struct tls12_crypto_info_aes_gcm_256 crypto_info; - memset(&crypto_info, 0, sizeof(crypto_info)); + memset(&crypto_info, 0, sizeof (crypto_info)); crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_256; assert (cipher_key.size == TLS_CIPHER_AES_GCM_256_KEY_SIZE); @@ -182,9 +184,83 @@ int _gnutls_ktls_set_keys(gnutls_session_t session, gnutls_transport_ktls_enable } } break; + case GNUTLS_CIPHER_AES_128_CCM: + { + struct tls12_crypto_info_aes_ccm_128 crypto_info; + memset(&crypto_info, 0, sizeof (crypto_info)); + + crypto_info.info.cipher_type = TLS_CIPHER_AES_CCM_128; + assert(cipher_key.size == TLS_CIPHER_AES_CCM_128_KEY_SIZE); + + /* for TLS 1.2 IV is generated in kernel */ + if (version == GNUTLS_TLS1_2) { + crypto_info.info.version = TLS_1_2_VERSION; + memcpy(crypto_info.iv, seq_number, TLS_CIPHER_AES_CCM_128_IV_SIZE); + } else { + crypto_info.info.version = TLS_1_3_VERSION; + assert(iv.size == TLS_CIPHER_AES_CCM_128_SALT_SIZE + + TLS_CIPHER_AES_CCM_128_IV_SIZE); + + memcpy(crypto_info.iv, iv.data + + TLS_CIPHER_AES_CCM_128_SALT_SIZE, + TLS_CIPHER_AES_CCM_128_IV_SIZE); + } + + memcpy(crypto_info.salt, iv.data, + TLS_CIPHER_AES_CCM_128_SALT_SIZE); + memcpy(crypto_info.rec_seq, seq_number, + TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); + memcpy(crypto_info.key, cipher_key.data, + TLS_CIPHER_AES_CCM_128_KEY_SIZE); + + if (setsockopt (sockin, SOL_TLS, TLS_RX, + &crypto_info, sizeof (crypto_info))) { + session->internals.ktls_enabled &= ~GNUTLS_KTLS_RECV; + return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); + } + } + break; + case GNUTLS_CIPHER_CHACHA20_POLY1305: + { + struct tls12_crypto_info_chacha20_poly1305 crypto_info; + memset(&crypto_info, 0, sizeof (crypto_info)); + + crypto_info.info.cipher_type = TLS_CIPHER_CHACHA20_POLY1305; + assert(cipher_key.size == TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE); + + /* for TLS 1.2 IV is generated in kernel */ + if (version == GNUTLS_TLS1_2) { + crypto_info.info.version = TLS_1_2_VERSION; + memcpy(crypto_info.iv, seq_number, TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE); + } else { + crypto_info.info.version = TLS_1_3_VERSION; + assert(iv.size == TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE + + TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE); + + memcpy(crypto_info.iv, iv.data + + TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE, + TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE); + } + + memcpy(crypto_info.salt, iv.data, + TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE); + memcpy(crypto_info.rec_seq, seq_number, + TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE); + memcpy(crypto_info.key, cipher_key.data, + TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE); + + if (setsockopt (sockin, SOL_TLS, TLS_RX, + &crypto_info, sizeof (crypto_info))) { + session->internals.ktls_enabled &= ~GNUTLS_KTLS_RECV; + return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); + } + } + break; default: assert(0); } + + } ret = gnutls_record_get_state (session, 0, &mac_key, &iv, &cipher_key, @@ -198,7 +274,7 @@ int _gnutls_ktls_set_keys(gnutls_session_t session, gnutls_transport_ktls_enable case GNUTLS_CIPHER_AES_128_GCM: { struct tls12_crypto_info_aes_gcm_128 crypto_info; - memset(&crypto_info, 0, sizeof(crypto_info)); + memset(&crypto_info, 0, sizeof (crypto_info)); crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_128; @@ -234,7 +310,7 @@ int _gnutls_ktls_set_keys(gnutls_session_t session, gnutls_transport_ktls_enable case GNUTLS_CIPHER_AES_256_GCM: { struct tls12_crypto_info_aes_gcm_256 crypto_info; - memset(&crypto_info, 0, sizeof(crypto_info)); + memset(&crypto_info, 0, sizeof (crypto_info)); crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_256; assert (cipher_key.size == TLS_CIPHER_AES_GCM_256_KEY_SIZE); @@ -266,10 +342,81 @@ int _gnutls_ktls_set_keys(gnutls_session_t session, gnutls_transport_ktls_enable } } break; + case GNUTLS_CIPHER_AES_128_CCM: + { + struct tls12_crypto_info_aes_ccm_128 crypto_info; + memset(&crypto_info, 0, sizeof (crypto_info)); + + crypto_info.info.cipher_type = TLS_CIPHER_AES_CCM_128; + assert (cipher_key.size == TLS_CIPHER_AES_CCM_128_KEY_SIZE); + + /* for TLS 1.2 IV is generated in kernel */ + if (version == GNUTLS_TLS1_2) { + crypto_info.info.version = TLS_1_2_VERSION; + memcpy(crypto_info.iv, seq_number, TLS_CIPHER_AES_CCM_128_IV_SIZE); + } else { + crypto_info.info.version = TLS_1_3_VERSION; + assert (iv.size == TLS_CIPHER_AES_CCM_128_SALT_SIZE + + TLS_CIPHER_AES_CCM_128_IV_SIZE); + + memcpy (crypto_info.iv, iv.data + TLS_CIPHER_AES_CCM_128_SALT_SIZE, + TLS_CIPHER_AES_CCM_128_IV_SIZE); + } + + memcpy (crypto_info.salt, iv.data, + TLS_CIPHER_AES_CCM_128_SALT_SIZE); + memcpy (crypto_info.rec_seq, seq_number, + TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); + memcpy (crypto_info.key, cipher_key.data, + TLS_CIPHER_AES_CCM_128_KEY_SIZE); + + if (setsockopt (sockout, SOL_TLS, TLS_TX, + &crypto_info, sizeof (crypto_info))) { + session->internals.ktls_enabled &= ~GNUTLS_KTLS_SEND; + return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); + } + } + break; + case GNUTLS_CIPHER_CHACHA20_POLY1305: + { + struct tls12_crypto_info_chacha20_poly1305 crypto_info; + memset(&crypto_info, 0, sizeof (crypto_info)); + + crypto_info.info.cipher_type = TLS_CIPHER_CHACHA20_POLY1305; + assert (cipher_key.size == TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE); + + /* for TLS 1.2 IV is generated in kernel */ + if (version == GNUTLS_TLS1_2) { + crypto_info.info.version = TLS_1_2_VERSION; + memcpy(crypto_info.iv, seq_number, TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE); + } else { + crypto_info.info.version = TLS_1_3_VERSION; + assert (iv.size == TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE + + TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE); + + memcpy (crypto_info.iv, iv.data + TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE, + TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE); + } + + memcpy (crypto_info.salt, iv.data, + TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE); + memcpy (crypto_info.rec_seq, seq_number, + TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE); + memcpy (crypto_info.key, cipher_key.data, + TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE); + + if (setsockopt (sockout, SOL_TLS, TLS_TX, + &crypto_info, sizeof (crypto_info))) { + session->internals.ktls_enabled &= ~GNUTLS_KTLS_SEND; + return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); + } + } + break; default: assert(0); } + // set callback for sending handshake messages gnutls_handshake_set_read_function(session, _gnutls_ktls_send_handshake_msg); -- 2.38.1 From 24bd0559302f8a7adf9f072f61f2aa03efa664f6 Mon Sep 17 00:00:00 2001 From: Frantisek Krenzelok Date: Fri, 2 Dec 2022 11:07:48 +0100 Subject: [PATCH 2/2] KTLS: add ciphersuites (tests) Signed-off-by: Frantisek Krenzelok --- tests/gnutls_ktls.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/gnutls_ktls.c b/tests/gnutls_ktls.c index 8f9c5fa36..919270778 100644 --- a/tests/gnutls_ktls.c +++ b/tests/gnutls_ktls.c @@ -350,8 +350,12 @@ void doit(void) { run("NORMAL:-VERS-ALL:+VERS-TLS1.2:-CIPHER-ALL:+AES-128-GCM"); run("NORMAL:-VERS-ALL:+VERS-TLS1.2:-CIPHER-ALL:+AES-256-GCM"); + run("NORMAL:-VERS-ALL:+VERS-TLS1.2:-CIPHER-ALL:+AES-128-CCM"); + run("NORMAL:-VERS-ALL:+VERS-TLS1.2:-CIPHER-ALL:+CHACHA20-POLY1305"); run("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-GCM"); run("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-256-GCM"); + run("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-CCM"); + run("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+CHACHA20-POLY1305"); } #endif /* _WIN32 */ -- 2.38.1