Skip to content

Commit

Permalink
Merge branch 'master' into kazuho/mbedtls
Browse files Browse the repository at this point in the history
  • Loading branch information
kazuho committed Nov 14, 2023
2 parents 7e7d39b + 8fb46c6 commit 762afbb
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 22 deletions.
14 changes: 4 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,13 @@ IF (CMAKE_VERSION VERSION_LESS 3.13.0)
ENDIF ()

FIND_PACKAGE(PkgConfig REQUIRED)
INCLUDE(cmake/dtrace-utils.cmake)
INCLUDE(cmake/boringssl-adjust.cmake)
INCLUDE(cmake/dtrace-utils.cmake)
INCLUDE(cmake/fusion.cmake)
SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

CHECK_DTRACE(${PROJECT_SOURCE_DIR}/picotls-probes.d)
IF ((CMAKE_SIZEOF_VOID_P EQUAL 8) AND
(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") OR
(CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64") OR
(CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64"))
SET(WITH_FUSION_DEFAULT "ON")
ELSE ()
SET(WITH_FUSION_DEFAULT "OFF")
ENDIF ()
CHECK_FUSION_PREREQUISITES()

OPTION(WITH_DTRACE "use USDT (userspace Dtrace probes)" ${HAVE_DTRACE})
OPTION(WITH_FUSION "build 'fusion' AES-GCM engine" ${WITH_FUSION_DEFAULT})
Expand Down Expand Up @@ -197,7 +191,7 @@ IF (WITH_FUSION)
ADD_DEPENDENCIES(test-fusion.t generate-picotls-probes)
ENDIF ()
SET(TEST_EXES ${TEST_EXES} test-fusion.t)

SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPTLS_HAVE_FUSION=1")
LIST(APPEND PTLSBENCH_LIBS picotls-fusion)
ENDIF ()
Expand Down
30 changes: 30 additions & 0 deletions cmake/fusion.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
INCLUDE(CheckCSourceCompiles)
INCLUDE(CMakePushCheckState)

FUNCTION (CHECK_FUSION_PREREQUISITES)
MESSAGE(STATUS "Detecting fusion support")

CMAKE_PUSH_CHECK_STATE()
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -mavx2 -maes -mpclmul -mvaes -mvpclmulqdq")
CHECK_C_SOURCE_COMPILES("
#include <emmintrin.h>
#include <immintrin.h>
int main(void) {
__m256i ord0, ord1, ord2, ord3 = _mm256_setzero_si256();
ord0 = _mm256_aesenc_epi128(ord1, ord2);
ord3 = _mm256_aesenclast_epi128(ord0, ord1);
ord1 = _mm256_clmulepi64_epi128(ord3, ord2, 0x00);
_mm_insert_epi64(_mm_setr_epi32(0, 1, 2, 3), 0, 0);
return 0;
}
" CC_HAS_AESNI256)
CMAKE_POP_CHECK_STATE()

IF (CC_HAS_AESNI256)
MESSAGE(STATUS "Can use fusion")
SET(WITH_FUSION_DEFAULT "ON" PARENT_SCOPE)
ELSE ()
MESSAGE(STATUS "Cannot use fusion")
SET(WITH_FUSION_DEFAULT "OFF" PARENT_SCOPE)
ENDIF ()
ENDFUNCTION ()
11 changes: 10 additions & 1 deletion lib/cifra/x25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ static int x25519_derive_secret(ptls_iovec_t *secret, const uint8_t *clientpriv,
return PTLS_ERROR_NO_MEMORY;

cf_curve25519_mul(secret->base, clientpriv != NULL ? clientpriv : serverpriv, clientpriv != NULL ? serverpub : clientpub);

static const uint8_t zeros[X25519_KEY_SIZE] = {0};
if (ptls_mem_equal(secret->base, zeros, sizeof(zeros))) {
free(secret->base);
return PTLS_ERROR_INCOMPATIBLE_KEY;
}

secret->len = X25519_KEY_SIZE;
return 0;
}
Expand Down Expand Up @@ -111,8 +118,10 @@ static int x25519_key_exchange(ptls_key_exchange_algorithm_t *algo, ptls_iovec_t

Exit:
ptls_clear_memory(priv, sizeof(priv));
if (pub != NULL && ret != 0)
if (pub != NULL && ret != 0) {
ptls_clear_memory(pub, X25519_KEY_SIZE);
free(pub);
}
return ret;
}

Expand Down
26 changes: 22 additions & 4 deletions lib/openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -525,22 +525,35 @@ static int evp_keyex_on_exchange(ptls_key_exchange_context_t **_ctx, int release
}

#ifdef OPENSSL_IS_BORINGSSL
#define X25519_KEY_SIZE 32
if (ctx->super.algo->id == PTLS_GROUP_X25519) {
secret->len = peerkey.len;
if ((secret->base = malloc(secret->len)) == NULL) {
/* allocate memory to return secret */
if ((secret->base = malloc(X25519_KEY_SIZE)) == NULL) {
ret = PTLS_ERROR_NO_MEMORY;
goto Exit;
}
uint8_t sk_raw[32];
secret->len = X25519_KEY_SIZE;
/* fetch raw key and derive the secret */
uint8_t sk_raw[X25519_KEY_SIZE];
size_t sk_raw_len = sizeof(sk_raw);
if (EVP_PKEY_get_raw_private_key(ctx->privkey, sk_raw, &sk_raw_len) != 1) {
ret = PTLS_ERROR_LIBRARY;
goto Exit;
}
assert(sk_raw_len == sizeof(sk_raw));
X25519(secret->base, sk_raw, peerkey.base);
ptls_clear_memory(sk_raw, sizeof(sk_raw));
/* check bad key */
static const uint8_t zeros[X25519_KEY_SIZE] = {0};
if (ptls_mem_equal(secret->base, zeros, X25519_KEY_SIZE)) {
ret = PTLS_ERROR_INCOMPATIBLE_KEY;
goto Exit;
}
/* success */
ret = 0;
goto Exit;
}
#undef X25519_KEY_SIZE
#endif

if ((evppeer = EVP_PKEY_new()) == NULL) {
Expand Down Expand Up @@ -595,6 +608,9 @@ static int evp_keyex_on_exchange(ptls_key_exchange_context_t **_ctx, int release
return ret;
}

/**
* Upon success, ownership of `pkey` is transferred to the object being created. Otherwise, the refcount remains unchanged.
*/
static int evp_keyex_init(ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **_ctx, EVP_PKEY *pkey)
{
struct st_evp_keyex_context_t *ctx = NULL;
Expand All @@ -617,8 +633,10 @@ static int evp_keyex_init(ptls_key_exchange_algorithm_t *algo, ptls_key_exchange
*_ctx = &ctx->super;
ret = 0;
Exit:
if (ret != 0 && ctx != NULL)
if (ret != 0 && ctx != NULL) {
ctx->privkey = NULL; /* do not decrement refcount of pkey in case of error */
evp_keyex_free(ctx);
}
return ret;
}

Expand Down
18 changes: 12 additions & 6 deletions lib/picotls.c
Original file line number Diff line number Diff line change
Expand Up @@ -2373,7 +2373,10 @@ static int send_client_hello(ptls_t *tls, ptls_message_emitter_t *emitter, ptls_

/* initialize key schedule */
if (!is_second_flight) {
tls->key_schedule = key_schedule_new(tls->cipher_suite, tls->ctx->cipher_suites, tls->ech.aead != NULL);
if ((tls->key_schedule = key_schedule_new(tls->cipher_suite, tls->ctx->cipher_suites, tls->ech.aead != NULL)) == NULL) {
ret = PTLS_ERROR_NO_MEMORY;
goto Exit;
}
if ((ret = key_schedule_extract(tls->key_schedule, resumption_secret)) != 0)
goto Exit;
}
Expand Down Expand Up @@ -3570,10 +3573,10 @@ static int decode_client_hello(ptls_context_t *ctx, struct st_ptls_client_hello_
src = end;
});

/* CH defined in TLS versions below 1.2 might not have extensions (or they might, see what OpenSSL 1.0.0 sends); so bail out
* after parsing the main variables. Zero is returned as it is a valid ClientHello. However `ptls_t::selected_version` remains
* zero indicating that no compatible version were found. */
if (ch->legacy_version < 0x0303 && src == end) {
/* In TLS versions 1.2 and earlier CH might not have an extensions block (or they might, see what OpenSSL 1.0.0 sends); so bail
* out if that is the case after parsing the main variables. Zero is returned as it is a valid ClientHello. However
* `ptls_t::selected_version` remains zero indicating that no compatible version were found. */
if (src == end) {
ret = 0;
goto Exit;
}
Expand Down Expand Up @@ -4366,7 +4369,10 @@ static int server_handle_hello(ptls_t *tls, ptls_message_emitter_t *emitter, ptl
goto Exit;
if (!is_second_flight) {
tls->cipher_suite = cs;
tls->key_schedule = key_schedule_new(cs, NULL, 0);
if ((tls->key_schedule = key_schedule_new(cs, NULL, 0)) == NULL) {
ret = PTLS_ERROR_NO_MEMORY;
goto Exit;
}
} else {
if (tls->cipher_suite != cs) {
ret = PTLS_ALERT_HANDSHAKE_FAILURE;
Expand Down
4 changes: 3 additions & 1 deletion picotls.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@
081F00CD291A358800534A86 /* pembase64.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pembase64.h; sourceTree = "<group>"; };
081F00CE291A358800534A86 /* ptlsbcrypt.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ptlsbcrypt.h; sourceTree = "<group>"; };
087F1A732B034AEB00E81AC1 /* FindMbedTLS.cmake */ = {isa = PBXFileReference; lastKnownFileType = text; path = FindMbedTLS.cmake; sourceTree = "<group>"; };
0883D3272AEF8F2500B711CC /* fusion.cmake */ = {isa = PBXFileReference; lastKnownFileType = text; path = fusion.cmake; sourceTree = "<group>"; };
0883D32A2AF601A700B711CC /* mbedtls.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mbedtls.c; sourceTree = "<group>"; };
0883D32B2AF601B900B711CC /* mbedtls.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mbedtls.c; sourceTree = "<group>"; };
0883D32C2AF601CB00B711CC /* mbedtls.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mbedtls.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -533,9 +534,10 @@
E95EBCC9227E9FF30022C32D /* cmake */ = {
isa = PBXGroup;
children = (
087F1A732B034AEB00E81AC1 /* FindMbedTLS.cmake */,
08A835EB2996971300D872CE /* boringssl-adjust.cmake */,
E95EBCCA227EA0180022C32D /* dtrace-utils.cmake */,
087F1A732B034AEB00E81AC1 /* FindMbedTLS.cmake */,
0883D3272AEF8F2500B711CC /* fusion.cmake */,
);
path = cmake;
sourceTree = "<group>";
Expand Down
21 changes: 21 additions & 0 deletions t/picotls.c
Original file line number Diff line number Diff line change
Expand Up @@ -2022,6 +2022,13 @@ static void test_legacy_ch(void)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x05, 0x00, 0x2f, 0x00, 0x33, 0x00, 0x32, 0x00, 0x0a, 0x00, 0x16,
0x00, 0x13, 0x00, 0x09, 0x00, 0x15, 0x00, 0x12, 0x00, 0x03, 0x00, 0x08, 0x00, 0x14, 0x00, 0x11, 0x00, 0xff, 0x01, 0x00};
static const uint8_t tls12_no_exts[] = {
0x16, 0x03, 0x01, 0x00, 0x67, 0x01, 0x00, 0x00, 0x63, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xee, 0x8a, 0x29, 0xdd, 0xcf, 0x6d, 0x64, 0xfd, 0xd0, 0xcd,
0xa0, 0x9b, 0xc1, 0x32, 0x46, 0xbf, 0x53, 0xda, 0x29, 0x23, 0x81, 0x5f, 0x54, 0x1f, 0xbd, 0xe0, 0x8e, 0x97,
0x17, 0x5b, 0x03, 0x5d, 0x00, 0x1c, 0x00, 0xff, 0x00, 0x9c, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x0a, 0xc0, 0x09,
0xc0, 0x13, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x9e, 0x00, 0x33, 0x00, 0x39, 0x00, 0x0a, 0x01, 0x00};
/* client hello generated by openssl 1.0.0s; s_client -bugs -no_ticket -cipher DES-CBC-SHA -connect */
static const uint8_t tls10_with_exts[] = {0x16, 0x03, 0x01, 0x00, 0x2f, 0x01, 0x00, 0x00, 0x2b, 0x03, 0x01, 0x63, 0xfc,
0x5a, 0x16, 0xde, 0x7a, 0xfc, 0xc1, 0x0c, 0x54, 0x12, 0xa6, 0xd3, 0x8c, 0xcf,
Expand Down Expand Up @@ -2083,6 +2090,14 @@ static void test_legacy_ch(void)
free(legacy_params);
legacy_params = NULL;

tls = ptls_new(ctx, 1);
len = sizeof(tls12_no_exts);
ret = ptls_handshake(tls, &sendbuf, tls12_no_exts, &len, NULL);
ptls_free(tls);
ok(ret == PTLS_ALERT_PROTOCOL_VERSION);
free(legacy_params);
legacy_params = NULL;

tls = ptls_new(ctx, 1);
len = sizeof(tls10_with_exts);
ret = ptls_handshake(tls, &sendbuf, tls10_with_exts, &len, NULL);
Expand Down Expand Up @@ -2184,4 +2199,10 @@ void test_key_exchange(ptls_key_exchange_algorithm_t *client, ptls_key_exchange_
ret = ctx->on_exchange(&ctx, 1, NULL, ptls_iovec_init(NULL, 0));
ok(ret == 0);
ok(ctx == NULL);

/* test derivation failure. In case of X25519, the outcome is derived key becoming all-zero and rejected. In case of others, it
* is most likely that the provided key would be rejected. */
static uint8_t zeros[32] = {0};
ret = server->exchange(server, &server_pubkey, &server_secret, ptls_iovec_init(zeros, sizeof(zeros)));
ok(ret != 0);
}

0 comments on commit 762afbb

Please sign in to comment.