Skip to content

Commit

Permalink
Add optional support for the AEGIS cipher suites
Browse files Browse the repository at this point in the history
This adds the following TLS 1.3 suites:

- `TLS_AEGIS_256_SHA384 (0x13, 0x07)`
- `TLS_AEGIS_128L_SHA256 (0x13, 0x06)`

Requires `libaegis`.
  • Loading branch information
jedisct1 committed Aug 4, 2023
1 parent 9a3a311 commit 6609fc5
Show file tree
Hide file tree
Showing 13 changed files with 492 additions and 16 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: "Linux / OpenSSL 1.1.0"
command: make -f misc/docker-ci.mk CMAKE_ARGS='-DOPENSSL_ROOT_DIR=-DOPENSSL_ROOT_DIR=/opt/openssl-1.1.0 -DWITH_FUSION=OFF' CONTAINER_NAME='h2oserver/h2o-ci:ubuntu1604'
- name: "Linux / OpenSSL 1.1.1"
command: make -f misc/docker-ci.mk
command: make -f misc/docker-ci.mk CMAKE_ARGS='-DWITH_AEGIS=1 -DAEGIS_INCLUDE_DIR=/usr/local/include'
- name: "Linux / OpenSSL 3.0"
command: make -f misc/docker-ci.mk CONTAINER_NAME=h2oserver/h2o-ci:ubuntu2204
- name: "Linux / OpenSSL 1.1.1 + ASan & UBSan"
Expand Down
39 changes: 32 additions & 7 deletions CMakeLists.txt
Expand Up @@ -31,6 +31,7 @@ ENDIF ()
IF (WITH_FUSION)
MESSAGE(STATUS "Enabling 'fusion' AES-GCM engine")
ENDIF ()
OPTION(WITH_AEGIS "enable AEGIS (requires libaegis)" ${WITH_AEGIS})

SET(CMAKE_C_FLAGS "-std=c99 -Wall -O2 -g ${CC_WARNING_FLAGS} ${CMAKE_C_FLAGS}")
INCLUDE_DIRECTORIES(
Expand Down Expand Up @@ -88,8 +89,13 @@ ADD_LIBRARY(picotls-core ${CORE_FILES})
TARGET_LINK_LIBRARIES(picotls-core ${CORE_EXTRA_LIBS})
TARGET_LINK_DIRECTORIES(picotls-core PUBLIC ${CORE_EXTRA_LIBS_DIRS})

IF (WITH_AEGIS)
SET(MINICRYPTO_AEGIS_FILES lib/cifra/libaegis.c)
ENDIF ()

ADD_LIBRARY(picotls-minicrypto
${MINICRYPTO_LIBRARY_FILES}
${MINICRYPTO_AEGIS_FILES}
lib/cifra.c
lib/cifra/x25519.c
lib/cifra/chacha20.c
Expand All @@ -103,6 +109,7 @@ ADD_LIBRARY(picotls-minicrypto
TARGET_LINK_LIBRARIES(picotls-minicrypto picotls-core)
ADD_EXECUTABLE(test-minicrypto.t
${MINICRYPTO_LIBRARY_FILES}
${MINICRYPTO_AEGIS_FILES}
deps/picotest/picotest.c
${CORE_TEST_FILES}
t/minicrypto.c
Expand All @@ -120,19 +127,37 @@ SET(TEST_EXES test-minicrypto.t)
SET(PTLSBENCH_LIBS
picotls-minicrypto picotls-core)

IF (WITH_AEGIS)
FIND_PACKAGE(aegis)
IF (aegis_FOUND)
INCLUDE_DIRECTORIES(${AEGIS_INCLUDE_DIR})
IF (EXISTS "${AEGIS_INCLUDE_DIR}/aegis.h")
MESSAGE(STATUS "Enabling AEGIS support (library found in ${aegis_DIR})")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPTLS_HAVE_AEGIS=1")
SET(AEGIS_LIBRARIES ${aegis_LIBRARIES})
TARGET_LINK_LIBRARIES(test-minicrypto.t ${AEGIS_LIBRARIES})
ELSE()
MESSAGE(FATAL_ERROR "libaegis found, but aegis.h not found - Define AEGIS_INCLUDE_DIR accordingly")
ENDIF()
ELSE()
MESSAGE(FATAL_ERROR "libaegis not found")
ENDIF()
ENDIF()

FIND_PACKAGE(OpenSSL)
BORINGSSL_ADJUST()

IF (OPENSSL_FOUND AND NOT (OPENSSL_VERSION VERSION_LESS "1.0.1"))
MESSAGE(STATUS " Enabling OpenSSL support")
INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
ADD_LIBRARY(picotls-openssl lib/openssl.c)
TARGET_LINK_LIBRARIES(picotls-openssl ${OPENSSL_CRYPTO_LIBRARIES} picotls-core ${CMAKE_DL_LIBS})
TARGET_LINK_LIBRARIES(picotls-openssl ${OPENSSL_CRYPTO_LIBRARIES} ${AEGIS_LIBRARIES} picotls-core ${CMAKE_DL_LIBS})
ADD_EXECUTABLE(cli t/cli.c lib/pembase64.c)
TARGET_LINK_LIBRARIES(cli picotls-openssl picotls-core)

ADD_EXECUTABLE(test-openssl.t
${MINICRYPTO_LIBRARY_FILES}
${MINICRYPTO_AEGIS_FILES}
lib/cifra.c
lib/cifra/x25519.c
lib/cifra/chacha20.c
Expand All @@ -147,9 +172,9 @@ IF (OPENSSL_FOUND AND NOT (OPENSSL_VERSION VERSION_LESS "1.0.1"))
${CORE_TEST_FILES}
t/openssl.c)
SET_TARGET_PROPERTIES(test-openssl.t PROPERTIES COMPILE_FLAGS "-DPTLS_MEMORY_DEBUG=1")
TARGET_LINK_LIBRARIES(test-openssl.t ${OPENSSL_CRYPTO_LIBRARIES} ${CMAKE_DL_LIBS})
TARGET_LINK_LIBRARIES(test-openssl.t ${OPENSSL_CRYPTO_LIBRARIES} ${AEGIS_LIBRARIES} ${CMAKE_DL_LIBS})

LIST(APPEND PTLSBENCH_LIBS picotls-openssl ${OPENSSL_CRYPTO_LIBRARIES} ${CMAKE_DL_LIBS})
LIST(APPEND PTLSBENCH_LIBS picotls-openssl ${OPENSSL_CRYPTO_LIBRARIES} ${AEGIS_LIBRARIES} ${CMAKE_DL_LIBS})

SET(TEST_EXES ${TEST_EXES} test-openssl.t)
ELSE ()
Expand Down Expand Up @@ -196,7 +221,7 @@ ENDIF ()

IF (BUILD_FUZZER)
IF (NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
MESSAGE(FATAL ERROR "The fuzzer needs clang as a compiler")
MESSAGE(FATAL_ERROR "The fuzzer needs clang as a compiler")
ENDIF()

ADD_EXECUTABLE(fuzz-asn1 fuzz/fuzz-asn1.c)
Expand Down Expand Up @@ -225,8 +250,8 @@ IF (BUILD_FUZZER)
LINK_FLAGS "-fsanitize=fuzzer")
ENDIF (OSS_FUZZ)

TARGET_LINK_LIBRARIES(fuzz-asn1 picotls-minicrypto picotls-core picotls-openssl ${OPENSSL_CRYPTO_LIBRARIES} ${LIB_FUZZER})
TARGET_LINK_LIBRARIES(fuzz-server-hello picotls-core picotls-openssl ${OPENSSL_CRYPTO_LIBRARIES} ${LIB_FUZZER})
TARGET_LINK_LIBRARIES(fuzz-client-hello picotls-core picotls-openssl ${OPENSSL_CRYPTO_LIBRARIES} ${LIB_FUZZER})
TARGET_LINK_LIBRARIES(fuzz-asn1 picotls-minicrypto picotls-core picotls-openssl ${OPENSSL_CRYPTO_LIBRARIES} ${AEGIS_LIBRARIES} ${LIB_FUZZER})
TARGET_LINK_LIBRARIES(fuzz-server-hello picotls-core picotls-openssl ${OPENSSL_CRYPTO_LIBRARIES} ${AEGIS_LIBRARIES} ${LIB_FUZZER})
TARGET_LINK_LIBRARIES(fuzz-client-hello picotls-core picotls-openssl ${OPENSSL_CRYPTO_LIBRARIES} ${AEGIS_LIBRARIES} ${LIB_FUZZER})

ENDIF()
5 changes: 3 additions & 2 deletions README.md
Expand Up @@ -8,6 +8,7 @@ Picotls is a [TLS 1.3 (RFC 8446)](https://tools.ietf.org/html/rfc8446) protocol
* "OpenSSL" backend using libcrypto for crypto and X.509 operations
* "minicrypto" backend using [cifra](https://github.com/ctz/cifra) for most crypto and [micro-ecc](https://github.com/kmackay/micro-ecc) for secp256r1
* ["fusion" AES-GCM engine, optimized for QUIC and other protocols that use short AEAD blocks](https://github.com/h2o/picotls/pull/310)
* [libaegis](https://github.com/jedisct1/libaegis) for the AEGIS AEADs
* support for PSK, PSK-DHE resumption using 0-RTT
* API for dealing directly with TLS handshake messages (essential for QUIC)
* supported extensions:
Expand All @@ -23,8 +24,8 @@ License and the cryptographic algorithms supported by the crypto bindings are as

| Binding | License | Key Exchange | Certificate | AEAD cipher |
|:-----:|:-----:|:-----:|:-----:|:-----:|
| minicrypto | [CC0](https://github.com/ctz/cifra/) / [2-clause BSD](https://github.com/kmackay/micro-ecc) | secp256r1, x25519 | ECDSA (secp256r1)<sup>1</sup> | AES-128-GCM, chacha20-poly1305 |
| OpenSSL | OpenSSL | secp256r1, secp384r1, secp521r1, x25519 | RSA, ECDSA (secp256r1, secp384r1, secp521r1), ed25519 | AES-128-GCM, AES-256-GCM, chacha20-poly1305 |
| minicrypto | [CC0](https://github.com/ctz/cifra/) / [2-clause BSD](https://github.com/kmackay/micro-ecc) | secp256r1, x25519 | ECDSA (secp256r1)<sup>1</sup> | AES-128-GCM, chacha20-poly1305, AEGIS-128L (using libaegis), AEGIS-256 (using libaegis) |
| OpenSSL | OpenSSL | secp256r1, secp384r1, secp521r1, x25519 | RSA, ECDSA (secp256r1, secp384r1, secp521r1), ed25519 | AES-128-GCM, AES-256-GCM, chacha20-poly1305, AEGIS-128L (using libaegis), AEGIS-256 (using libaegis) |

Note 1: Minicrypto binding is capable of signing a handshake using the certificate's key, but cannot verify a signature sent by the peer.

Expand Down
18 changes: 17 additions & 1 deletion include/picotls.h
Expand Up @@ -91,6 +91,18 @@ extern "C" {
#define PTLS_CHACHA20POLY1305_CONFIDENTIALITY_LIMIT UINT64_MAX /* at least 2^64 */
#define PTLS_CHACHA20POLY1305_INTEGRITY_LIMIT UINT64_C(0x1000000000) /* 2^36 */

#define PTLS_AEGIS128L_KEY_SIZE 16
#define PTLS_AEGIS128L_IV_SIZE 16
#define PTLS_AEGIS128L_TAG_SIZE 16
#define PTLS_AEGIS128L_CONFIDENTIALITY_LIMIT UINT64_MAX /* at least 2^64 */
#define PTLS_AEGIS128L_INTEGRITY_LIMIT UINT64_C(0x1000000000000) /* 2^48 */

#define PTLS_AEGIS256_KEY_SIZE 32
#define PTLS_AEGIS256_IV_SIZE 32
#define PTLS_AEGIS256_TAG_SIZE 16
#define PTLS_AEGIS256_CONFIDENTIALITY_LIMIT UINT64_MAX /* at least 2^64 */
#define PTLS_AEGIS256_INTEGRITY_LIMIT UINT64_C(0x1000000000000) /* 2^48 */

#define PTLS_BLOWFISH_KEY_SIZE 16
#define PTLS_BLOWFISH_BLOCK_SIZE 8

Expand All @@ -104,7 +116,7 @@ extern "C" {
#define PTLS_SHA512_DIGEST_SIZE 64

#define PTLS_MAX_SECRET_SIZE 32
#define PTLS_MAX_IV_SIZE 16
#define PTLS_MAX_IV_SIZE 32
#define PTLS_MAX_DIGEST_SIZE 64

/* versions */
Expand All @@ -118,6 +130,10 @@ extern "C" {
#define PTLS_CIPHER_SUITE_NAME_AES_256_GCM_SHA384 "TLS_AES_256_GCM_SHA384"
#define PTLS_CIPHER_SUITE_CHACHA20_POLY1305_SHA256 0x1303
#define PTLS_CIPHER_SUITE_NAME_CHACHA20_POLY1305_SHA256 "TLS_CHACHA20_POLY1305_SHA256"
#define PTLS_CIPHER_SUITE_AEGIS256_SHA384 0x1306
#define PTLS_CIPHER_SUITE_NAME_AEGIS256_SHA384 "TLS_AEGIS_256_SHA384"
#define PTLS_CIPHER_SUITE_AEGIS128L_SHA256 0x1307
#define PTLS_CIPHER_SUITE_NAME_AEGIS128L_SHA256 "TLS_AEGIS_128L_SHA256"

/* TLS/1.2 cipher-suites that we support (for compatibility, OpenSSL names are used) */
#define PTLS_CIPHER_SUITE_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xc02b
Expand Down
8 changes: 8 additions & 0 deletions include/picotls/minicrypto.h
Expand Up @@ -47,8 +47,16 @@ extern ptls_key_exchange_algorithm_t *ptls_minicrypto_key_exchanges[];
extern ptls_cipher_algorithm_t ptls_minicrypto_aes128ecb, ptls_minicrypto_aes256ecb, ptls_minicrypto_aes128ctr,
ptls_minicrypto_aes256ctr, ptls_minicrypto_chacha20;
extern ptls_aead_algorithm_t ptls_minicrypto_aes128gcm, ptls_minicrypto_aes256gcm, ptls_minicrypto_chacha20poly1305;
#ifdef PTLS_HAVE_AEGIS
extern ptls_aead_algorithm_t ptls_minicrypto_aegis128l;
extern ptls_aead_algorithm_t ptls_minicrypto_aegis256;
#endif
extern ptls_hash_algorithm_t ptls_minicrypto_sha256, ptls_minicrypto_sha384;
extern ptls_cipher_suite_t ptls_minicrypto_aes128gcmsha256, ptls_minicrypto_aes256gcmsha384, ptls_minicrypto_chacha20poly1305sha256;
#ifdef PTLS_HAVE_AEGIS
extern ptls_cipher_suite_t ptls_minicrypto_aegis128lsha256;
extern ptls_cipher_suite_t ptls_minicrypto_aegis256sha384;
#endif
extern ptls_cipher_suite_t *ptls_minicrypto_cipher_suites[];

typedef struct st_ptls_asn1_pkcs8_private_key_t {
Expand Down
15 changes: 13 additions & 2 deletions lib/cifra.c
Expand Up @@ -23,5 +23,16 @@
#include "picotls.h"
#include "picotls/minicrypto.h"

ptls_cipher_suite_t *ptls_minicrypto_cipher_suites[] = {&ptls_minicrypto_aes256gcmsha384, &ptls_minicrypto_aes128gcmsha256,
&ptls_minicrypto_chacha20poly1305sha256, NULL};
ptls_cipher_suite_t *ptls_minicrypto_cipher_suites[] = {// ciphers used with sha384 (must be first)
#ifdef PTLS_HAVE_AEGIS
&ptls_minicrypto_aegis256sha384,
#endif
&ptls_minicrypto_aes256gcmsha384,

// ciphers used with sha256
#ifdef PTLS_HAVE_AEGIS
&ptls_minicrypto_aegis128lsha256,
#endif
&ptls_minicrypto_aes128gcmsha256,
&ptls_minicrypto_chacha20poly1305sha256,
NULL};
62 changes: 62 additions & 0 deletions lib/cifra/libaegis.c
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2023 Frank Denis
*
* 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.
*/

#include "../libaegis.h"

extern ptls_hash_algorithm_t ptls_minicrypto_sha256;
extern ptls_hash_algorithm_t ptls_minicrypto_sha384;

ptls_aead_algorithm_t ptls_minicrypto_aegis128l = {"AEGIS-128L",
PTLS_AEGIS128L_CONFIDENTIALITY_LIMIT,
PTLS_AEGIS128L_INTEGRITY_LIMIT,
NULL,
NULL,
PTLS_AEGIS128L_KEY_SIZE,
PTLS_AEGIS128L_IV_SIZE,
PTLS_AEGIS128L_TAG_SIZE,
{ 0, 0 },
0,
0,
sizeof(struct aegis128l_context_t),
aegis128l_setup_crypto};
ptls_cipher_suite_t ptls_minicrypto_aegis128lsha256 = {.id = PTLS_CIPHER_SUITE_AEGIS128L_SHA256,
.name = PTLS_CIPHER_SUITE_NAME_AEGIS128L_SHA256,
.aead = &ptls_minicrypto_aegis128l,
.hash = &ptls_minicrypto_sha256};

ptls_aead_algorithm_t ptls_minicrypto_aegis256 = {"AEGIS-256",
PTLS_AEGIS256_CONFIDENTIALITY_LIMIT,
PTLS_AEGIS256_INTEGRITY_LIMIT,
NULL,
NULL,
PTLS_AEGIS256_KEY_SIZE,
PTLS_AEGIS256_IV_SIZE,
PTLS_AEGIS256_TAG_SIZE,
{ 0, 0 },
0,
0,
sizeof(struct aegis256_context_t),
aegis256_setup_crypto};
ptls_cipher_suite_t ptls_minicrypto_aegis256sha384 = {.id = PTLS_CIPHER_SUITE_AEGIS256_SHA384,
.name = PTLS_CIPHER_SUITE_NAME_AEGIS256_SHA384,
.aead = &ptls_minicrypto_aegis256,
.hash = &ptls_minicrypto_sha384};

0 comments on commit 6609fc5

Please sign in to comment.