Skip to content

Commit

Permalink
Merge pull request #478 from jedisct1/aegis
Browse files Browse the repository at this point in the history
Add optional support for the AEGIS cipher suites
  • Loading branch information
kazuho committed Aug 9, 2023
2 parents 8cf2d1b + 958ed1a commit fe2cb6b
Show file tree
Hide file tree
Showing 16 changed files with 526 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
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
37 changes: 31 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
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 @@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
9 changes: 9 additions & 0 deletions include/picotls/minicrypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,18 @@ 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[];
extern ptls_cipher_suite_t *ptls_minicrypto_cipher_suites_all[];

typedef struct st_ptls_asn1_pkcs8_private_key_t {
ptls_iovec_t vec;
Expand Down
8 changes: 8 additions & 0 deletions include/picotls/openssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ extern ptls_hash_algorithm_t ptls_openssl_sha512;
extern ptls_cipher_suite_t ptls_openssl_aes128gcmsha256;
extern ptls_cipher_suite_t ptls_openssl_aes256gcmsha384;
extern ptls_cipher_suite_t *ptls_openssl_cipher_suites[];
extern ptls_cipher_suite_t *ptls_openssl_cipher_suites_all[];
extern ptls_cipher_suite_t *ptls_openssl_tls12_cipher_suites[];

#if PTLS_OPENSSL_HAVE_CHACHA20_POLY1305
Expand All @@ -93,6 +94,13 @@ extern ptls_aead_algorithm_t ptls_openssl_chacha20poly1305;
extern ptls_cipher_suite_t ptls_openssl_chacha20poly1305sha256;
#endif

#ifdef PTLS_HAVE_AEGIS
extern ptls_aead_algorithm_t ptls_openssl_aegis128l;
extern ptls_aead_algorithm_t ptls_openssl_aegis256;
extern ptls_cipher_suite_t ptls_openssl_aegis128lsha256;
extern ptls_cipher_suite_t ptls_openssl_aegis256sha384;
#endif

extern ptls_cipher_suite_t ptls_openssl_tls12_ecdhe_rsa_aes128gcmsha256;
extern ptls_cipher_suite_t ptls_openssl_tls12_ecdhe_ecdsa_aes128gcmsha256;
extern ptls_cipher_suite_t ptls_openssl_tls12_ecdhe_rsa_aes256gcmsha384;
Expand Down
23 changes: 21 additions & 2 deletions lib/cifra.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,24 @@
#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)
&ptls_minicrypto_aes256gcmsha384,

// ciphers used with sha256
&ptls_minicrypto_aes128gcmsha256,
&ptls_minicrypto_chacha20poly1305sha256,
NULL};

ptls_cipher_suite_t *ptls_minicrypto_cipher_suites_all[] = {// 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
Original file line number Diff line number Diff line change
@@ -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};
Loading

0 comments on commit fe2cb6b

Please sign in to comment.