Skip to content
Snippets Groups Projects
Commit ae813bfe authored by Daiki Ueno's avatar Daiki Ueno
Browse files

crypto: add GnuTLS backend


This adds a crypto backend based on GnuTLS.  While most of the
gnutls_* functions used in this backend are officially available in
upstream GnuTLS, the following functions are only available in the
'tmp-quic' branch, for ABI assurance reasons until the QUIC standard
is finalized:
- gnutls_handshake_write
- gnutls_quic_get_peer_transport_params

Signed-off-by: default avatarDaiki Ueno <dueno@redhat.com>
Signed-off-by: default avatarAnderson Toshiyuki Sasaki <ansasaki@redhat.com>
parent 1720afc4
Branches
No related merge requests found
...@@ -67,6 +67,7 @@ foreach(_build_type "Release" "MinSizeRel" "RelWithDebInfo") ...@@ -67,6 +67,7 @@ foreach(_build_type "Release" "MinSizeRel" "RelWithDebInfo")
endforeach() endforeach()
find_package(GnuTLS 3.6.12)
find_package(OpenSSL 1.1.1) find_package(OpenSSL 1.1.1)
find_package(Libev 4.11) find_package(Libev 4.11)
find_package(Libnghttp3 0.0.0) find_package(Libnghttp3 0.0.0)
...@@ -81,6 +82,7 @@ endif() ...@@ -81,6 +82,7 @@ endif()
set(HAVE_OPENSSL ${OPENSSL_FOUND}) set(HAVE_OPENSSL ${OPENSSL_FOUND})
if(OPENSSL_FOUND) if(OPENSSL_FOUND)
set(OPENSSL_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIR}) set(OPENSSL_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIR})
set(HAVE_CRYPTO 1)
else() else()
set(OPENSSL_INCLUDE_DIRS "") set(OPENSSL_INCLUDE_DIRS "")
set(OPENSSL_LIBRARIES "") set(OPENSSL_LIBRARIES "")
...@@ -90,6 +92,16 @@ set(HAVE_LIBEV ${LIBEV_FOUND}) ...@@ -90,6 +92,16 @@ set(HAVE_LIBEV ${LIBEV_FOUND})
# libnghttp3 (for examples) # libnghttp3 (for examples)
set(HAVE_LIBNGHTTP3 ${LIBNGHTTP3_FOUND}) set(HAVE_LIBNGHTTP3 ${LIBNGHTTP3_FOUND})
# GnuTLS (for examples)
set(HAVE_GNUTLS ${GNUTLS_FOUND})
if(GNUTLS_FOUND)
set(GNUTLS_INCLUDE_DIRS ${GNUTLS_INCLUDE_DIR})
set(HAVE_CRYPTO 1)
else()
set(GNUTLS_INCLUDE_DIRS "")
set(GNUTLS_LIBRARIES "")
endif()
# Checks for header files. # Checks for header files.
include(CheckIncludeFile) include(CheckIncludeFile)
check_include_file("arpa/inet.h" HAVE_ARPA_INET_H) check_include_file("arpa/inet.h" HAVE_ARPA_INET_H)
...@@ -280,4 +292,5 @@ message(STATUS "summary of build options: ...@@ -280,4 +292,5 @@ message(STATUS "summary of build options:
OpenSSL: ${HAVE_OPENSSL} (LIBS='${OPENSSL_LIBRARIES}') OpenSSL: ${HAVE_OPENSSL} (LIBS='${OPENSSL_LIBRARIES}')
Libev: ${HAVE_LIBEV} (LIBS='${LIBEV_LIBRARIES}') Libev: ${HAVE_LIBEV} (LIBS='${LIBEV_LIBRARIES}')
Libnghttp3: ${HAVE_LIBNGHTTP3} (LIBS='${LIBNGHTTP3_LIBRARIES}') Libnghttp3: ${HAVE_LIBNGHTTP3} (LIBS='${LIBNGHTTP3_LIBRARIES}')
GnuTLS: ${HAVE_GNUTLS} (LIBS='${GNUTLS_LIBRARIES}')
") ")
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
SUBDIRS = lib tests SUBDIRS = lib tests
if HAVE_OPENSSL if HAVE_CRYPTO
SUBDIRS += crypto SUBDIRS += crypto
endif endif
......
...@@ -49,6 +49,10 @@ AC_SUBST(CRYPTO_OPENSSL_LT_CURRENT, 0) ...@@ -49,6 +49,10 @@ AC_SUBST(CRYPTO_OPENSSL_LT_CURRENT, 0)
AC_SUBST(CRYPTO_OPENSSL_LT_REVISION, 0) AC_SUBST(CRYPTO_OPENSSL_LT_REVISION, 0)
AC_SUBST(CRYPTO_OPENSSL_LT_AGE, 0) AC_SUBST(CRYPTO_OPENSSL_LT_AGE, 0)
AC_SUBST(CRYPTO_GNUTLS_LT_CURRENT, 0)
AC_SUBST(CRYPTO_GNUTLS_LT_REVISION, 0)
AC_SUBST(CRYPTO_GNUTLS_LT_AGE, 0)
# from nghttp2 # from nghttp2
major=`echo $PACKAGE_VERSION |cut -d. -f1 | sed -e "s/[^0-9]//g"` major=`echo $PACKAGE_VERSION |cut -d. -f1 | sed -e "s/[^0-9]//g"`
minor=`echo $PACKAGE_VERSION |cut -d. -f2 | sed -e "s/[^0-9]//g"` minor=`echo $PACKAGE_VERSION |cut -d. -f2 | sed -e "s/[^0-9]//g"`
...@@ -144,6 +148,16 @@ if test "x${have_openssl}" = "xno"; then ...@@ -144,6 +148,16 @@ if test "x${have_openssl}" = "xno"; then
fi fi
AM_CONDITIONAL([HAVE_OPENSSL], [ test "x${have_openssl}" = "xyes" ]) AM_CONDITIONAL([HAVE_OPENSSL], [ test "x${have_openssl}" = "xyes" ])
# GnuTLS (for examples)
PKG_CHECK_MODULES([GNUTLS], [gnutls >= 3.6.11],
[have_gnutls=yes], [have_gnutls=no])
if test "x${have_gnutls}" = "xno"; then
AC_MSG_NOTICE($GNUTLS_PKG_ERRORS)
fi
AM_CONDITIONAL([HAVE_GNUTLS], [ test "x${have_gnutls}" = "xyes" ])
AM_CONDITIONAL([HAVE_CRYPTO], [ test "x${have_openssl}" = "xyes" || test "x${have_gnutls}" = "xyes" ])
# libnghttp3 (for examples) # libnghttp3 (for examples)
PKG_CHECK_MODULES([LIBNGHTTP3], [libnghttp3 >= 0.0.0], PKG_CHECK_MODULES([LIBNGHTTP3], [libnghttp3 >= 0.0.0],
[have_libnghttp3=yes], [have_libnghttp3=no]) [have_libnghttp3=yes], [have_libnghttp3=no])
...@@ -368,6 +382,8 @@ AC_CONFIG_FILES([ ...@@ -368,6 +382,8 @@ AC_CONFIG_FILES([
crypto/openssl/Makefile crypto/openssl/Makefile
crypto/openssl/libngtcp2_crypto_openssl.pc crypto/openssl/libngtcp2_crypto_openssl.pc
crypto/includes/Makefile crypto/includes/Makefile
crypto/gnutls/Makefile
crypto/gnutls/libngtcp2_crypto_gnutls.pc
third-party/Makefile third-party/Makefile
examples/Makefile examples/Makefile
]) ])
...@@ -399,6 +415,7 @@ AC_MSG_NOTICE([summary of build options: ...@@ -399,6 +415,7 @@ AC_MSG_NOTICE([summary of build options:
Static: ${enable_static} Static: ${enable_static}
Crypto helper libraries: Crypto helper libraries:
libngtcp2_crypto_openssl: ${have_openssl} libngtcp2_crypto_openssl: ${have_openssl}
libngtcp2_crypto_gnutls: ${have_gnutls}
Test: Test:
CUnit: ${have_cunit} (CFLAGS='${CUNIT_CFLAGS}' LIBS='${CUNIT_LIBS}') CUnit: ${have_cunit} (CFLAGS='${CUNIT_CFLAGS}' LIBS='${CUNIT_LIBS}')
Debug: Debug:
...@@ -408,5 +425,6 @@ AC_MSG_NOTICE([summary of build options: ...@@ -408,5 +425,6 @@ AC_MSG_NOTICE([summary of build options:
Libev: ${have_libev} (CFLAGS='${LIBEV_CFLAGS}' LIBS='${LIBEV_LIBS}') Libev: ${have_libev} (CFLAGS='${LIBEV_CFLAGS}' LIBS='${LIBEV_LIBS}')
Libnghttp3: ${have_libnghttp3} (CFLAGS='${LIBNGHTTP3_CFLAGS}' LIBS='${LIBNGHTTP3_LIBS}') Libnghttp3: ${have_libnghttp3} (CFLAGS='${LIBNGHTTP3_CFLAGS}' LIBS='${LIBNGHTTP3_LIBS}')
Jemalloc: ${have_jemalloc} (LIBS='${JEMALLOC_LIBS}') Jemalloc: ${have_jemalloc} (LIBS='${JEMALLOC_LIBS}')
GnuTLS: ${have_gnutls} (CFLAGS='${GNUTLS_CFLAGS}' LIBS='${GNUTLS_LIBS}')
Examples: ${enable_examples} Examples: ${enable_examples}
]) ])
...@@ -21,9 +21,18 @@ ...@@ -21,9 +21,18 @@
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
if(OPENSSL_FOUND) if(HAVE_CRYPTO)
add_subdirectory(includes) add_subdirectory(includes)
endif()
if(OPENSSL_FOUND)
add_subdirectory(openssl) add_subdirectory(openssl)
else() else()
message(WARNING "libngtcp2_crypto_openssl library is disabled due to lack of good OpenSSL") message(WARNING "libngtcp2_crypto_openssl library is disabled due to lack of good OpenSSL")
endif() endif()
if(GNUTLS_FOUND)
add_subdirectory(gnutls)
else()
message(WARNING "libngtcp2_crypto_gnutls library is disabled due to lack of good GnuTLS")
endif()
...@@ -22,6 +22,14 @@ ...@@ -22,6 +22,14 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
SUBDIRS = SUBDIRS =
if HAVE_CRYPTO
SUBDIRS += includes
endif
if HAVE_OPENSSL if HAVE_OPENSSL
SUBDIRS += includes openssl SUBDIRS += openssl
endif
if HAVE_GNUTLS
SUBDIRS += gnutls
endif endif
/libngtcp2_crypto_gnutls.pc
# ngtcp2
# Copyright (c) 2020 ngtcp2
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
add_definitions(-DBUILDING_NGTCP2)
set(ngtcp2_crypto_gnutls_SOURCES
gnutls.c
../shared.c
)
set(ngtcp2_crypto_gnutls_INCLUDE_DIRS
"${CMAKE_CURRENT_SOURCE_DIR}/../../lib/includes"
"${CMAKE_CURRENT_BINARY_DIR}/../../lib/includes"
"${CMAKE_CURRENT_SOURCE_DIR}/../../lib"
"${CMAKE_CURRENT_SOURCE_DIR}/../../crypto/includes"
"${CMAKE_CURRENT_BINARY_DIR}/../../crypto/includes"
"${GNUTLS_INCLUDE_DIRS}"
)
foreach(name libngtcp2_crypto_gnutls.pc)
configure_file("${name}.in" "${name}" @ONLY)
endforeach()
# Public shared library
add_library(ngtcp2_crypto_gnutls ${ngtcp2_crypto_gnutls_SOURCES})
set_target_properties(ngtcp2_crypto_gnutls PROPERTIES
COMPILE_FLAGS "${WARNCFLAGS}"
VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
C_VISIBILITY_PRESET hidden
)
target_include_directories(ngtcp2_crypto_gnutls PUBLIC
${ngtcp2_crypto_gnutls_INCLUDE_DIRS})
if(NOT BUILD_SHARED_LIBS)
target_compile_definitions(ngtcp2_crypto_gnutls PUBLIC "-DNGTCP2_STATICLIB")
endif()
install(TARGETS ngtcp2_crypto_gnutls
DESTINATION "${CMAKE_INSTALL_LIBDIR}")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libngtcp2_crypto_gnutls.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
# ngtcp2
# Copyright (c) 2020 ngtcp2 contributors
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
AM_CFLAGS = $(WARNCFLAGS) $(DEBUGCFLAGS) $(EXTRACFLAG)
AM_CPPFLAGS = -I$(top_srcdir)/lib/includes -I$(top_builddir)/lib/includes \
-I$(top_srcdir)/lib -DBUILDING_NGTCP2 \
-I$(top_srcdir)/crypto/includes -I$(top_builddir)/crypto/includes \
@GNUTLS_CFLAGS@
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libngtcp2_crypto_gnutls.pc
DISTCLEANFILES = $(pkgconfig_DATA)
lib_LTLIBRARIES = libngtcp2_crypto_gnutls.la
libngtcp2_crypto_gnutls_la_SOURCES = gnutls.c ../shared.c ../shared.h
libngtcp2_crypto_gnutls_la_LDFLAGS = -no-undefined \
-version-info $(CRYPTO_GNUTLS_LT_CURRENT):$(CRYPTO_GNUTLS_LT_REVISION):$(CRYPTO_GNUTLS_LT_AGE) \
@JEMALLOC_LIBS@ @GNUTLS_LIBS@
libngtcp2_crypto_gnutls_la_LIBADD = $(top_builddir)/lib/libngtcp2.la
/*
* ngtcp2
*
* Copyright (c) 2020 ngtcp2 contributors
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <assert.h>
#include <ngtcp2/ngtcp2_crypto.h>
#include <ngtcp2/ngtcp2_crypto_gnutls.h>
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
#include <string.h>
ngtcp2_crypto_ctx *ngtcp2_crypto_ctx_initial(ngtcp2_crypto_ctx *ctx) {
ctx->aead.native_handle = (void *)GNUTLS_CIPHER_AES_128_GCM;
ctx->md.native_handle = (void *)GNUTLS_DIG_SHA256;
ctx->hp.native_handle = (void *)GNUTLS_CIPHER_AES_128_CBC;
return ctx;
}
ngtcp2_crypto_aead *ngtcp2_crypto_aead_retry(ngtcp2_crypto_aead *aead) {
aead->native_handle = (void *)GNUTLS_CIPHER_AES_128_GCM;
return aead;
}
static gnutls_cipher_algorithm_t crypto_get_hp(gnutls_session_t session) {
switch (gnutls_cipher_get(session)) {
case GNUTLS_CIPHER_AES_128_GCM:
case GNUTLS_CIPHER_AES_128_CCM:
return GNUTLS_CIPHER_AES_128_CBC;
case GNUTLS_CIPHER_AES_256_GCM:
case GNUTLS_CIPHER_AES_256_CCM:
return GNUTLS_CIPHER_AES_256_CBC;
case GNUTLS_CIPHER_CHACHA20_POLY1305:
return GNUTLS_CIPHER_CHACHA20_32;
default:
return GNUTLS_CIPHER_UNKNOWN;
}
}
ngtcp2_crypto_ctx *ngtcp2_crypto_ctx_tls(ngtcp2_crypto_ctx *ctx,
void *tls_native_handle) {
gnutls_session_t session = tls_native_handle;
gnutls_cipher_algorithm_t cipher;
gnutls_digest_algorithm_t hash;
gnutls_cipher_algorithm_t hp_cipher;
cipher = gnutls_cipher_get(session);
if (cipher != GNUTLS_CIPHER_UNKNOWN || cipher != GNUTLS_CIPHER_NULL) {
ctx->aead.native_handle = (void *)cipher;
}
hash = gnutls_prf_hash_get(session);
if (hash != GNUTLS_DIG_UNKNOWN || hash != GNUTLS_DIG_NULL) {
ctx->md.native_handle = (void *)hash;
}
hp_cipher = crypto_get_hp(session);
if (hp_cipher != GNUTLS_CIPHER_UNKNOWN) {
ctx->hp.native_handle = (void *)hp_cipher;
}
return ctx;
}
size_t ngtcp2_crypto_md_hashlen(const ngtcp2_crypto_md *md) {
return gnutls_hash_get_len((gnutls_digest_algorithm_t)md->native_handle);
}
size_t ngtcp2_crypto_aead_keylen(const ngtcp2_crypto_aead *aead) {
return gnutls_cipher_get_key_size((gnutls_cipher_algorithm_t)aead->native_handle);
}
size_t ngtcp2_crypto_aead_noncelen(const ngtcp2_crypto_aead *aead) {
return gnutls_cipher_get_iv_size((gnutls_cipher_algorithm_t)aead->native_handle);
}
size_t ngtcp2_crypto_aead_taglen(const ngtcp2_crypto_aead *aead) {
return gnutls_cipher_get_tag_size((gnutls_cipher_algorithm_t)aead->native_handle);
}
int ngtcp2_crypto_hkdf_extract(uint8_t *dest, const ngtcp2_crypto_md *md,
const uint8_t *secret, size_t secretlen,
const uint8_t *salt, size_t saltlen) {
gnutls_mac_algorithm_t prf = (gnutls_mac_algorithm_t)md->native_handle;
gnutls_datum_t _secret = {(void*)secret, secretlen};
gnutls_datum_t _salt = {(void*)salt, saltlen};
if (gnutls_hkdf_extract(prf, &_secret, &_salt, dest) != 0) {
return -1;
}
return 0;
}
int ngtcp2_crypto_hkdf_expand(uint8_t *dest, size_t destlen,
const ngtcp2_crypto_md *md, const uint8_t *secret,
size_t secretlen, const uint8_t *info,
size_t infolen) {
gnutls_mac_algorithm_t prf = (gnutls_mac_algorithm_t)md->native_handle;
gnutls_datum_t _secret = {(void*)secret, secretlen};
gnutls_datum_t _info = {(void*)info, infolen};
if (gnutls_hkdf_expand(prf, &_secret, &_info, dest, destlen) != 0) {
return -1;
}
return 0;
}
int ngtcp2_crypto_encrypt(uint8_t *dest, const ngtcp2_crypto_aead *aead,
const uint8_t *plaintext, size_t plaintextlen,
const uint8_t *key, const uint8_t *nonce,
size_t noncelen, const uint8_t *ad, size_t adlen) {
gnutls_cipher_algorithm_t cipher = (gnutls_cipher_algorithm_t)aead->native_handle;
gnutls_aead_cipher_hd_t hd = NULL;
gnutls_datum_t _key;
size_t taglen = ngtcp2_crypto_aead_taglen(aead);
size_t ciphertextlen = plaintextlen + taglen;
int rv = 0;
_key.data = (void *)key;
_key.size = ngtcp2_crypto_aead_keylen(aead);
if (gnutls_aead_cipher_init(&hd, cipher, &_key) != 0 ||
gnutls_aead_cipher_encrypt(hd,
nonce, noncelen,
ad, adlen, taglen,
plaintext, plaintextlen,
dest, &ciphertextlen) != 0) {
rv = -1;
}
gnutls_aead_cipher_deinit(hd);
return rv;
}
int ngtcp2_crypto_decrypt(uint8_t *dest, const ngtcp2_crypto_aead *aead,
const uint8_t *ciphertext, size_t ciphertextlen,
const uint8_t *key, const uint8_t *nonce,
size_t noncelen, const uint8_t *ad, size_t adlen) {
gnutls_cipher_algorithm_t cipher =
(gnutls_cipher_algorithm_t)aead->native_handle;
size_t taglen = gnutls_cipher_get_tag_size(cipher);
gnutls_aead_cipher_hd_t hd = NULL;
gnutls_datum_t _key;
int rv = 0;
size_t plaintextlen;
if (taglen > ciphertextlen) {
return -1;
}
plaintextlen = ciphertextlen - taglen;
_key.data = (void *)key;
_key.size = ngtcp2_crypto_aead_keylen(aead);
if (gnutls_aead_cipher_init(&hd, cipher, &_key) != 0 ||
gnutls_aead_cipher_decrypt(hd,
nonce, noncelen,
ad, adlen,
taglen,
ciphertext, ciphertextlen,
dest, &plaintextlen) != 0) {
rv = -1;
}
gnutls_aead_cipher_deinit(hd);
return rv;
}
int ngtcp2_crypto_hp_mask(uint8_t *dest, const ngtcp2_crypto_cipher *hp,
const uint8_t *hp_key, const uint8_t *sample) {
gnutls_cipher_algorithm_t cipher = (gnutls_cipher_algorithm_t)hp->native_handle;
int rv = 0;
switch (cipher) {
case GNUTLS_CIPHER_AES_128_CBC:
case GNUTLS_CIPHER_AES_256_CBC:
{
gnutls_cipher_hd_t hd = NULL;
gnutls_datum_t _hp_key;
uint8_t iv[16];
gnutls_datum_t _iv;
uint8_t buf[16];
_hp_key.data = (void *)hp_key;
_hp_key.size = gnutls_cipher_get_key_size(cipher);
/* Emulate one block AES-ECB by invalidating the effect of IV */
memset(iv, 0, sizeof(iv));
_iv.data = iv;
_iv.size = 16;
if (gnutls_cipher_init(&hd, cipher, &_hp_key, &_iv) != 0 ||
gnutls_cipher_encrypt2(hd, sample, 16, buf, sizeof(buf)) != 0) {
rv = -1;
}
memcpy(dest, buf, 5);
gnutls_cipher_deinit(hd);
}
break;
case GNUTLS_CIPHER_CHACHA20_32:
{
gnutls_cipher_hd_t hd = NULL;
static const uint8_t PLAINTEXT[] = "\x00\x00\x00\x00\x00";
gnutls_datum_t _hp_key;
gnutls_datum_t _iv;
uint8_t buf[5 + 16];
size_t buflen = sizeof(buf);
_hp_key.data = (void *)hp_key;
_hp_key.size = gnutls_cipher_get_key_size(cipher);
_iv.data = (void *)sample;
_iv.size = 16;
if (gnutls_cipher_init(&hd, cipher, &_hp_key, &_iv) != 0 ||
gnutls_cipher_encrypt2(hd,
PLAINTEXT, sizeof(PLAINTEXT) - 1,
buf, buflen) != 0) {
rv = -1;
}
memcpy(dest, buf, 5);
gnutls_cipher_deinit(hd);
}
break;
default:
assert(0);
}
return rv;
}
static gnutls_record_encryption_level_t
from_ngtcp2_level(ngtcp2_crypto_level crypto_level) {
switch (crypto_level) {
case NGTCP2_CRYPTO_LEVEL_INITIAL:
return GNUTLS_ENCRYPTION_LEVEL_INITIAL;
case NGTCP2_CRYPTO_LEVEL_HANDSHAKE:
return GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE;
case NGTCP2_CRYPTO_LEVEL_APP:
return GNUTLS_ENCRYPTION_LEVEL_APPLICATION;
case NGTCP2_CRYPTO_LEVEL_EARLY:
return GNUTLS_ENCRYPTION_LEVEL_EARLY;
default:
assert(0);
}
}
int ngtcp2_crypto_read_write_crypto_data(ngtcp2_conn *conn, void *tls,
ngtcp2_crypto_level crypto_level,
const uint8_t *data, size_t datalen) {
gnutls_session_t session = tls;
int rv;
if (datalen > 0) {
if (gnutls_handshake_write(session, from_ngtcp2_level(crypto_level), data,
datalen) != 0) {
return -1;
}
}
if (!ngtcp2_conn_get_handshake_completed(conn)) {
rv = gnutls_handshake(session);
if (rv < 0) {
if (!gnutls_error_is_fatal(rv)) {
return 0;
}
gnutls_alert_send_appropriate(session, rv);
return -1;
}
ngtcp2_conn_handshake_completed(conn);
}
return 0;
}
int ngtcp2_crypto_set_remote_transport_params(ngtcp2_conn *conn, void *tls,
ngtcp2_crypto_side side) {
/* Nothing to do; GnuTLS applications are supposed to register the
quic_transport_parameters extension with
gnutls_session_ext_register. */
return 0;
}
# ngtcp2
# Copyright (c) 2020 ngtcp2 contributors
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: libngtcp2_crypto_gnutls
Description: ngtcp2 GnuTLS crypto library
URL: https://github.com/ngtcp2/ngtcp2
Version: @VERSION@
Libs: -L${libdir} -lngtcp2_crypto_gnutls
Cflags: -I${includedir}
/*
* ngtcp2
*
* Copyright (c) 2020 ngtcp2 contributors
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef NGTCP2_CRYPTO_GNUTLS_H
#define NGTCP2_CRYPTO_GNUTLS_H
#include <ngtcp2/ngtcp2.h>
#endif /* NGTCP2_CRYPTO_GNUTLS_H */
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment