From 52c2797104dbb2aafd847664f1935676ac9b32c1 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 10:39:27 -0700 Subject: [PATCH 01/84] Incorporate mbedtls in cmake --- CMakeLists.txt | 20 ++ cmake/FindMbedTLS.cmake | 15 + include/picotls/ptls_mbedtls.h | 42 +++ lib/ptls_mbedtls.c | 586 +++++++++++++++++++++++++++++++++ t/ptls_mbedtls.c | 349 ++++++++++++++++++++ 5 files changed, 1012 insertions(+) create mode 100644 cmake/FindMbedTLS.cmake create mode 100644 include/picotls/ptls_mbedtls.h create mode 100644 lib/ptls_mbedtls.c create mode 100644 t/ptls_mbedtls.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 42692a520..bec745882 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ IF (WITH_FUSION) MESSAGE(STATUS "Enabling 'fusion' AES-GCM engine") ENDIF () OPTION(WITH_AEGIS "enable AEGIS (requires libaegis)" ${WITH_AEGIS}) +OPTION(WITH_MBEDTLS "enable MBEDTLS" ${WITH_MBEDTLS}) SET(CMAKE_C_FLAGS "-std=c99 -Wall -O2 -g ${CC_WARNING_FLAGS} ${CMAKE_C_FLAGS}") INCLUDE_DIRECTORIES( @@ -199,6 +200,25 @@ IF (WITH_FUSION) LIST(APPEND PTLSBENCH_LIBS picotls-fusion) ENDIF () +IF (WITH_MBEDTLS) + FIND_PACKAGE(MbedTLS) + IF (NOT MbedTLS) + MESSAGE (FATAL_ERROR "MbedTLS not found") + ELSE () + message(STATUS "mbedtls/include: ${MBEDTLS_INCLUDE_DIRS}") + message(STATUS "mbedtls libraries: ${MBEDTLS_LIBRARIES}") + INCLUDE_DIRECTORIES(${MBEDTLS_INCLUDE_DIRS}) + ADD_LIBRARY(picotls-mbedtls lib/ptls_mbedtls.c) + ADD_EXECUTABLE(test-mbedtls.t + deps/picotest/picotest.c + lib/picotls.c + t/ptls_mbedtls.c) + TARGET_LINK_LIBRARIES(test-mbedtls.t + picotls-minicrypto picotls-mbedtls + ${MBEDTLS_LIBRARIES}) + ENDIF() +ENDIF () + ADD_EXECUTABLE(ptlsbench t/ptlsbench.c) SET_TARGET_PROPERTIES(ptlsbench PROPERTIES COMPILE_FLAGS "-DPTLS_MEMORY_DEBUG=1") TARGET_LINK_LIBRARIES(ptlsbench ${PTLSBENCH_LIBS}) diff --git a/cmake/FindMbedTLS.cmake b/cmake/FindMbedTLS.cmake new file mode 100644 index 000000000..2bddc77e1 --- /dev/null +++ b/cmake/FindMbedTLS.cmake @@ -0,0 +1,15 @@ +# - Try to find MbedTLS +# set(MBEDTLS_LIBRARY mbedtls) +# set(MBEDTLS_INCLUDE_DIRS ${MBEDTLS_SOURCE_DIR}/include) +find_path(MBEDTLS_INCLUDE_DIRS + NAMES mbedtls/build_info.h psa/crypto.h + HINTS ${MBEDTLS_PREFIX}/include/ + ${CMAKE_SOURCE_DIR}/../mbedtls/include/ + ${CMAKE_BINARY_DIR}/../mbedtls/include/ + ../mbedtls/include/ ) + +set(MBEDTLS_HINTS ${MBEDTLS_PREFIX}/build ${CMAKE_BINARY_DIR}/../mbedtls/build ../mbedtls/build) + +find_library(MBEDTLS_LIBRARY mbedtls HINTS ${MBEDTLS_HINTS}) + +mark_as_advanced(MBEDTLS_LIBRARY MBEDTLS_INCLUDE_DIRS) diff --git a/include/picotls/ptls_mbedtls.h b/include/picotls/ptls_mbedtls.h new file mode 100644 index 000000000..18f67370e --- /dev/null +++ b/include/picotls/ptls_mbedtls.h @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2023, Christian Huitema +* +* 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 picotls_mbedtls_h +#define picotls_mbedtls_h + +#ifdef __cplusplus +extern "C" { +#endif +#include "picotls.h" + +extern ptls_hash_algorithm_t ptls_mbedtls_sha256; + +extern ptls_cipher_algorithm_t ptls_mbedtls_aes128ecb; +extern ptls_cipher_algorithm_t ptls_mbedtls_aes256ecb; +extern ptls_cipher_algorithm_t ptls_mbedtls_aes128ctr; +extern ptls_cipher_algorithm_t ptls_mbedtls_aes256ctr; + +extern ptls_aead_algorithm_t ptls_mbedtls_aes128gcm; + +#ifdef __cplusplus +} +#endif +#endif /* picotls_mbedtls_h */ \ No newline at end of file diff --git a/lib/ptls_mbedtls.c b/lib/ptls_mbedtls.c new file mode 100644 index 000000000..6c2bf82b6 --- /dev/null +++ b/lib/ptls_mbedtls.c @@ -0,0 +1,586 @@ +#ifdef _WINDOWS +#include "wincompat.h" +#endif + +#include +#include +#include +#include +#include "mbedtls/build_info.h" +#include "psa/crypto.h" +#include "psa/crypto_struct.h" +#include "mbedtls/sha256.h" +#include "mbedtls/aes.h" + +/* Definitions for hash algorithms. +* In Picotls, these are described by the stucture +* ptls_hash_algorithm_t, which include the function +* pointer for creation of the hash context. +* +* The structure contains a function pointer to the +* "create" function that creates a hash operation, +* which itself contains three function pointers: +* +* void (*update)(struct st_ptls_hash_context_t *ctx, const void *src, size_t len); +* void (*final)(struct st_ptls_hash_context_t *ctx, void *md, ptls_hash_final_mode_t mode); +* struct st_ptls_hash_context_t *(*clone_)(struct st_ptls_hash_context_t *src); +* +* TODO: develop shim for other hash methods besides SHA256 +*/ + +typedef struct st_ptls_mbedtls_sha256_ctx_t { + ptls_hash_context_t super; + mbedtls_sha256_context mctx; +} ptls_mbedtls_sha256_ctx_t; + +static void ptls_mbedtls_sha256_update(struct st_ptls_hash_context_t* _ctx, const void* src, size_t len) +{ + ptls_mbedtls_sha256_ctx_t* ctx = (ptls_mbedtls_sha256_ctx_t*)_ctx; + + (void)mbedtls_sha256_update(&ctx->mctx, (const uint8_t*)src, len); +} + +static void ptls_mbedtls_sha256_final(struct st_ptls_hash_context_t* _ctx, void* md, ptls_hash_final_mode_t mode); + +static struct st_ptls_hash_context_t* ptls_mbedtls_sha256_clone(struct st_ptls_hash_context_t* _src) +{ + ptls_mbedtls_sha256_ctx_t* ctx = (ptls_mbedtls_sha256_ctx_t*)malloc(sizeof(ptls_mbedtls_sha256_ctx_t)); + + if (ctx != NULL) { + ptls_mbedtls_sha256_ctx_t* src = (ptls_mbedtls_sha256_ctx_t*)_src; + memset(&ctx->mctx, 0, sizeof(mbedtls_sha256_context)); + ctx->super.clone_ = ptls_mbedtls_sha256_clone; + ctx->super.update = ptls_mbedtls_sha256_update; + ctx->super.final = ptls_mbedtls_sha256_final; + mbedtls_sha256_clone(&ctx->mctx, &src->mctx); + } + return (ptls_hash_context_t*)ctx; +} + +static void ptls_mbedtls_sha256_final(struct st_ptls_hash_context_t* _ctx, void* md, ptls_hash_final_mode_t mode) +{ + ptls_mbedtls_sha256_ctx_t* ctx = (ptls_mbedtls_sha256_ctx_t*)_ctx; + + if (mode == PTLS_HASH_FINAL_MODE_SNAPSHOT) { + struct st_ptls_hash_context_t* cloned = ptls_mbedtls_sha256_clone(_ctx); + + if (cloned != NULL) { + ptls_mbedtls_sha256_final(cloned, md, PTLS_HASH_FINAL_MODE_FREE); + } + } else { + if (md != NULL) { + (void)mbedtls_sha256_finish(&ctx->mctx, (uint8_t*)md); + } + + if (mode == PTLS_HASH_FINAL_MODE_FREE) { + mbedtls_sha256_free(&ctx->mctx); + free(ctx); + } + else { + /* if mode = reset, reset the context */ + mbedtls_sha256_init(&ctx->mctx); + mbedtls_sha256_starts(&ctx->mctx, 0 /* is224 = 0 */); + } + } +} + +ptls_hash_context_t* ptls_mbedtls_sha256_create(void) +{ + ptls_mbedtls_sha256_ctx_t* ctx = (ptls_mbedtls_sha256_ctx_t*)malloc(sizeof(ptls_mbedtls_sha256_ctx_t)); + + if (ctx != NULL) { + memset(&ctx->mctx, 0, sizeof(mbedtls_sha256_context)); + ctx->super.clone_ = ptls_mbedtls_sha256_clone; + ctx->super.update = ptls_mbedtls_sha256_update; + ctx->super.final = ptls_mbedtls_sha256_final; + if (mbedtls_sha256_starts(&ctx->mctx, 0 /* is224 = 0 */) != 0) { + free(ctx); + ctx = NULL; + } + } + return (ptls_hash_context_t*)ctx; +} + +ptls_hash_algorithm_t ptls_mbedtls_sha256 = {"sha256", PTLS_SHA256_BLOCK_SIZE, PTLS_SHA256_DIGEST_SIZE, ptls_mbedtls_sha256_create, +PTLS_ZERO_DIGEST_SHA256}; + + +/* definitions for symmetric crypto algorithms. +* Each algorithm (ECB or CTR) is represented by an "algorithm" +* entry in which the 'setup" function is used to initialize +* The "setup" function creates an object of type +* ptls_cipher_context_t, with three function pointers: +* +* void (*do_dispose)(struct st_ptls_cipher_context_t *ctx); +* void (*do_init)(struct st_ptls_cipher_context_t *ctx, const void *iv); +* void (*do_transform)(struct st_ptls_cipher_context_t *ctx, void *output, const void *input, size_t len); +* +* "do_init" sets the IV value. In CTR mode, this is the nonce value, which +* will be incremented after each block. In CTR mode, this also sets the +* "stream block". +* + */ +struct ptls_mbedtls_symmetric_param_t { + uint8_t iv[PTLS_MAX_IV_SIZE]; + uint8_t *key_object; + int is_enc; +}; + +struct st_ptls_mbedtls_aes_context_t { + ptls_cipher_context_t super; + mbedtls_aes_context aes_ctx; + uint8_t nonce_counter[16]; + uint8_t stream_block[16]; + int is_enc; /* MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT */ +}; + +static void ptls_mbedtls_aes_ctr_init(ptls_cipher_context_t *_ctx, const void *iv) +{ + struct st_ptls_mbedtls_aes_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; + + if (iv == NULL) { + memset(ctx->nonce_counter, 0, 16); + } + else { + memcpy(ctx->nonce_counter, iv, 16); + } + memset(ctx->stream_block, 0, 16); +} + +static void ptls_mbedtls_aes_ecb_transform(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t len) +{ + struct st_ptls_mbedtls_aes_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; + + /* Call the encryption */ + if (mbedtls_aes_crypt_ecb(&ctx->aes_ctx, ctx->is_enc, (const uint8_t*)input, (uint8_t*)output) != 0) { + memset(output, 0, len); + } +} + +static void ptls_mbedtls_aes_ctr_transform(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t len) +{ + struct st_ptls_mbedtls_aes_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; + size_t nc_off = 0; + + if (mbedtls_aes_crypt_ctr(&ctx->aes_ctx, len, &nc_off, ctx->nonce_counter, ctx->stream_block, + (const uint8_t*)input, (uint8_t*)output) != 0) { + memset(output, 0, len); + } +} + +static void ptls_mbedtls_aes_ctr_dispose(ptls_cipher_context_t *_ctx) +{ + struct st_ptls_mbedtls_aes_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; + mbedtls_aes_free(&ctx->aes_ctx); +} + +static int ptls_mbedtls_cipher_setup_crypto_aes(ptls_cipher_context_t* _ctx, int is_enc, const void* key, unsigned int keybits) +{ + struct st_ptls_mbedtls_aes_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; + int ret = 0; + + memset(ctx->nonce_counter, 0, 16); + memset(ctx->stream_block, 0, 16); + + ctx->super.do_dispose = ptls_mbedtls_aes_ctr_dispose; + ctx->super.do_init = ptls_mbedtls_aes_ctr_init; + ctx->super.do_transform = NULL; + + mbedtls_aes_init(&ctx->aes_ctx); + if (is_enc) { + ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, key, keybits); + ctx->is_enc = MBEDTLS_AES_ENCRYPT; + } + else { + ret = mbedtls_aes_setkey_dec(&ctx->aes_ctx, key, keybits); + ctx->is_enc = MBEDTLS_AES_DECRYPT; + } + + return ret; + +} + +static int ptls_mbedtls_cipher_setup_crypto_aes128_ecb(ptls_cipher_context_t *_ctx, int is_enc, const void *key) +{ + struct st_ptls_mbedtls_aes_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; + int ret = ptls_mbedtls_cipher_setup_crypto_aes(_ctx, is_enc, key, 128); + + if (ret == 0) { + ctx->super.do_transform = ptls_mbedtls_aes_ecb_transform; + } + + return ret; +} + +static int ptls_mbedtls_cipher_setup_crypto_aes128_ctr(ptls_cipher_context_t *_ctx, int is_enc, const void *key) +{ +#ifdef _WINDOWS + UNREFERENCED_PARAMETER(is_enc); +#endif + struct st_ptls_mbedtls_aes_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; + int ret = ptls_mbedtls_cipher_setup_crypto_aes(_ctx, 1, key, 128); /* No difference between CTR encrypt and decrypt */ + + if (ret == 0) { + ctx->super.do_transform = ptls_mbedtls_aes_ctr_transform; + } + + return ret; +} + + +static int ptls_mbedtls_cipher_setup_crypto_aes256_ecb(ptls_cipher_context_t *_ctx, int is_enc, const void *key) +{ + struct st_ptls_mbedtls_aes_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; + int ret = ptls_mbedtls_cipher_setup_crypto_aes(_ctx, is_enc, key, 256); + + if (ret == 0) { + ctx->super.do_transform = ptls_mbedtls_aes_ecb_transform; + } + + return ret; +} + +static int ptls_mbedtls_cipher_setup_crypto_aes256_ctr(ptls_cipher_context_t *_ctx, int is_enc, const void *key) +{ +#ifdef _WINDOWS + UNREFERENCED_PARAMETER(is_enc); +#endif + struct st_ptls_mbedtls_aes_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; + int ret = ptls_mbedtls_cipher_setup_crypto_aes(_ctx, 1, key, 256); /* No difference between CTR encrypt and decrypt */ + + if (ret == 0) { + ctx->super.do_transform = ptls_mbedtls_aes_ctr_transform; + } + + return ret; +} + +ptls_cipher_algorithm_t ptls_mbedtls_aes128ecb = { + "AES128-ECB", + PTLS_AES128_KEY_SIZE, + PTLS_AES_BLOCK_SIZE, + 0 /* iv size */, + sizeof(struct st_ptls_mbedtls_aes_context_t), + ptls_mbedtls_cipher_setup_crypto_aes128_ecb}; + +ptls_cipher_algorithm_t ptls_mbedtls_aes256ecb = {"AES256-ECB", +PTLS_AES256_KEY_SIZE, +PTLS_AES_BLOCK_SIZE, +0 /* iv size */, +sizeof(struct st_ptls_mbedtls_aes_context_t), +ptls_mbedtls_cipher_setup_crypto_aes256_ecb}; + +ptls_cipher_algorithm_t ptls_mbedtls_aes128ctr = {"AES128-CTR", +PTLS_AES128_KEY_SIZE, +PTLS_AES_BLOCK_SIZE, +0 /* iv size */, +sizeof(struct st_ptls_mbedtls_aes_context_t), +ptls_mbedtls_cipher_setup_crypto_aes128_ctr}; + +ptls_cipher_algorithm_t ptls_mbedtls_aes256ctr = {"AES256-CTR", +PTLS_AES256_KEY_SIZE, +PTLS_AES_BLOCK_SIZE, +0 /* iv size */, +sizeof(struct st_ptls_mbedtls_aes_context_t), +ptls_mbedtls_cipher_setup_crypto_aes256_ctr}; + +/* Definitions of AEAD algorithms. +* +* For the picotls API, AEAD algorithms are created by calling: +* +* ptls_aead_context_t *ptls_aead_new(ptls_aead_algorithm_t *aead, +* ptls_hash_algorithm_t *hash, int is_enc, const void *secret, +* const char *label_prefix) +* That procedure will allocate memory and create keys, and then call +* a provider specific function: +* +* if (aead->setup_crypto(ctx, is_enc, key, iv) != 0) { +* free(ctx); +* return NULL; +* } +* +* The function will finish completing the aead structure, perform +* initialization, and then document the function pointers: +* +* ctx->super.dispose_crypto: release all resourc +* ctx->super.do_get_iv: return IV +* ctx->super.do_set_iv: set IV value +* ctx->super.do_decrypt: decrypt function +* ctx->super.do_encrypt_init: start encrypting one message +* ctx->super.do_encrypt_update: feed more ciphertext to descriptor +* ctx->super.do_encrypt_final: finalize encryption, including AEAD checksum +* ctx->super.do_encrypt: single shot variant of init/update/final +* ctx->super.do_encrypt_v: scatter gather version of do encrypt +* +* The aead context also documents the underlying "ECB" and "CTR" modes. +* In QUIC, these are used for PN encryption. +* +* TODO: declare other lagorithms besides AES128_GCM +*/ + +struct ptls_mbedtls_aead_param_t { + uint8_t static_iv[PTLS_MAX_IV_SIZE]; + psa_algorithm_t alg; + psa_key_id_t key; + psa_aead_operation_t op; + size_t extra_bytes; + int is_op_in_progress; +}; + +struct ptls_mbedtls_aead_context_t { + struct st_ptls_aead_context_t super; + struct ptls_mbedtls_aead_param_t mctx; +}; + +void ptls_mbedtls_aead_dispose_crypto(struct st_ptls_aead_context_t* _ctx) +{ + struct ptls_mbedtls_aead_context_t* ctx = + (struct ptls_mbedtls_aead_context_t*)_ctx; + if (ctx->mctx.is_op_in_progress) { + psa_aead_abort(&ctx->mctx.op); + ctx->mctx.is_op_in_progress = 0; + } + psa_destroy_key(ctx->mctx.key); +} + + +static void ptls_mbedtls_aead_get_iv(ptls_aead_context_t *_ctx, void *iv) +{ + struct ptls_mbedtls_aead_context_t* ctx = + (struct ptls_mbedtls_aead_context_t*)_ctx; + + memcpy(iv, ctx->mctx.static_iv, ctx->super.algo->iv_size); +} + +static void ptls_mbedtls_aead_set_iv(ptls_aead_context_t *_ctx, const void *iv) +{ + struct ptls_mbedtls_aead_context_t* ctx = + (struct ptls_mbedtls_aead_context_t*)_ctx; + + memcpy(ctx->mctx.static_iv, iv, ctx->super.algo->iv_size); +} + +void ptls_mbedtls_aead_do_encrypt_init(struct st_ptls_aead_context_t* _ctx, uint64_t seq, const void* aad, size_t aadlen) +{ + struct ptls_mbedtls_aead_context_t* ctx = + (struct ptls_mbedtls_aead_context_t*)_ctx; + psa_status_t status; + + if (ctx->mctx.is_op_in_progress) { + psa_aead_abort(&ctx->mctx.op); /* required on errors, harmless on success */ + ctx->mctx.is_op_in_progress = 0; + } + + ctx->mctx.is_op_in_progress = 1; + memset(&ctx->mctx.op, 0, sizeof(ctx->mctx.op)); + + status = psa_aead_encrypt_setup(&ctx->mctx.op, ctx->mctx.key, ctx->mctx.alg); + + if (status == PSA_SUCCESS) { + /* set the nonce. */ + uint8_t iv[PTLS_MAX_IV_SIZE]; + ptls_aead__build_iv(ctx->super.algo, iv, ctx->mctx.static_iv, seq); + status = psa_aead_set_nonce(&ctx->mctx.op, iv, ctx->super.algo->iv_size); + } + + if (status == PSA_SUCCESS) { + status = psa_aead_update_ad(&ctx->mctx.op, aad, aadlen); + } + + if (status != PSA_SUCCESS) { + psa_aead_abort(&ctx->mctx.op); /* required on errors, harmless on success */ + ctx->mctx.is_op_in_progress = 0; + } +} + +size_t ptls_mbedtls_aead_do_encrypt_update(struct st_ptls_aead_context_t* _ctx, void* output, const void* input, size_t inlen) +{ + size_t olen = 0; + struct ptls_mbedtls_aead_context_t* ctx = + (struct ptls_mbedtls_aead_context_t*)_ctx; + + if (ctx->mctx.is_op_in_progress) { + size_t available = inlen + ctx->mctx.extra_bytes; + psa_status_t status = psa_aead_update(&ctx->mctx.op, input, inlen, (uint8_t *)output, available + ctx->super.algo->tag_size, &olen); + + if (status == PSA_SUCCESS) { + if (olen < available) { + ctx->mctx.extra_bytes = available - olen; + } + else { + ctx->mctx.extra_bytes = 0; + } + } + else { + psa_aead_abort(&ctx->mctx.op); /* required on errors */ + ctx->mctx.is_op_in_progress = 0; + } + } + + return olen; +} + +size_t ptls_mbedtls_aead_do_encrypt_final(struct st_ptls_aead_context_t* _ctx, void* output) +{ + size_t olen = 0; + struct ptls_mbedtls_aead_context_t* ctx = + (struct ptls_mbedtls_aead_context_t*)_ctx; + + if (ctx->mctx.is_op_in_progress) { + unsigned char tag[PSA_AEAD_TAG_MAX_SIZE]; + size_t olen_tag = 0; + size_t available = ctx->mctx.extra_bytes; + uint8_t* p = (uint8_t*)output; + psa_status_t status = psa_aead_finish(&ctx->mctx.op, p, available + ctx->super.algo->tag_size, &olen, + tag, sizeof(tag), &olen_tag); + + if (status == PSA_SUCCESS) { + p += olen; + memcpy(p, tag, ctx->super.algo->tag_size); + olen += ctx->super.algo->tag_size; + } + else { + psa_aead_abort(&ctx->mctx.op); /* required on errors */ + } + ctx->mctx.is_op_in_progress = 0; + } + + return(olen); +} + +void ptls_mbedtls_aead_do_encrypt_v(struct st_ptls_aead_context_t* _ctx, void* output, ptls_iovec_t* input, size_t incnt, uint64_t seq, + const void* aad, size_t aadlen) +{ + unsigned char* p = (uint8_t*)output; + + ptls_mbedtls_aead_do_encrypt_init(_ctx, seq, aad, aadlen); + + for (size_t i = 0; i < incnt; i++) { + p += ptls_mbedtls_aead_do_encrypt_update(_ctx, p, input[i].base, input[i].len); + } + + (void)ptls_mbedtls_aead_do_encrypt_final(_ctx, p); +} + +void ptls_mbedtls_aead_do_encrypt(struct st_ptls_aead_context_t* _ctx, void* output, const void* input, size_t inlen, uint64_t seq, + const void* aad, size_t aadlen, ptls_aead_supplementary_encryption_t* supp) +{ + ptls_iovec_t in_v; + in_v.base = (uint8_t*)input; + in_v.len = inlen; + + ptls_mbedtls_aead_do_encrypt_v(_ctx, output, &in_v, 1, seq, aad, aadlen); +} + +size_t ptls_mbedtls_aead_do_decrypt(struct st_ptls_aead_context_t* _ctx, void* output, const void* input, size_t inlen, uint64_t seq, + const void* aad, size_t aadlen) +{ + size_t o_len = 0; + uint8_t iv[PTLS_MAX_IV_SIZE]; + struct ptls_mbedtls_aead_context_t* ctx = + (struct ptls_mbedtls_aead_context_t*)_ctx; + psa_status_t status; + /* set the nonce. */ + ptls_aead__build_iv(ctx->super.algo, iv, ctx->mctx.static_iv, seq); + + status = psa_aead_decrypt(ctx->mctx.key, ctx->mctx.alg, iv, ctx->super.algo->iv_size, (uint8_t*)aad, aadlen, + (uint8_t*)input, inlen, (uint8_t*)output, inlen, &o_len); + if (status != PSA_SUCCESS) { + o_len = inlen + 1; + } + return o_len; +} + +static int ptls_mbedtls_aead_setup_crypto(ptls_aead_context_t *_ctx, int is_enc, const void *key_bytes, const void *iv) +{ + int ret = 0; + struct ptls_mbedtls_aead_context_t* ctx = + (struct ptls_mbedtls_aead_context_t*)_ctx; + size_t key_bits; + psa_key_type_t key_type; + + /* set mbed specific context to NULL, just to be sure */ + memset(&ctx->mctx, 0, sizeof(struct ptls_mbedtls_aead_param_t)); + + /* deduce the PSA algorithm from the name */ + if (strcmp(ctx->super.algo->name, "AES128-GCM") == 0) { + ctx->mctx.alg = PSA_ALG_GCM; + key_bits = 128; + key_type = PSA_KEY_TYPE_AES; + } else if (strcmp(ctx->super.algo->name, "AES256-GCM") == 0) { + ctx->mctx.alg = PSA_ALG_GCM; + key_bits = 256; + key_type = PSA_KEY_TYPE_AES; + } else if (strcmp(ctx->super.algo->name, "AES128-GCM_8") == 0) { + ctx->mctx.alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 8); + key_bits = 128; + key_type = PSA_KEY_TYPE_AES; + } else if (strcmp(ctx->super.algo->name, "CHACHA20-POLY1305") == 0) { + ctx->mctx.alg = PSA_ALG_CHACHA20_POLY1305; + key_bits = 256; + key_type = PSA_KEY_TYPE_CHACHA20; + } else { + ret = PTLS_ERROR_LIBRARY; + } + + /* Initialize the key attributes */ + if (ret == 0) { + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, + (is_enc)?PSA_KEY_USAGE_ENCRYPT:PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, ctx->mctx.alg); + psa_set_key_type(&attributes, key_type); + psa_set_key_bits(&attributes, key_bits); + /* Import key */ + if (psa_import_key(&attributes, key_bytes, key_bits / 8, + &ctx->mctx.key) != PSA_SUCCESS) { + ret = PTLS_ERROR_LIBRARY; + } + } + + if (ret == 0) { + /* Store the static IV */ + if (ctx->super.algo->iv_size > PTLS_MAX_IV_SIZE) { + ret = PTLS_ERROR_LIBRARY; + } + else { + memcpy(ctx->mctx.static_iv, iv, ctx->super.algo->iv_size); + ctx->mctx.is_op_in_progress = 0; + } + } + + /* set the pointers to the individual functions */ + if (ret == 0) { + if (is_enc) { + ctx->super.do_encrypt_init = ptls_mbedtls_aead_do_encrypt_init; + ctx->super.do_encrypt_update = ptls_mbedtls_aead_do_encrypt_update; + ctx->super.do_encrypt_final = ptls_mbedtls_aead_do_encrypt_final; + ctx->super.do_encrypt = ptls_mbedtls_aead_do_encrypt; + ctx->super.do_encrypt_v = ptls_mbedtls_aead_do_encrypt_v; + } + else { + ctx->super.do_decrypt = ptls_mbedtls_aead_do_decrypt; + } + ctx->super.dispose_crypto = ptls_mbedtls_aead_dispose_crypto; + ctx->super.do_get_iv = ptls_mbedtls_aead_get_iv; + ctx->super.do_set_iv = ptls_mbedtls_aead_set_iv; + } + + return ret; +} + +ptls_aead_algorithm_t ptls_mbedtls_aes128gcm = { + "AES128-GCM", + PTLS_AESGCM_CONFIDENTIALITY_LIMIT, + PTLS_AESGCM_INTEGRITY_LIMIT, + &ptls_mbedtls_aes128ecb, + &ptls_mbedtls_aes128ctr, + PTLS_AES128_KEY_SIZE, + PTLS_AESGCM_IV_SIZE, + PTLS_AESGCM_TAG_SIZE, + {PTLS_TLS12_AESGCM_FIXED_IV_SIZE, PTLS_TLS12_AESGCM_RECORD_IV_SIZE}, + 0, + 0, + sizeof(struct ptls_mbedtls_aead_context_t), + ptls_mbedtls_aead_setup_crypto +}; diff --git a/t/ptls_mbedtls.c b/t/ptls_mbedtls.c new file mode 100644 index 000000000..2b14e92f6 --- /dev/null +++ b/t/ptls_mbedtls.c @@ -0,0 +1,349 @@ +/* +* Copyright (c) 2023, Christian Huitema +* +* 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 _WINDOWS +#include "wincompat.h" +#endif + +#include +#include +#include +#include +#include +#include "mbedtls/build_info.h" +#include "psa/crypto.h" +#include "psa/crypto_struct.h" +#include "picotls/ptls_mbedtls.h" +#include "picotls/minicrypto.h" +#include "../deps/picotest/picotest.h" + +static int hash_trial(ptls_hash_algorithm_t* algo, const uint8_t* input, size_t len1, size_t len2, uint8_t* final_hash) +{ + int ret = 0; + ptls_hash_context_t* hash_ctx = algo->create(); + + hash_ctx->update(hash_ctx, input, len1); + if (len2 > 0) { + hash_ctx->update(hash_ctx, input + len1, len2); + } + hash_ctx->final(hash_ctx, final_hash, PTLS_HASH_FINAL_MODE_FREE); + + return ret; +} + +static int hash_reset_trial(ptls_hash_algorithm_t* algo, const uint8_t* input, size_t len1, size_t len2, + uint8_t* hash1, uint8_t* hash2) +{ + int ret = 0; + ptls_hash_context_t* hash_ctx = algo->create(); + + hash_ctx->update(hash_ctx, input, len1); + hash_ctx->final(hash_ctx, hash1, PTLS_HASH_FINAL_MODE_RESET); + hash_ctx->update(hash_ctx, input + len1, len2); + hash_ctx->final(hash_ctx, hash2, PTLS_HASH_FINAL_MODE_FREE); + + return ret; +} + +static int test_hash(ptls_hash_algorithm_t* algo, ptls_hash_algorithm_t* ref) +{ + int ret = 0; + uint8_t input[1234]; + uint8_t final_hash[32]; + uint8_t final_ref[32]; + uint8_t hash1[32], hash2[32], href1[32], href2[32]; + + memset(input, 0xba, sizeof(input)); + + ret = hash_trial(algo, input, sizeof(input), 0, final_hash); + if (ret == 0) { + ret = hash_trial(ref, input, sizeof(input), 0, final_ref); + } + if (ret == 0) { + if (memcmp(final_hash, final_ref, ref->digest_size) != 0) { + ret = -1; + } + } + if (ret == 0) { + ret = hash_trial(algo, input, sizeof(input) - 17, 17, final_hash); + } + if (ret == 0) { + if (memcmp(final_hash, final_ref, ref->digest_size) != 0) { + ret = -1; + } + } + + if (ret == 0) { + ret = hash_reset_trial(algo, input, sizeof(input) - 126, 126, hash1, hash2); + } + if (ret == 0) { + ret = hash_reset_trial(ref, input, sizeof(input) - 126, 126, href1, href2); + } + if (ret == 0) { + if (memcmp(hash1, href1, ref->digest_size) != 0) { + ret = -1; + } + else if (memcmp(hash2, href2, ref->digest_size) != 0) { + ret = -1; + } + } + + return ret; +} + +static int cipher_trial(ptls_cipher_algorithm_t * cipher, const uint8_t * key, const uint8_t * iv, int is_enc, const uint8_t * v_in, uint8_t * v_out1, uint8_t * v_out2, size_t len) +{ + int ret = 0; + ptls_cipher_context_t* test_cipher = ptls_cipher_new(cipher, is_enc, key); + if (test_cipher == NULL) { + ret = -1; + } else { + if (test_cipher->do_init != NULL) { + ptls_cipher_init(test_cipher, iv); + } + ptls_cipher_encrypt(test_cipher, v_out1, v_in, len); + if (test_cipher->do_init != NULL) { + ptls_cipher_init(test_cipher, iv); + } + ptls_cipher_encrypt(test_cipher, v_out2, v_out1, len); + ptls_cipher_free(test_cipher); + } + + return ret; +} + +static int test_cipher(ptls_cipher_algorithm_t * cipher, ptls_cipher_algorithm_t * cipher_ref) +{ + uint8_t key[32]; + uint8_t iv[16]; + uint8_t v_in[16]; + uint8_t v_out_1a[16], v_out_2a[16], v_out_1b[16], v_out_2b[16], v_out_1d[16], v_out_2d[16]; + int ret = 0; + + /* Set initial values */ + memset(key, 0x55, sizeof(key)); + memset(iv, 0x33, sizeof(iv)); + memset(v_in, 0xaa, sizeof(v_in)); + + /* Encryption test */ + ret = cipher_trial(cipher, key, iv, 1, v_in, v_out_1a, v_out_2a, 16); + if (ret == 0) { + ret = cipher_trial(cipher_ref, key, iv, 1, v_in, v_out_1b, v_out_2b, 16); + } + if (ret == 0) { + if (memcmp(v_out_1a, v_out_1b, 16) != 0) { + ret = -1; + } + else if (memcmp(v_out_2a, v_out_2b, 16) != 0) { + ret = -1; + } + } + /* decryption test */ + if (ret == 0) { + ret = cipher_trial(cipher, key, iv, 0, v_out_2a, v_out_1d, v_out_2d, 16); + } + if (ret == 0) { + if (memcmp(v_out_1a, v_out_1d, 16) != 0) { + ret = -1; + } + else if (memcmp(v_out_2d, v_in, 16) != 0) { + ret = -1; + } + } + + return ret; +} + +static int label_test(ptls_hash_algorithm_t * hash, uint8_t * v_out, size_t o_len, const uint8_t * secret, + char const * label, char const * label_prefix) +{ + uint8_t h_val_v[32]; + ptls_iovec_t h_val = { 0 }; + ptls_iovec_t s_vec = { 0 }; + s_vec.base = (uint8_t *)secret; + s_vec.len = 32; + h_val.base = h_val_v; + h_val.len = 32; + memset(h_val_v, 0, sizeof(h_val_v)); + + ptls_hkdf_expand_label(hash, v_out, o_len, s_vec, label, h_val, label_prefix); + return 0; +} + +static int test_label(ptls_hash_algorithm_t* hash, ptls_hash_algorithm_t* ref) +{ + int ret = 0; + uint8_t v_out[16], v_ref[16]; + uint8_t secret[32]; + char const* label = "label"; + char const* label_prefix = "label_prefix"; + memset(secret, 0x5e, sizeof(secret)); + + ret = label_test(hash, v_out, 16, secret, label, label_prefix); + + if (ret == 0) { + ret = label_test(ref, v_ref, 16, secret, label, label_prefix); + } + + if (ret == 0 && memcmp(v_out, v_ref, 16) != 0) { + ret = -1; + } + + return ret; +} + +static int aead_trial(ptls_aead_algorithm_t * algo, ptls_hash_algorithm_t * hash, const uint8_t * secret, int is_enc, + const uint8_t * v_in, size_t len, uint8_t * aad, size_t aad_len, uint64_t seq, uint8_t * v_out, size_t * o_len) +{ + int ret = 0; + ptls_aead_context_t* aead = ptls_aead_new(algo, hash, is_enc, secret, "test_aead"); + + if (aead == NULL) { + ret = -1; + } + else{ + if (is_enc) { + *o_len = ptls_aead_encrypt(aead, v_out, v_in, len, seq, aad, aad_len); + if (*o_len != len + algo->tag_size) { + ret = -1; + } + } + else { + *o_len = ptls_aead_decrypt(aead, v_out, v_in, len, seq, aad, aad_len); + if (*o_len != len - algo->tag_size) { + ret = -1; + } + } + ptls_aead_free(aead); + } + return ret; +} + +static int test_aead(ptls_aead_algorithm_t* algo, ptls_hash_algorithm_t* hash, ptls_aead_algorithm_t* ref, ptls_hash_algorithm_t* hash_ref) +{ + uint8_t secret[32]; + uint8_t v_in[1234]; + uint8_t aad[17]; + uint8_t v_out_a[1250], v_out_b[1250], v_out_r[1250]; + size_t olen_a, olen_b, olen_r; + uint64_t seq = 12345; + int ret = 0; + + memset(secret, 0x58, sizeof(secret)); + memset(v_in, 0x12, sizeof(v_in)); + memset(aad, 0xaa, sizeof(aad)); + + ret = aead_trial(algo, hash, secret, 1, v_in, sizeof(v_in), aad, sizeof(aad), seq, v_out_a, &olen_a); + if (ret == 0) { + ret = aead_trial(ref, hash_ref, secret, 1, v_in, sizeof(v_in), aad, sizeof(aad), seq, v_out_b, &olen_b); + } + if (ret == 0 && (olen_a != olen_b || memcmp(v_out_a, v_out_b, olen_a) != 0)) { + ret = -1; + } + if (ret == 0) { + ret = aead_trial(ref, hash_ref, secret, 0, v_out_a, olen_a, aad, sizeof(aad), seq, v_out_r, &olen_r); + } + if (ret == 0 && (olen_r != sizeof(v_in) || memcmp(v_in, v_out_r, sizeof(v_in)) != 0)) { + ret = -1; + } + return ret; +} + +static void test_sha256(void) +{ + if (test_hash(&ptls_mbedtls_sha256, &ptls_minicrypto_sha256) != 0) { + ok(!"fail"); + return; + } + ok(!!"success"); +} + +static void test_label_sha256(void) +{ + if (test_label(&ptls_mbedtls_sha256, &ptls_minicrypto_sha256) != 0) { + ok(!"fail"); + return; + } + ok(!!"success"); +} + +static void test_aes128ecb(void) +{ + if (test_cipher(ptls_mbedtls_aes128ecb, ptls_minicrypto_aes128ecb) != 0) { + ok(!"fail"); + } + ok(!!"success"); +} + +static void test_aes128ctr(void) +{ + if (test_cipher(ptls_mbedtls_aes128ctr, ptls_minicrypto_aes128ctr) != 0) { + ok(!"fail"); + } + ok(!!"success"); +} + +static void test_aes256ecb(void) +{ + if (test_cipher(ptls_mbedtls_aes256ecb, ptls_minicrypto_aes256ecb) != 0) { + ok(!"fail"); + } + ok(!!"success"); +} + +static void test_aes256ctr(void) +{ + if (test_cipher(ptls_mbedtls_aes256ctr, ptls_minicrypto_aes2568ctr) != 0) { + ok(!"fail"); + } + ok(!!"success"); +} + +static void test_aes128gcm_sha256(void) +{ + if (test_aead(&ptls_mbedtls_aes128gcm, &ptls_mbedtls_sha256, &ptls_minicrypto_aes128gcm, &ptls_minicrypto_sha256) != 0) { + ok(!"fail"); + } + ok(!!"success"); +} + +int main(int argc, char **argv) +{ + /* Initialize the PSA crypto library. */ + if ((status = psa_crypto_init()) != PSA_SUCCESS) { + note("psa_crypto_init fails."); + return done_testing(); + } + /* Series of test to check consistency between wrapped mbedtls and minicrypto */ + subtest("sha256", test_sha256); + subtest("label_sha256", test_label_sha256); + subtest("aes128ecb", test_aes128ecb); + subtest("aes128ctr", test_aes128ctr); + subtest("aes256ecb", test_aes256ecb); + subtest("aes256ctr", test_aes256ctr); + subtest("aes128gcm_sha256", test_aes128gcm_sha256); + + /* Deinitialize the PSA crypto library. */ + mbedtls_psa_crypto_free(); + + return done_testing(); +} From aac44919b23ff7f1ce691fa67e7f8fff1af76907 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 10:47:47 -0700 Subject: [PATCH 02/84] include find mbedtls --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index bec745882..9be3421a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,7 @@ ENDIF () FIND_PACKAGE(PkgConfig REQUIRED) INCLUDE(cmake/dtrace-utils.cmake) INCLUDE(cmake/boringssl-adjust.cmake) +INCLUDE(cmake/FindMbedTLS.cmake) CHECK_DTRACE(${PROJECT_SOURCE_DIR}/picotls-probes.d) IF ((CMAKE_SIZEOF_VOID_P EQUAL 8) AND From e5cd27567b21d62d2da16b0d0add08b0e98a6a9f Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 10:49:47 -0700 Subject: [PATCH 03/84] Add cmake module path --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9be3421a7..3200ae609 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ ENDIF () FIND_PACKAGE(PkgConfig REQUIRED) INCLUDE(cmake/dtrace-utils.cmake) INCLUDE(cmake/boringssl-adjust.cmake) -INCLUDE(cmake/FindMbedTLS.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 From be89606ccfe7923e9903786f405abd21ba43775d Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 11:04:36 -0700 Subject: [PATCH 04/84] Add find package --- cmake/FindMbedTLS.cmake | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmake/FindMbedTLS.cmake b/cmake/FindMbedTLS.cmake index 2bddc77e1..ae3d4e80e 100644 --- a/cmake/FindMbedTLS.cmake +++ b/cmake/FindMbedTLS.cmake @@ -11,5 +11,11 @@ find_path(MBEDTLS_INCLUDE_DIRS set(MBEDTLS_HINTS ${MBEDTLS_PREFIX}/build ${CMAKE_BINARY_DIR}/../mbedtls/build ../mbedtls/build) find_library(MBEDTLS_LIBRARY mbedtls HINTS ${MBEDTLS_HINTS}) +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set PTLS_FOUND to TRUE +# if all listed variables are TRUE +find_package_handle_standard_args(MbedTLS REQUIRED_VARS + MBEDTLS_LIBRARY + MBEDTLS_INCLUDE_DIRS) mark_as_advanced(MBEDTLS_LIBRARY MBEDTLS_INCLUDE_DIRS) From 4a01610e8233d06b3f16ae3a781b3627b4b5d56d Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 11:14:21 -0700 Subject: [PATCH 05/84] Update MbedTLS find --- cmake/FindMbedTLS.cmake | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/cmake/FindMbedTLS.cmake b/cmake/FindMbedTLS.cmake index ae3d4e80e..b2638f911 100644 --- a/cmake/FindMbedTLS.cmake +++ b/cmake/FindMbedTLS.cmake @@ -8,14 +8,24 @@ find_path(MBEDTLS_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/../mbedtls/include/ ../mbedtls/include/ ) -set(MBEDTLS_HINTS ${MBEDTLS_PREFIX}/build ${CMAKE_BINARY_DIR}/../mbedtls/build ../mbedtls/build) + + +set(MBEDTLS_HINTS ${MBEDTLS_PREFIX}/build/library + ${CMAKE_BINARY_DIR}/../mbedtls/build/library + ../mbedtls/build/library ../mbedtls/library) find_library(MBEDTLS_LIBRARY mbedtls HINTS ${MBEDTLS_HINTS}) +find_library(MBEDTLS_CRYPTO mbedcrypto HINTS ${MBEDTLS_HINTS}) +find_library(MBEDTLS_X509 mbedx509 HINTS ${MBEDTLS_HINTS}) include(FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set PTLS_FOUND to TRUE # if all listed variables are TRUE find_package_handle_standard_args(MbedTLS REQUIRED_VARS MBEDTLS_LIBRARY + MBEDTLS_CRYPTO + MBEDTLS_X509 MBEDTLS_INCLUDE_DIRS) - -mark_as_advanced(MBEDTLS_LIBRARY MBEDTLS_INCLUDE_DIRS) + +if(MbedTLS_FOUND) + set(MBEDTLS_LIBRARIES ${MBEDTLS_LIBRARY} ${MBEDTLS_CRYPTO} ${MBEDTLS_X509}) + mark_as_advanced(MBEDTLS_LIBRARIES MBEDTLS_INCLUDE_DIRS) From 7a53976a314c042f302ead80918ba6ffed788a7a Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 11:22:40 -0700 Subject: [PATCH 06/84] Add missing endif --- cmake/FindMbedTLS.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmake/FindMbedTLS.cmake b/cmake/FindMbedTLS.cmake index b2638f911..e71403ea0 100644 --- a/cmake/FindMbedTLS.cmake +++ b/cmake/FindMbedTLS.cmake @@ -26,6 +26,7 @@ find_package_handle_standard_args(MbedTLS REQUIRED_VARS MBEDTLS_X509 MBEDTLS_INCLUDE_DIRS) -if(MbedTLS_FOUND) +if (MbedTLS_FOUND) set(MBEDTLS_LIBRARIES ${MBEDTLS_LIBRARY} ${MBEDTLS_CRYPTO} ${MBEDTLS_X509}) mark_as_advanced(MBEDTLS_LIBRARIES MBEDTLS_INCLUDE_DIRS) +endif () \ No newline at end of file From 5aac49fca43f37a236c64f66352cf73fc6013560 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 11:25:06 -0700 Subject: [PATCH 07/84] Check mbedtls found condition --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3200ae609..571d7a544 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -203,7 +203,7 @@ ENDIF () IF (WITH_MBEDTLS) FIND_PACKAGE(MbedTLS) - IF (NOT MbedTLS) + IF (NOT MbedTLS_FOUND) MESSAGE (FATAL_ERROR "MbedTLS not found") ELSE () message(STATUS "mbedtls/include: ${MBEDTLS_INCLUDE_DIRS}") From bbb502ee882c1857de820f73384dd7e46f204cf5 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 11:26:13 -0700 Subject: [PATCH 08/84] Struggling with Found condition. --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 571d7a544..9bce67ce7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -203,9 +203,7 @@ ENDIF () IF (WITH_MBEDTLS) FIND_PACKAGE(MbedTLS) - IF (NOT MbedTLS_FOUND) - MESSAGE (FATAL_ERROR "MbedTLS not found") - ELSE () + IF (MbedTLS_FOUND) message(STATUS "mbedtls/include: ${MBEDTLS_INCLUDE_DIRS}") message(STATUS "mbedtls libraries: ${MBEDTLS_LIBRARIES}") INCLUDE_DIRECTORIES(${MBEDTLS_INCLUDE_DIRS}) @@ -217,6 +215,8 @@ IF (WITH_MBEDTLS) TARGET_LINK_LIBRARIES(test-mbedtls.t picotls-minicrypto picotls-mbedtls ${MBEDTLS_LIBRARIES}) + ELSE () + MESSAGE (FATAL_ERROR "MbedTLS not found") ENDIF() ENDIF () From 262d334610d1daa3e7621f41ac40e3338b3d6a1f Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 11:30:25 -0700 Subject: [PATCH 09/84] Remove error condition for debug --- CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9bce67ce7..b44a64125 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -203,7 +203,7 @@ ENDIF () IF (WITH_MBEDTLS) FIND_PACKAGE(MbedTLS) - IF (MbedTLS_FOUND) + # IF (MbedTLS_FOUND) message(STATUS "mbedtls/include: ${MBEDTLS_INCLUDE_DIRS}") message(STATUS "mbedtls libraries: ${MBEDTLS_LIBRARIES}") INCLUDE_DIRECTORIES(${MBEDTLS_INCLUDE_DIRS}) @@ -215,9 +215,9 @@ IF (WITH_MBEDTLS) TARGET_LINK_LIBRARIES(test-mbedtls.t picotls-minicrypto picotls-mbedtls ${MBEDTLS_LIBRARIES}) - ELSE () - MESSAGE (FATAL_ERROR "MbedTLS not found") - ENDIF() + #ELSE () + # MESSAGE (FATAL_ERROR "MbedTLS not found") + #ENDIF() ENDIF () ADD_EXECUTABLE(ptlsbench t/ptlsbench.c) From 17dee3e2a7d5683b86251b7a86876983161e38bb Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 11:34:16 -0700 Subject: [PATCH 10/84] update mbedtls test --- t/ptls_mbedtls.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/t/ptls_mbedtls.c b/t/ptls_mbedtls.c index 2b14e92f6..fd2b4f198 100644 --- a/t/ptls_mbedtls.c +++ b/t/ptls_mbedtls.c @@ -288,7 +288,7 @@ static void test_label_sha256(void) static void test_aes128ecb(void) { - if (test_cipher(ptls_mbedtls_aes128ecb, ptls_minicrypto_aes128ecb) != 0) { + if (test_cipher(&ptls_mbedtls_aes128ecb, &ptls_minicrypto_aes128ecb) != 0) { ok(!"fail"); } ok(!!"success"); @@ -296,7 +296,7 @@ static void test_aes128ecb(void) static void test_aes128ctr(void) { - if (test_cipher(ptls_mbedtls_aes128ctr, ptls_minicrypto_aes128ctr) != 0) { + if (test_cipher(&ptls_mbedtls_aes128ctr, &ptls_minicrypto_aes128ctr) != 0) { ok(!"fail"); } ok(!!"success"); @@ -304,7 +304,7 @@ static void test_aes128ctr(void) static void test_aes256ecb(void) { - if (test_cipher(ptls_mbedtls_aes256ecb, ptls_minicrypto_aes256ecb) != 0) { + if (test_cipher(&ptls_mbedtls_aes256ecb, &ptls_minicrypto_aes256ecb) != 0) { ok(!"fail"); } ok(!!"success"); @@ -312,7 +312,7 @@ static void test_aes256ecb(void) static void test_aes256ctr(void) { - if (test_cipher(ptls_mbedtls_aes256ctr, ptls_minicrypto_aes2568ctr) != 0) { + if (test_cipher(&ptls_mbedtls_aes256ctr, &ptls_minicrypto_aes2568ctr) != 0) { ok(!"fail"); } ok(!!"success"); @@ -329,7 +329,7 @@ static void test_aes128gcm_sha256(void) int main(int argc, char **argv) { /* Initialize the PSA crypto library. */ - if ((status = psa_crypto_init()) != PSA_SUCCESS) { + if (psa_crypto_init() != PSA_SUCCESS) { note("psa_crypto_init fails."); return done_testing(); } From 3d5657ce87fd080f56d6c4b8add0cb7b73605b2d Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 11:35:17 -0700 Subject: [PATCH 11/84] fix typo --- t/ptls_mbedtls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/ptls_mbedtls.c b/t/ptls_mbedtls.c index fd2b4f198..a4f9eeef3 100644 --- a/t/ptls_mbedtls.c +++ b/t/ptls_mbedtls.c @@ -312,7 +312,7 @@ static void test_aes256ecb(void) static void test_aes256ctr(void) { - if (test_cipher(&ptls_mbedtls_aes256ctr, &ptls_minicrypto_aes2568ctr) != 0) { + if (test_cipher(&ptls_mbedtls_aes256ctr, &ptls_minicrypto_aes256ctr) != 0) { ok(!"fail"); } ok(!!"success"); From b29d4b4b0fdcd7603a5667c66d6d865baf2ddeac Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 13:01:14 -0700 Subject: [PATCH 12/84] Add github action for mbedtls --- .github/workflows/mbedtls.yml | 36 +++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/mbedtls.yml diff --git a/.github/workflows/mbedtls.yml b/.github/workflows/mbedtls.yml new file mode 100644 index 000000000..298d2351c --- /dev/null +++ b/.github/workflows/mbedtls.yml @@ -0,0 +1,36 @@ +--- +name: "MbedTLS-test" + +on: [push, pull_request] + +jobs: + mbedtls: + name: MbedTLS-test + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + # We must fetch at least the immediate parents so that if this is + # a pull request then we can checkout the head. + fetch-depth: 2 + submodules: 'recursive' + + - name: Installing MbedTLS + run: | + git clone https://github.com/Mbed-TLS/mbedtls + cd mbedtls + cmake --build . + cd build + make + cd ../.. + + - name: Compile picotls + run: | + cmake "-DWITH_MBEDTLS=ON" . + make + + - name: Run test + run: | + ./test-mbedtls.t \ No newline at end of file From ce37fa0ceacfc6151991a8d9826978617cf86db7 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 14:08:10 -0700 Subject: [PATCH 13/84] Debugging github action. --- .github/workflows/mbedtls.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/mbedtls.yml b/.github/workflows/mbedtls.yml index 298d2351c..fb2b23cd9 100644 --- a/.github/workflows/mbedtls.yml +++ b/.github/workflows/mbedtls.yml @@ -21,6 +21,8 @@ jobs: run: | git clone https://github.com/Mbed-TLS/mbedtls cd mbedtls + echo "cloned mbedtls" + ls cmake --build . cd build make From 684008cb9b4a3a79d14233c25c977fc892d8a351 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 14:13:42 -0700 Subject: [PATCH 14/84] Decomposing the build steps --- .github/workflows/mbedtls.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/mbedtls.yml b/.github/workflows/mbedtls.yml index fb2b23cd9..8f8109ea0 100644 --- a/.github/workflows/mbedtls.yml +++ b/.github/workflows/mbedtls.yml @@ -22,9 +22,10 @@ jobs: git clone https://github.com/Mbed-TLS/mbedtls cd mbedtls echo "cloned mbedtls" - ls - cmake --build . + mkdir build cd build + cmake -S .. . + echo "cmake done" make cd ../.. From 8bca3c2c405324cc8bcb7442e4e1c8bc2b50f8fd Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 14:21:20 -0700 Subject: [PATCH 15/84] More debugging of github action --- .github/workflows/mbedtls.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/mbedtls.yml b/.github/workflows/mbedtls.yml index 8f8109ea0..dc7ebcadc 100644 --- a/.github/workflows/mbedtls.yml +++ b/.github/workflows/mbedtls.yml @@ -27,10 +27,14 @@ jobs: cmake -S .. . echo "cmake done" make + echo "compiled MbedTLS" + pwd cd ../.. - name: Compile picotls run: | + echo "building picotls with MbedTLS" + pwd cmake "-DWITH_MBEDTLS=ON" . make From 12bd1944add05fc1674fbbc97524724bf3380aed Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 14:29:59 -0700 Subject: [PATCH 16/84] Build mbedtls parallel to picotls --- .github/workflows/mbedtls.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/mbedtls.yml b/.github/workflows/mbedtls.yml index dc7ebcadc..93d14de85 100644 --- a/.github/workflows/mbedtls.yml +++ b/.github/workflows/mbedtls.yml @@ -19,6 +19,7 @@ jobs: - name: Installing MbedTLS run: | + cd .. git clone https://github.com/Mbed-TLS/mbedtls cd mbedtls echo "cloned mbedtls" @@ -29,7 +30,7 @@ jobs: make echo "compiled MbedTLS" pwd - cd ../.. + cd ../../picotls - name: Compile picotls run: | From ccecfa5dfa5d87b02cfc9a2fadbfef7aaccf7b27 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 17:12:59 -0700 Subject: [PATCH 17/84] Add sha512 and sha384 --- include/picotls/ptls_mbedtls.h | 4 ++ lib/ptls_mbedtls.c | 107 ++++++++++++++++++++++++++++++++- t/ptls_mbedtls.c | 32 +++++++++- 3 files changed, 139 insertions(+), 4 deletions(-) diff --git a/include/picotls/ptls_mbedtls.h b/include/picotls/ptls_mbedtls.h index 18f67370e..0ab1d9f2f 100644 --- a/include/picotls/ptls_mbedtls.h +++ b/include/picotls/ptls_mbedtls.h @@ -28,6 +28,10 @@ extern "C" { #include "picotls.h" extern ptls_hash_algorithm_t ptls_mbedtls_sha256; +extern ptls_hash_algorithm_t ptls_mbedtls_sha512; +#if defined(MBEDTLS_SHA384_C) +extern ptls_hash_algorithm_t ptls_mbedtls_sha384; +#endif extern ptls_cipher_algorithm_t ptls_mbedtls_aes128ecb; extern ptls_cipher_algorithm_t ptls_mbedtls_aes256ecb; diff --git a/lib/ptls_mbedtls.c b/lib/ptls_mbedtls.c index 6c2bf82b6..e19a09f52 100644 --- a/lib/ptls_mbedtls.c +++ b/lib/ptls_mbedtls.c @@ -6,10 +6,12 @@ #include #include #include +#include "mbedtls/config.h" #include "mbedtls/build_info.h" #include "psa/crypto.h" #include "psa/crypto_struct.h" #include "mbedtls/sha256.h" +#include "mbedtls/sha512.h" #include "mbedtls/aes.h" /* Definitions for hash algorithms. @@ -25,7 +27,6 @@ * void (*final)(struct st_ptls_hash_context_t *ctx, void *md, ptls_hash_final_mode_t mode); * struct st_ptls_hash_context_t *(*clone_)(struct st_ptls_hash_context_t *src); * -* TODO: develop shim for other hash methods besides SHA256 */ typedef struct st_ptls_mbedtls_sha256_ctx_t { @@ -105,6 +106,110 @@ ptls_hash_algorithm_t ptls_mbedtls_sha256 = {"sha256", PTLS_SHA256_BLOCK_SIZE, P PTLS_ZERO_DIGEST_SHA256}; +/* SHA 512 follows the same general architecture as SHA 256. + * The SHA 384 module is using the same code, with an option to + * deliver a shorter hash. + */ + + +typedef struct st_ptls_mbedtls_sha512_ctx_t { + ptls_hash_context_t super; + mbedtls_sha512_context mctx; +} ptls_mbedtls_sha512_ctx_t; + +static void ptls_mbedtls_sha512_update(struct st_ptls_hash_context_t* _ctx, const void* src, size_t len) +{ + ptls_mbedtls_sha512_ctx_t* ctx = (ptls_mbedtls_sha512_ctx_t*)_ctx; + + (void)mbedtls_sha512_update(&ctx->mctx, (const uint8_t*)src, len); +} + +static void ptls_mbedtls_sha512_final(struct st_ptls_hash_context_t* _ctx, void* md, ptls_hash_final_mode_t mode); + +static struct st_ptls_hash_context_t* ptls_mbedtls_sha512_clone(struct st_ptls_hash_context_t* _src) +{ + ptls_mbedtls_sha512_ctx_t* ctx = (ptls_mbedtls_sha512_ctx_t*)malloc(sizeof(ptls_mbedtls_sha512_ctx_t)); + + if (ctx != NULL) { + ptls_mbedtls_sha512_ctx_t* src = (ptls_mbedtls_sha512_ctx_t*)_src; + memset(&ctx->mctx, 0, sizeof(mbedtls_sha512_context)); + ctx->super.clone_ = ptls_mbedtls_sha512_clone; + ctx->super.update = ptls_mbedtls_sha512_update; + ctx->super.final = ptls_mbedtls_sha512_final; + mbedtls_sha512_clone(&ctx->mctx, &src->mctx); + } + return (ptls_hash_context_t*)ctx; +} + +static void ptls_mbedtls_sha512_final(struct st_ptls_hash_context_t* _ctx, void* md, ptls_hash_final_mode_t mode) +{ + ptls_mbedtls_sha512_ctx_t* ctx = (ptls_mbedtls_sha512_ctx_t*)_ctx; + + if (mode == PTLS_HASH_FINAL_MODE_SNAPSHOT) { + struct st_ptls_hash_context_t* cloned = ptls_mbedtls_sha512_clone(_ctx); + + if (cloned != NULL) { + ptls_mbedtls_sha512_final(cloned, md, PTLS_HASH_FINAL_MODE_FREE); + } + } else { + if (md != NULL) { + (void)mbedtls_sha512_finish(&ctx->mctx, (uint8_t*)md); + } + + if (mode == PTLS_HASH_FINAL_MODE_FREE) { + mbedtls_sha512_free(&ctx->mctx); + free(ctx); + } + else { + /* if mode = reset, reset the context */ + mbedtls_sha512_init(&ctx->mctx); + mbedtls_sha512_starts(&ctx->mctx, 0 /* is224 = 0 */); + } + } +} + +ptls_hash_context_t* ptls_mbedtls_sha512_create(void) +{ + ptls_mbedtls_sha512_ctx_t* ctx = (ptls_mbedtls_sha512_ctx_t*)malloc(sizeof(ptls_mbedtls_sha512_ctx_t)); + + if (ctx != NULL) { + memset(&ctx->mctx, 0, sizeof(mbedtls_sha512_context)); + ctx->super.clone_ = ptls_mbedtls_sha512_clone; + ctx->super.update = ptls_mbedtls_sha512_update; + ctx->super.final = ptls_mbedtls_sha512_final; + if (mbedtls_sha512_starts(&ctx->mctx, 0 /* is384 = 0 */) != 0) { + free(ctx); + ctx = NULL; + } + } + return (ptls_hash_context_t*)ctx; +} + +ptls_hash_algorithm_t ptls_mbedtls_sha512 = {"SHA512", PTLS_SHA512_BLOCK_SIZE, PTLS_SHA512_DIGEST_SIZE, ptls_mbedtls_sha512_create, +PTLS_ZERO_DIGEST_SHA512}; + +#if defined(MBEDTLS_SHA384_C) +ptls_hash_context_t* ptls_mbedtls_sha384_create(void) +{ + ptls_mbedtls_sha512_ctx_t* ctx = (ptls_mbedtls_sha512_ctx_t*)malloc(sizeof(ptls_mbedtls_sha512_ctx_t)); + + if (ctx != NULL) { + memset(&ctx->mctx, 0, sizeof(mbedtls_sha512_context)); + ctx->super.clone_ = ptls_mbedtls_sha512_clone; + ctx->super.update = ptls_mbedtls_sha512_update; + ctx->super.final = ptls_mbedtls_sha512_final; + if (mbedtls_sha512_starts(&ctx->mctx, 1 /* is384 = 1 */) != 0) { + free(ctx); + ctx = NULL; + } + } + return (ptls_hash_context_t*)ctx; +} + +ptls_hash_algorithm_t ptls_mbedtls_sha512 = {"SHA384", PTLS_SHA384_BLOCK_SIZE, PTLS_SHA384_DIGEST_SIZE, ptls_mbedtls_sha384_create, +PTLS_ZERO_DIGEST_SHA384}; +#endif /* MBEDTLS_SHA384_C */ + /* definitions for symmetric crypto algorithms. * Each algorithm (ECB or CTR) is represented by an "algorithm" * entry in which the 'setup" function is used to initialize diff --git a/t/ptls_mbedtls.c b/t/ptls_mbedtls.c index a4f9eeef3..643204cc3 100644 --- a/t/ptls_mbedtls.c +++ b/t/ptls_mbedtls.c @@ -29,6 +29,7 @@ #include #include #include +#include "mbedtls/config.h" #include "mbedtls/build_info.h" #include "psa/crypto.h" #include "psa/crypto_struct.h" @@ -68,9 +69,9 @@ static int test_hash(ptls_hash_algorithm_t* algo, ptls_hash_algorithm_t* ref) { int ret = 0; uint8_t input[1234]; - uint8_t final_hash[32]; - uint8_t final_ref[32]; - uint8_t hash1[32], hash2[32], href1[32], href2[32]; + uint8_t final_hash[64]; + uint8_t final_ref[64]; + uint8_t hash1[64], hash2[64], href1[64], href2[64]; memset(input, 0xba, sizeof(input)); @@ -277,6 +278,27 @@ static void test_sha256(void) ok(!!"success"); } +static void test_sha512(void) +{ + if (test_hash(&ptls_mbedtls_sha512, &ptls_minicrypto_sha512) != 0) { + ok(!"fail"); + return; + } + ok(!!"success"); +} + + +#if defined(MBEDTLS_SHA384_C) +static void test_sha384(void) +{ + if (test_hash(&ptls_mbedtls_sha384, &ptls_minicrypto_sha384) != 0) { + ok(!"fail"); + return; + } + ok(!!"success"); +} +#endif + static void test_label_sha256(void) { if (test_label(&ptls_mbedtls_sha256, &ptls_minicrypto_sha256) != 0) { @@ -335,6 +357,10 @@ int main(int argc, char **argv) } /* Series of test to check consistency between wrapped mbedtls and minicrypto */ subtest("sha256", test_sha256); + subtest("sha512", test_sha256); +#if defined(MBEDTLS_SHA384_C) + subtest("sha384", test_sha256); +#endif subtest("label_sha256", test_label_sha256); subtest("aes128ecb", test_aes128ecb); subtest("aes128ctr", test_aes128ctr); From bc75434991922794088a80e9f496e9689080f2a1 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 17:57:31 -0700 Subject: [PATCH 18/84] Update sha384 definitions and test --- lib/ptls_mbedtls.c | 36 ++++++++++++++++-------------------- t/ptls_mbedtls.c | 15 ++------------- 2 files changed, 18 insertions(+), 33 deletions(-) diff --git a/lib/ptls_mbedtls.c b/lib/ptls_mbedtls.c index e19a09f52..26f2aa731 100644 --- a/lib/ptls_mbedtls.c +++ b/lib/ptls_mbedtls.c @@ -6,7 +6,7 @@ #include #include #include -#include "mbedtls/config.h" +#include "mbedtls/mbedtls_config.h" #include "mbedtls/build_info.h" #include "psa/crypto.h" #include "psa/crypto_struct.h" @@ -115,6 +115,7 @@ PTLS_ZERO_DIGEST_SHA256}; typedef struct st_ptls_mbedtls_sha512_ctx_t { ptls_hash_context_t super; mbedtls_sha512_context mctx; + int is384; } ptls_mbedtls_sha512_ctx_t; static void ptls_mbedtls_sha512_update(struct st_ptls_hash_context_t* _ctx, const void* src, size_t len) @@ -163,12 +164,12 @@ static void ptls_mbedtls_sha512_final(struct st_ptls_hash_context_t* _ctx, void* else { /* if mode = reset, reset the context */ mbedtls_sha512_init(&ctx->mctx); - mbedtls_sha512_starts(&ctx->mctx, 0 /* is224 = 0 */); + mbedtls_sha512_starts(&ctx->mctx, ctx->is384); } } } -ptls_hash_context_t* ptls_mbedtls_sha512_create(void) +ptls_hash_context_t* ptls_mbedtls_sha512_384_create(int is384) { ptls_mbedtls_sha512_ctx_t* ctx = (ptls_mbedtls_sha512_ctx_t*)malloc(sizeof(ptls_mbedtls_sha512_ctx_t)); @@ -177,7 +178,9 @@ ptls_hash_context_t* ptls_mbedtls_sha512_create(void) ctx->super.clone_ = ptls_mbedtls_sha512_clone; ctx->super.update = ptls_mbedtls_sha512_update; ctx->super.final = ptls_mbedtls_sha512_final; - if (mbedtls_sha512_starts(&ctx->mctx, 0 /* is384 = 0 */) != 0) { + ctx->is384 = is384; + + if (mbedtls_sha512_starts(&ctx->mctx, is384) != 0) { free(ctx); ctx = NULL; } @@ -185,28 +188,22 @@ ptls_hash_context_t* ptls_mbedtls_sha512_create(void) return (ptls_hash_context_t*)ctx; } +ptls_hash_context_t* ptls_mbedtls_sha512_create(void) +{ + return ptls_mbedtls_sha512_384_create(0); +} + ptls_hash_algorithm_t ptls_mbedtls_sha512 = {"SHA512", PTLS_SHA512_BLOCK_SIZE, PTLS_SHA512_DIGEST_SIZE, ptls_mbedtls_sha512_create, PTLS_ZERO_DIGEST_SHA512}; #if defined(MBEDTLS_SHA384_C) ptls_hash_context_t* ptls_mbedtls_sha384_create(void) { - ptls_mbedtls_sha512_ctx_t* ctx = (ptls_mbedtls_sha512_ctx_t*)malloc(sizeof(ptls_mbedtls_sha512_ctx_t)); - - if (ctx != NULL) { - memset(&ctx->mctx, 0, sizeof(mbedtls_sha512_context)); - ctx->super.clone_ = ptls_mbedtls_sha512_clone; - ctx->super.update = ptls_mbedtls_sha512_update; - ctx->super.final = ptls_mbedtls_sha512_final; - if (mbedtls_sha512_starts(&ctx->mctx, 1 /* is384 = 1 */) != 0) { - free(ctx); - ctx = NULL; - } - } - return (ptls_hash_context_t*)ctx; + return ptls_mbedtls_sha512_384_create(1); } -ptls_hash_algorithm_t ptls_mbedtls_sha512 = {"SHA384", PTLS_SHA384_BLOCK_SIZE, PTLS_SHA384_DIGEST_SIZE, ptls_mbedtls_sha384_create, +ptls_hash_algorithm_t ptls_mbedtls_sha384 = {"SHA384", PTLS_SHA384_BLOCK_SIZE, +PTLS_SHA384_DIGEST_SIZE, ptls_mbedtls_sha384_create, PTLS_ZERO_DIGEST_SHA384}; #endif /* MBEDTLS_SHA384_C */ @@ -332,7 +329,6 @@ static int ptls_mbedtls_cipher_setup_crypto_aes128_ctr(ptls_cipher_context_t *_c return ret; } - static int ptls_mbedtls_cipher_setup_crypto_aes256_ecb(ptls_cipher_context_t *_ctx, int is_enc, const void *key) { struct st_ptls_mbedtls_aes_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; @@ -420,7 +416,7 @@ ptls_mbedtls_cipher_setup_crypto_aes256_ctr}; * The aead context also documents the underlying "ECB" and "CTR" modes. * In QUIC, these are used for PN encryption. * -* TODO: declare other lagorithms besides AES128_GCM +* TODO: declare other algorithms besides AES128_GCM */ struct ptls_mbedtls_aead_param_t { diff --git a/t/ptls_mbedtls.c b/t/ptls_mbedtls.c index 643204cc3..59e6a228d 100644 --- a/t/ptls_mbedtls.c +++ b/t/ptls_mbedtls.c @@ -29,7 +29,7 @@ #include #include #include -#include "mbedtls/config.h" +#include "mbedtls/mbedtls_config.h" #include "mbedtls/build_info.h" #include "psa/crypto.h" #include "psa/crypto_struct.h" @@ -278,16 +278,6 @@ static void test_sha256(void) ok(!!"success"); } -static void test_sha512(void) -{ - if (test_hash(&ptls_mbedtls_sha512, &ptls_minicrypto_sha512) != 0) { - ok(!"fail"); - return; - } - ok(!!"success"); -} - - #if defined(MBEDTLS_SHA384_C) static void test_sha384(void) { @@ -357,9 +347,8 @@ int main(int argc, char **argv) } /* Series of test to check consistency between wrapped mbedtls and minicrypto */ subtest("sha256", test_sha256); - subtest("sha512", test_sha256); #if defined(MBEDTLS_SHA384_C) - subtest("sha384", test_sha256); + subtest("sha384", test_sha384); #endif subtest("label_sha256", test_label_sha256); subtest("aes128ecb", test_aes128ecb); From 251d42b85b3d03ebd49bc18a312f3d19680f738e Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 19:51:35 -0700 Subject: [PATCH 19/84] Add aes256gcm --- include/picotls/ptls_mbedtls.h | 1 + lib/ptls_mbedtls.c | 16 ++++++++++++++++ t/ptls_mbedtls.c | 16 ++++++++++++++-- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/include/picotls/ptls_mbedtls.h b/include/picotls/ptls_mbedtls.h index 0ab1d9f2f..f0a59ede9 100644 --- a/include/picotls/ptls_mbedtls.h +++ b/include/picotls/ptls_mbedtls.h @@ -39,6 +39,7 @@ extern ptls_cipher_algorithm_t ptls_mbedtls_aes128ctr; extern ptls_cipher_algorithm_t ptls_mbedtls_aes256ctr; extern ptls_aead_algorithm_t ptls_mbedtls_aes128gcm; +extern ptls_aead_algorithm_t ptls_mbedtls_aes256gcm; #ifdef __cplusplus } diff --git a/lib/ptls_mbedtls.c b/lib/ptls_mbedtls.c index 26f2aa731..68a7971cc 100644 --- a/lib/ptls_mbedtls.c +++ b/lib/ptls_mbedtls.c @@ -685,3 +685,19 @@ ptls_aead_algorithm_t ptls_mbedtls_aes128gcm = { sizeof(struct ptls_mbedtls_aead_context_t), ptls_mbedtls_aead_setup_crypto }; + +ptls_aead_algorithm_t ptls_mbedtls_aes256gcm = { + "AES256-GCM", + PTLS_AESGCM_CONFIDENTIALITY_LIMIT, + PTLS_AESGCM_INTEGRITY_LIMIT, + &ptls_mbedtls_aes256ecb, + &ptls_mbedtls_aes256ctr, + PTLS_AES256_KEY_SIZE, + PTLS_AESGCM_IV_SIZE, + PTLS_AESGCM_TAG_SIZE, + {PTLS_TLS12_AESGCM_FIXED_IV_SIZE, PTLS_TLS12_AESGCM_RECORD_IV_SIZE}, + 0, + 0, + sizeof(struct ptls_mbedtls_aead_context_t), + ptls_mbedtls_aead_setup_crypto +}; diff --git a/t/ptls_mbedtls.c b/t/ptls_mbedtls.c index 59e6a228d..3d91979a7 100644 --- a/t/ptls_mbedtls.c +++ b/t/ptls_mbedtls.c @@ -241,7 +241,7 @@ static int aead_trial(ptls_aead_algorithm_t * algo, ptls_hash_algorithm_t * hash static int test_aead(ptls_aead_algorithm_t* algo, ptls_hash_algorithm_t* hash, ptls_aead_algorithm_t* ref, ptls_hash_algorithm_t* hash_ref) { - uint8_t secret[32]; + uint8_t secret[64]; uint8_t v_in[1234]; uint8_t aad[17]; uint8_t v_out_a[1250], v_out_b[1250], v_out_r[1250]; @@ -338,6 +338,16 @@ static void test_aes128gcm_sha256(void) ok(!!"success"); } +#if defined(MBEDTLS_SHA384_C) +static void test_aes256gcm_sha384(void) +{ + if (test_aead(&ptls_mbedtls_aes256gcm, &ptls_mbedtls_sha384, &ptls_minicrypto_aes256gcm, &ptls_minicrypto_sha384) != 0) { + ok(!"fail"); + } + ok(!!"success"); +} +#endif + int main(int argc, char **argv) { /* Initialize the PSA crypto library. */ @@ -356,7 +366,9 @@ int main(int argc, char **argv) subtest("aes256ecb", test_aes256ecb); subtest("aes256ctr", test_aes256ctr); subtest("aes128gcm_sha256", test_aes128gcm_sha256); - +#if defined(MBEDTLS_SHA384_C) + subtest("aes256gcm_sha384", test_aes256gcm_sha384); +#endif /* Deinitialize the PSA crypto library. */ mbedtls_psa_crypto_free(); From ca4b8cbd3e8550943490caff92e80845cf659096 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 21:02:01 -0700 Subject: [PATCH 20/84] Add chachapoly --- lib/ptls_mbedtls.c | 79 ++++++++++++++++++++++++++++++++++++++++++---- t/ptls_mbedtls.c | 8 +++++ 2 files changed, 80 insertions(+), 7 deletions(-) diff --git a/lib/ptls_mbedtls.c b/lib/ptls_mbedtls.c index 68a7971cc..4f4c4eba1 100644 --- a/lib/ptls_mbedtls.c +++ b/lib/ptls_mbedtls.c @@ -13,6 +13,7 @@ #include "mbedtls/sha256.h" #include "mbedtls/sha512.h" #include "mbedtls/aes.h" +#include "mbedtls/chacha20.h" /* Definitions for hash algorithms. * In Picotls, these are described by the stucture @@ -222,11 +223,6 @@ PTLS_ZERO_DIGEST_SHA384}; * "stream block". * */ -struct ptls_mbedtls_symmetric_param_t { - uint8_t iv[PTLS_MAX_IV_SIZE]; - uint8_t *key_object; - int is_enc; -}; struct st_ptls_mbedtls_aes_context_t { ptls_cipher_context_t super; @@ -385,6 +381,59 @@ PTLS_AES_BLOCK_SIZE, sizeof(struct st_ptls_mbedtls_aes_context_t), ptls_mbedtls_cipher_setup_crypto_aes256_ctr}; +struct st_ptls_mbedtls_chacha20_context_t { + ptls_cipher_context_t super; + mbedtls_chacha20_context mctx; +}; + +static void ptls_mbedtls_chacha20_init(ptls_cipher_context_t *_ctx, const void *iv) +{ + struct st_ptls_mbedtls_chacha20_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; + + (void)mbedtls_chacha20_starts(mbedtls_chacha20_context * ctx, (const uint8_t*)iv, 0); +} + +static void ptls_mbedtls_chacha20_transform(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t len) +{ + struct st_ptls_mbedtls_chacha20_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; + size_t nc_off = 0; + + if (mbedtls_chacha20_update(&ctx->mctx, len, + (const uint8_t*)input, (uint8_t*)output) != 0) { + memset(output, 0, len); + } +} + +static void ptls_mbedtls_chacha20_dispose(ptls_cipher_context_t *_ctx) +{ + struct st_ptls_mbedtls_chacha20_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; + mbedtls_chacha20_free(&ctx->mctx); +} + +static int ptls_mbedtls_cipher_setup_crypto_chacha20(ptls_cipher_context_t *_ctx, int is_enc, const void *key) +{ + struct st_ptls_mbedtls_chacha20_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; + int ret = 0; + + mbedtls_chacha20_init(&ctx->mctx); + ret = mbedtls_chacha20_setkey(&ctx->mctx, (const uint8_t*)key); + + ctx->super.do_dispose = ptls_mbedtls_chacha20_dispose; + ctx->super.do_init = ptls_mbedtls_chacha20_init; + ctx->super.do_transform = NULL; + + if (ret == 0) { + ctx->super.do_transform = ptls_mbedtls_chacha20_transform; + } + + return ret; +} + +ptls_cipher_algorithm_t ptls_minicrypto_chacha20 = { + "CHACHA20", PTLS_CHACHA20_KEY_SIZE, 1 /* block size */, PTLS_CHACHA20_IV_SIZE, sizeof(struct st_ptls_mbedtls_chacha20_context_t), + ptls_mbedtls_cipher_setup_crypto_chacha20}; + + /* Definitions of AEAD algorithms. * * For the picotls API, AEAD algorithms are created by calling: @@ -674,8 +723,8 @@ ptls_aead_algorithm_t ptls_mbedtls_aes128gcm = { "AES128-GCM", PTLS_AESGCM_CONFIDENTIALITY_LIMIT, PTLS_AESGCM_INTEGRITY_LIMIT, - &ptls_mbedtls_aes128ecb, &ptls_mbedtls_aes128ctr, + &ptls_mbedtls_aes128ecb, PTLS_AES128_KEY_SIZE, PTLS_AESGCM_IV_SIZE, PTLS_AESGCM_TAG_SIZE, @@ -690,8 +739,8 @@ ptls_aead_algorithm_t ptls_mbedtls_aes256gcm = { "AES256-GCM", PTLS_AESGCM_CONFIDENTIALITY_LIMIT, PTLS_AESGCM_INTEGRITY_LIMIT, - &ptls_mbedtls_aes256ecb, &ptls_mbedtls_aes256ctr, + &ptls_mbedtls_aes256ecb, PTLS_AES256_KEY_SIZE, PTLS_AESGCM_IV_SIZE, PTLS_AESGCM_TAG_SIZE, @@ -701,3 +750,19 @@ ptls_aead_algorithm_t ptls_mbedtls_aes256gcm = { sizeof(struct ptls_mbedtls_aead_context_t), ptls_mbedtls_aead_setup_crypto }; + +ptls_aead_algorithm_t ptls_minicrypto_chacha20poly1305 = { + "CHACHA20-POLY1305", + PTLS_CHACHA20POLY1305_CONFIDENTIALITY_LIMIT, + PTLS_CHACHA20POLY1305_INTEGRITY_LIMIT, + &ptls_minicrypto_chacha20, + NULL, + PTLS_CHACHA20_KEY_SIZE, + PTLS_CHACHA20POLY1305_IV_SIZE, + PTLS_CHACHA20POLY1305_TAG_SIZE, + {PTLS_TLS12_CHACHAPOLY_FIXED_IV_SIZE, PTLS_TLS12_CHACHAPOLY_RECORD_IV_SIZE}, + 0, + 0, + sizeof(struct ptls_mbedtls_aead_context_t), + ptls_mbedtls_aead_setup_crypto +}; \ No newline at end of file diff --git a/t/ptls_mbedtls.c b/t/ptls_mbedtls.c index 3d91979a7..87dacf188 100644 --- a/t/ptls_mbedtls.c +++ b/t/ptls_mbedtls.c @@ -348,6 +348,14 @@ static void test_aes256gcm_sha384(void) } #endif +static void test_chacha20poly1305_sha256(void) +{ + if (test_aead(&ptls_minicrypto_chacha20poly1305, &ptls_mbedtls_sha256, &ptls_minicrypto_chacha20poly1305, &ptls_minicrypto_sha256) != 0) { + ok(!"fail"); + } + ok(!!"success"); +} + int main(int argc, char **argv) { /* Initialize the PSA crypto library. */ From 511863166c425cc49060f4c8d301c05b553f05c5 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 21:03:14 -0700 Subject: [PATCH 21/84] Add test definition. --- t/ptls_mbedtls.c | 1 + 1 file changed, 1 insertion(+) diff --git a/t/ptls_mbedtls.c b/t/ptls_mbedtls.c index 87dacf188..c19000ecb 100644 --- a/t/ptls_mbedtls.c +++ b/t/ptls_mbedtls.c @@ -377,6 +377,7 @@ int main(int argc, char **argv) #if defined(MBEDTLS_SHA384_C) subtest("aes256gcm_sha384", test_aes256gcm_sha384); #endif + subtest("chacha20poly1305_sha256", test_chacha20poly1305_sha256); /* Deinitialize the PSA crypto library. */ mbedtls_psa_crypto_free(); From 0ad6f7f1ae6eac519c3ec57845952bce017f3e77 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 21:20:55 -0700 Subject: [PATCH 22/84] Fix copy paste errors --- lib/ptls_mbedtls.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/ptls_mbedtls.c b/lib/ptls_mbedtls.c index 4f4c4eba1..80a836bc3 100644 --- a/lib/ptls_mbedtls.c +++ b/lib/ptls_mbedtls.c @@ -388,15 +388,14 @@ struct st_ptls_mbedtls_chacha20_context_t { static void ptls_mbedtls_chacha20_init(ptls_cipher_context_t *_ctx, const void *iv) { - struct st_ptls_mbedtls_chacha20_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; + struct st_ptls_mbedtls_chacha20_context_t *ctx = (struct st_ptls_mbedtls_chacha20_context_t *)_ctx; - (void)mbedtls_chacha20_starts(mbedtls_chacha20_context * ctx, (const uint8_t*)iv, 0); + (void)mbedtls_chacha20_starts(&ctx->mctx, (const uint8_t*)iv, 0); } static void ptls_mbedtls_chacha20_transform(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t len) { - struct st_ptls_mbedtls_chacha20_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; - size_t nc_off = 0; + struct st_ptls_mbedtls_chacha20_context_t *ctx = (struct st_ptls_mbedtls_chacha20_context_t *)_ctx; if (mbedtls_chacha20_update(&ctx->mctx, len, (const uint8_t*)input, (uint8_t*)output) != 0) { @@ -406,13 +405,13 @@ static void ptls_mbedtls_chacha20_transform(ptls_cipher_context_t *_ctx, void *o static void ptls_mbedtls_chacha20_dispose(ptls_cipher_context_t *_ctx) { - struct st_ptls_mbedtls_chacha20_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; + struct st_ptls_mbedtls_chacha20_context_t *ctx = (struct st_ptls_mbedtls_chacha20_context_t *)_ctx; mbedtls_chacha20_free(&ctx->mctx); } static int ptls_mbedtls_cipher_setup_crypto_chacha20(ptls_cipher_context_t *_ctx, int is_enc, const void *key) { - struct st_ptls_mbedtls_chacha20_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; + struct st_ptls_mbedtls_chacha20_context_t *ctx = (struct st_ptls_mbedtls_chacha20_context_t *)_ctx; int ret = 0; mbedtls_chacha20_init(&ctx->mctx); From 62736e7b17487cb63e2250d9142f829c1db260d5 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 21:26:49 -0700 Subject: [PATCH 23/84] Another typo to fix --- t/ptls_mbedtls.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/t/ptls_mbedtls.c b/t/ptls_mbedtls.c index c19000ecb..5a5f29dea 100644 --- a/t/ptls_mbedtls.c +++ b/t/ptls_mbedtls.c @@ -330,6 +330,14 @@ static void test_aes256ctr(void) ok(!!"success"); } +static void test_chacha20(void) +{ + if (test_cipher(&ptls_mbedtls_chacha20, &ptls_minicrypto_chacha20) != 0) { + ok(!"fail"); + } + ok(!!"success"); +} + static void test_aes128gcm_sha256(void) { if (test_aead(&ptls_mbedtls_aes128gcm, &ptls_mbedtls_sha256, &ptls_minicrypto_aes128gcm, &ptls_minicrypto_sha256) != 0) { @@ -350,7 +358,7 @@ static void test_aes256gcm_sha384(void) static void test_chacha20poly1305_sha256(void) { - if (test_aead(&ptls_minicrypto_chacha20poly1305, &ptls_mbedtls_sha256, &ptls_minicrypto_chacha20poly1305, &ptls_minicrypto_sha256) != 0) { + if (test_aead(&ptls_mbedtls_chacha20poly1305, &ptls_mbedtls_sha256, &ptls_minicrypto_chacha20poly1305, &ptls_minicrypto_sha256) != 0) { ok(!"fail"); } ok(!!"success"); From 4510592270ac21536032b20bbc3b9e91ad62f30b Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 21:43:10 -0700 Subject: [PATCH 24/84] Fix declarations --- include/picotls/ptls_mbedtls.h | 2 ++ lib/ptls_mbedtls.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/picotls/ptls_mbedtls.h b/include/picotls/ptls_mbedtls.h index f0a59ede9..d3be13fcb 100644 --- a/include/picotls/ptls_mbedtls.h +++ b/include/picotls/ptls_mbedtls.h @@ -37,9 +37,11 @@ extern ptls_cipher_algorithm_t ptls_mbedtls_aes128ecb; extern ptls_cipher_algorithm_t ptls_mbedtls_aes256ecb; extern ptls_cipher_algorithm_t ptls_mbedtls_aes128ctr; extern ptls_cipher_algorithm_t ptls_mbedtls_aes256ctr; +extern ptls_cipher_algorithm_t ptls_minicrypto_chacha20; extern ptls_aead_algorithm_t ptls_mbedtls_aes128gcm; extern ptls_aead_algorithm_t ptls_mbedtls_aes256gcm; +extern ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305; #ifdef __cplusplus } diff --git a/lib/ptls_mbedtls.c b/lib/ptls_mbedtls.c index 80a836bc3..a5474940d 100644 --- a/lib/ptls_mbedtls.c +++ b/lib/ptls_mbedtls.c @@ -750,7 +750,7 @@ ptls_aead_algorithm_t ptls_mbedtls_aes256gcm = { ptls_mbedtls_aead_setup_crypto }; -ptls_aead_algorithm_t ptls_minicrypto_chacha20poly1305 = { +ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305 = { "CHACHA20-POLY1305", PTLS_CHACHA20POLY1305_CONFIDENTIALITY_LIMIT, PTLS_CHACHA20POLY1305_INTEGRITY_LIMIT, From f8186754c502b0c0c4786f62fd8c6566a86c7cd4 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 21:51:54 -0700 Subject: [PATCH 25/84] use chacha20 test --- t/ptls_mbedtls.c | 1 + 1 file changed, 1 insertion(+) diff --git a/t/ptls_mbedtls.c b/t/ptls_mbedtls.c index 5a5f29dea..2bd5f73e3 100644 --- a/t/ptls_mbedtls.c +++ b/t/ptls_mbedtls.c @@ -381,6 +381,7 @@ int main(int argc, char **argv) subtest("aes128ctr", test_aes128ctr); subtest("aes256ecb", test_aes256ecb); subtest("aes256ctr", test_aes256ctr); + subtest("chacha20", test_chacha20); subtest("aes128gcm_sha256", test_aes128gcm_sha256); #if defined(MBEDTLS_SHA384_C) subtest("aes256gcm_sha384", test_aes256gcm_sha384); From 25894aecf1386e255bcc28f8699902a8ef6e29a7 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 22:22:01 -0700 Subject: [PATCH 26/84] Fix chacha20 declaration --- include/picotls/ptls_mbedtls.h | 2 +- lib/ptls_mbedtls.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/picotls/ptls_mbedtls.h b/include/picotls/ptls_mbedtls.h index d3be13fcb..2d2790c04 100644 --- a/include/picotls/ptls_mbedtls.h +++ b/include/picotls/ptls_mbedtls.h @@ -37,7 +37,7 @@ extern ptls_cipher_algorithm_t ptls_mbedtls_aes128ecb; extern ptls_cipher_algorithm_t ptls_mbedtls_aes256ecb; extern ptls_cipher_algorithm_t ptls_mbedtls_aes128ctr; extern ptls_cipher_algorithm_t ptls_mbedtls_aes256ctr; -extern ptls_cipher_algorithm_t ptls_minicrypto_chacha20; +extern ptls_cipher_algorithm_t ptls_mbedtls_chacha20; extern ptls_aead_algorithm_t ptls_mbedtls_aes128gcm; extern ptls_aead_algorithm_t ptls_mbedtls_aes256gcm; diff --git a/lib/ptls_mbedtls.c b/lib/ptls_mbedtls.c index a5474940d..110dd1db7 100644 --- a/lib/ptls_mbedtls.c +++ b/lib/ptls_mbedtls.c @@ -428,7 +428,7 @@ static int ptls_mbedtls_cipher_setup_crypto_chacha20(ptls_cipher_context_t *_ctx return ret; } -ptls_cipher_algorithm_t ptls_minicrypto_chacha20 = { +ptls_cipher_algorithm_t ptls_mbedtls_chacha20 = { "CHACHA20", PTLS_CHACHA20_KEY_SIZE, 1 /* block size */, PTLS_CHACHA20_IV_SIZE, sizeof(struct st_ptls_mbedtls_chacha20_context_t), ptls_mbedtls_cipher_setup_crypto_chacha20}; From 167be771691e8122576059d6d5623c4c72b84a96 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 22:48:25 -0700 Subject: [PATCH 27/84] One last typo, hopefully --- lib/ptls_mbedtls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ptls_mbedtls.c b/lib/ptls_mbedtls.c index 110dd1db7..9e8fe9020 100644 --- a/lib/ptls_mbedtls.c +++ b/lib/ptls_mbedtls.c @@ -754,7 +754,7 @@ ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305 = { "CHACHA20-POLY1305", PTLS_CHACHA20POLY1305_CONFIDENTIALITY_LIMIT, PTLS_CHACHA20POLY1305_INTEGRITY_LIMIT, - &ptls_minicrypto_chacha20, + &ptls_mbedptls_chacha20, NULL, PTLS_CHACHA20_KEY_SIZE, PTLS_CHACHA20POLY1305_IV_SIZE, From 9b80cac86411874a01f6ab4502dd4307c81007ec Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 6 Sep 2023 22:59:51 -0700 Subject: [PATCH 28/84] That's for coding when half asleep --- lib/ptls_mbedtls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ptls_mbedtls.c b/lib/ptls_mbedtls.c index 9e8fe9020..f33e43477 100644 --- a/lib/ptls_mbedtls.c +++ b/lib/ptls_mbedtls.c @@ -754,7 +754,7 @@ ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305 = { "CHACHA20-POLY1305", PTLS_CHACHA20POLY1305_CONFIDENTIALITY_LIMIT, PTLS_CHACHA20POLY1305_INTEGRITY_LIMIT, - &ptls_mbedptls_chacha20, + &ptls_mbedtls_chacha20, NULL, PTLS_CHACHA20_KEY_SIZE, PTLS_CHACHA20POLY1305_IV_SIZE, From 480f189ed8b4ffdb478bf30052341dcae3ee515f Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Thu, 7 Sep 2023 12:25:31 -0700 Subject: [PATCH 29/84] Fix initialization of chacha20-ctr --- lib/ptls_mbedtls.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/ptls_mbedtls.c b/lib/ptls_mbedtls.c index f33e43477..d78ac14ec 100644 --- a/lib/ptls_mbedtls.c +++ b/lib/ptls_mbedtls.c @@ -386,11 +386,13 @@ struct st_ptls_mbedtls_chacha20_context_t { mbedtls_chacha20_context mctx; }; -static void ptls_mbedtls_chacha20_init(ptls_cipher_context_t *_ctx, const void *iv) +static void ptls_mbedtls_chacha20_init(ptls_cipher_context_t *_ctx, const void *v_iv) { struct st_ptls_mbedtls_chacha20_context_t *ctx = (struct st_ptls_mbedtls_chacha20_context_t *)_ctx; + const uint8_t* iv = (const uint8_t*)v_iv; + uint32_t ctr = iv[0] | ((uint32_t)iv[1] << 8) | ((uint32_t)iv[2] << 16) | ((uint32_t)iv[3] << 24); - (void)mbedtls_chacha20_starts(&ctx->mctx, (const uint8_t*)iv, 0); + (void)mbedtls_chacha20_starts(&ctx->mctx, (const uint8_t*)(iv+4), ctr); } static void ptls_mbedtls_chacha20_transform(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t len) From c06bc1b61c4ddba083b017cda4ac6f12162c1549 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Thu, 7 Sep 2023 12:46:35 -0700 Subject: [PATCH 30/84] Add mbedtls to ptlsbench --- CMakeLists.txt | 2 ++ t/ptlsbench.c | 28 +++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b44a64125..c4ffd50d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -215,6 +215,8 @@ IF (WITH_MBEDTLS) TARGET_LINK_LIBRARIES(test-mbedtls.t picotls-minicrypto picotls-mbedtls ${MBEDTLS_LIBRARIES}) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPTLS_HAVE_MBEDTLS=1") + LIST(APPEND PTLSBENCH_LIBS picotls-mbedtls ${MBEDTLS_LIBRARIES}) #ELSE () # MESSAGE (FATAL_ERROR "MbedTLS not found") #ENDIF() diff --git a/t/ptlsbench.c b/t/ptlsbench.c index 1b27607eb..684d99c0d 100644 --- a/t/ptlsbench.c +++ b/t/ptlsbench.c @@ -57,6 +57,12 @@ #endif #endif +#ifdef PTLS_HAVE_MBEDTLS +#include "mbedtls/build_info.h" +#include "psa/crypto.h" +#include "picotls/ptls_mbedtls.h" +#endif + /* Time in microseconds */ static uint64_t bench_time() { @@ -269,7 +275,15 @@ static ptls_bench_entry_t aead_list[] = { {"openssl", "chacha20poly1305", &ptls_openssl_chacha20poly1305, &ptls_minicrypto_sha256, 1}, #endif {"openssl", "aes128gcm", &ptls_openssl_aes128gcm, &ptls_minicrypto_sha256, 1}, - {"openssl", "aes256gcm", &ptls_openssl_aes256gcm, &ptls_minicrypto_sha384, 1}}; + {"openssl", "aes256gcm", &ptls_openssl_aes256gcm, &ptls_minicrypto_sha384, 1}, +#ifdef PTLS_HAVE_MBEDTLS + {"mbedtls", "aes128gcm",& ptls_mbedtls_aes128gcm,& ptls_mbedtls_sha256, 1}, +#if defined(MBEDTLS_SHA384_C) + { "mbedtls", "aes256gcm", &ptls_mbedtls_aes256gcm, &ptls_mbedtls_sha384, 1 }, +#endif + { "mbedtls", "chacha20poly1305", &ptls_mbedtls_chacha20poly1305, &ptls_mbedtls_sha256, 1 }, +#endif +}; static size_t nb_aead_list = sizeof(aead_list) / sizeof(ptls_bench_entry_t); @@ -323,6 +337,13 @@ int main(int argc, char **argv) } #endif +#ifdef PTLS_HAVE_MBEDTLS + if (psa_crypto_init() != PSA_SUCCESS) { + note("psa_crypto_init fails."); + exit(-1); + } +#endif + if (argc == 2 && strcmp(argv[1], "-f") == 0) { force_all_tests = 1; } else if (argc > 1) { @@ -346,5 +367,10 @@ int main(int argc, char **argv) printf("Unexpected value of test sum s = %llx\n", (unsigned long long)s); } +#ifdef PTLS_HAVE_MBEDTLS + /* Deinitialize the PSA crypto library. */ + mbedtls_psa_crypto_free(); +#endif + return ret; } From 833b34ae17c6a3d95db119a1cacc8f289b9cb44e Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Thu, 7 Sep 2023 12:50:43 -0700 Subject: [PATCH 31/84] Fix debug message --- t/ptlsbench.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/ptlsbench.c b/t/ptlsbench.c index 684d99c0d..c86c6d5bf 100644 --- a/t/ptlsbench.c +++ b/t/ptlsbench.c @@ -339,7 +339,7 @@ int main(int argc, char **argv) #ifdef PTLS_HAVE_MBEDTLS if (psa_crypto_init() != PSA_SUCCESS) { - note("psa_crypto_init fails."); + fprintf(stderr, "psa_crypto_init fails.\n"); exit(-1); } #endif From 8f1542d7badf692d640817f6eaf75d68e8c3c856 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Thu, 7 Sep 2023 13:16:55 -0700 Subject: [PATCH 32/84] Condition fusion to PTLS_HAVE_FUSION --- CMakeLists.txt | 3 ++- t/ptlsbench.c | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c4ffd50d7..a40ca4ad6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -197,7 +197,8 @@ 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 () diff --git a/t/ptlsbench.c b/t/ptlsbench.c index c86c6d5bf..8fdb6fdb7 100644 --- a/t/ptlsbench.c +++ b/t/ptlsbench.c @@ -36,8 +36,10 @@ #include "picotls/minicrypto.h" #include "picotls/openssl.h" #ifndef _WINDOWS +#ifdef PTLS_HAVE_FUSION #include "picotls/fusion.h" #endif +#endif #include #ifdef _WINDOWS @@ -268,9 +270,11 @@ static ptls_bench_entry_t aead_list[] = { {"ptlsbcrypt", "aes256gcm", &ptls_bcrypt_aes256gcm, &ptls_bcrypt_sha384, 1}, #endif #if !defined(_WINDOWS) +#ifdef PTLS_HAVE_FUSION {"fusion", "aes128gcm", &ptls_fusion_aes128gcm, &ptls_minicrypto_sha256, 1}, {"fusion", "aes256gcm", &ptls_fusion_aes256gcm, &ptls_minicrypto_sha384, 1}, #endif +#endif #if PTLS_OPENSSL_HAVE_CHACHA20_POLY1305 {"openssl", "chacha20poly1305", &ptls_openssl_chacha20poly1305, &ptls_minicrypto_sha256, 1}, #endif From 815a6b59afac56e3288c57d8ea50a9c362a8e724 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Thu, 7 Sep 2023 17:00:08 -0700 Subject: [PATCH 33/84] Declare cipher suites --- include/picotls/ptls_mbedtls.h | 7 +++++++ lib/ptls_mbedtls.c | 19 ++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/include/picotls/ptls_mbedtls.h b/include/picotls/ptls_mbedtls.h index 2d2790c04..279fa7cc4 100644 --- a/include/picotls/ptls_mbedtls.h +++ b/include/picotls/ptls_mbedtls.h @@ -43,6 +43,13 @@ extern ptls_aead_algorithm_t ptls_mbedtls_aes128gcm; extern ptls_aead_algorithm_t ptls_mbedtls_aes256gcm; extern ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305; + +extern ptls_cipher_suite_t ptls_mbedtls_aes128gcmsha256; +#if defined(MBEDTLS_SHA384_C) +extern ptls_cipher_suite_t ptls_mbedtls_aes256gcmsha384; +#endif +extern ptls_cipher_suite_t ptls_mbedtls_chacha20poly1305sha256; + #ifdef __cplusplus } #endif diff --git a/lib/ptls_mbedtls.c b/lib/ptls_mbedtls.c index d78ac14ec..b78aa3e69 100644 --- a/lib/ptls_mbedtls.c +++ b/lib/ptls_mbedtls.c @@ -766,4 +766,21 @@ ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305 = { 0, sizeof(struct ptls_mbedtls_aead_context_t), ptls_mbedtls_aead_setup_crypto -}; \ No newline at end of file +}; + +ptls_cipher_suite_t ptls_mbedtls_aes128gcmsha256 = {.id = PTLS_CIPHER_SUITE_AES_128_GCM_SHA256, +.name = PTLS_CIPHER_SUITE_NAME_AES_128_GCM_SHA256, +.aead = &ptls_mbedtls_aes128gcm, +.hash = &ptls_mbedtls_sha256}; + +#if defined(MBEDTLS_SHA384_C) +ptls_cipher_suite_t ptls_mbedtls_aes256gcmsha384 = {.id = PTLS_CIPHER_SUITE_AES_256_GCM_SHA384, +.name = PTLS_CIPHER_SUITE_NAME_AES_256_GCM_SHA384, +.aead = &ptls_mbedtls_aes256gcm, +.hash = &ptls_mbedtls_sha384}; +#endif + +ptls_cipher_suite_t ptls_mbedtls_chacha20poly1305sha256 = {.id = PTLS_CIPHER_SUITE_CHACHA20_POLY1305_SHA256, +.name = PTLS_CIPHER_SUITE_NAME_CHACHA20_POLY1305_SHA256, +.aead = &ptls_mbedtls_chacha20poly1305, +.hash = &ptls_mbedtls_sha256}; \ No newline at end of file From e922949c4fa6e0d46bc9f1f36710899be7ae0763 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Fri, 8 Sep 2023 13:44:32 -0700 Subject: [PATCH 34/84] Add support for MbedTLS random --- include/picotls/ptls_mbedtls.h | 2 ++ lib/ptls_mbedtls.c | 12 ++++++++++++ t/ptls_mbedtls.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/include/picotls/ptls_mbedtls.h b/include/picotls/ptls_mbedtls.h index 279fa7cc4..397a224b4 100644 --- a/include/picotls/ptls_mbedtls.h +++ b/include/picotls/ptls_mbedtls.h @@ -50,6 +50,8 @@ extern ptls_cipher_suite_t ptls_mbedtls_aes256gcmsha384; #endif extern ptls_cipher_suite_t ptls_mbedtls_chacha20poly1305sha256; +void ptls_mbedtls_random_bytes(void* buf, size_t len); + #ifdef __cplusplus } #endif diff --git a/lib/ptls_mbedtls.c b/lib/ptls_mbedtls.c index b78aa3e69..73e4df486 100644 --- a/lib/ptls_mbedtls.c +++ b/lib/ptls_mbedtls.c @@ -15,6 +15,18 @@ #include "mbedtls/aes.h" #include "mbedtls/chacha20.h" +/* Random number generator. +* This is a call to the PSA random number generator, which according +* to the documentation meets cryptographic requirements. +*/ + +void ptls_mbedtls_random_bytes(void* buf, size_t len) +{ + if (psa_generate_random((uint8_t*)buf, len) != 0) { + memset(buf, 0, len); + } +} + /* Definitions for hash algorithms. * In Picotls, these are described by the stucture * ptls_hash_algorithm_t, which include the function diff --git a/t/ptls_mbedtls.c b/t/ptls_mbedtls.c index 2bd5f73e3..0dec6fed9 100644 --- a/t/ptls_mbedtls.c +++ b/t/ptls_mbedtls.c @@ -37,6 +37,34 @@ #include "picotls/minicrypto.h" #include "../deps/picotest/picotest.h" +static int test_random() +{ + /* The random test is just trying to check that we call the API properly. + * This is done by getting a vector of 1021 bytes, computing the sum of + * all values, and comparing to theoretical min and max, + * computed as average +- 8*standard deviation for sum of 1021 terms. + * 8 random deviations results in an extremely low probability of random + * failure. + * Note that this does not actually test the random generator. + */ + + uint8_t buf[PTLS_MBEDTLS_RANDOM_TEST_LENGTH]; + uint64_t sum = 0; + const uint64_t max_sum_1021 = 149505; + const uint64_t min_sum_1021 = 110849; + int ret = 0; + + ptls_mbedtls_random_bytes(buf, PTLS_MBEDTLS_RANDOM_TEST_LENGTH); + for (size_t i = 0; i < PTLS_MBEDTLS_RANDOM_TEST_LENGTH; i++) { + sum += buf[i]; + } + if (sum > max_sum_1021 || sum < min_sum_1021) { + ret = -1; + } + + return ret; +} + static int hash_trial(ptls_hash_algorithm_t* algo, const uint8_t* input, size_t len1, size_t len2, uint8_t* final_hash) { int ret = 0; @@ -371,6 +399,8 @@ int main(int argc, char **argv) note("psa_crypto_init fails."); return done_testing(); } + /* Test of the port of the mbedtls random generator */ + subtest("random", test_random); /* Series of test to check consistency between wrapped mbedtls and minicrypto */ subtest("sha256", test_sha256); #if defined(MBEDTLS_SHA384_C) From 943c8a9a559ae7bb2f2002af99e3b3014db07259 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Tue, 12 Sep 2023 17:27:51 -0700 Subject: [PATCH 35/84] use high level PSA API --- include/picotls/ptls_mbedtls.h | 33 +- lib/ptls_mbedtls.c | 586 ++++++++++++++++++--------------- 2 files changed, 341 insertions(+), 278 deletions(-) diff --git a/include/picotls/ptls_mbedtls.h b/include/picotls/ptls_mbedtls.h index 397a224b4..93dba6e25 100644 --- a/include/picotls/ptls_mbedtls.h +++ b/include/picotls/ptls_mbedtls.h @@ -27,30 +27,25 @@ extern "C" { #endif #include "picotls.h" -extern ptls_hash_algorithm_t ptls_mbedtls_sha256; -extern ptls_hash_algorithm_t ptls_mbedtls_sha512; + extern ptls_hash_algorithm_t ptls_mbedtls_sha256; + extern ptls_hash_algorithm_t ptls_mbedtls_sha512; #if defined(MBEDTLS_SHA384_C) -extern ptls_hash_algorithm_t ptls_mbedtls_sha384; + extern ptls_hash_algorithm_t ptls_mbedtls_sha384; #endif -extern ptls_cipher_algorithm_t ptls_mbedtls_aes128ecb; -extern ptls_cipher_algorithm_t ptls_mbedtls_aes256ecb; -extern ptls_cipher_algorithm_t ptls_mbedtls_aes128ctr; -extern ptls_cipher_algorithm_t ptls_mbedtls_aes256ctr; -extern ptls_cipher_algorithm_t ptls_mbedtls_chacha20; + extern ptls_cipher_algorithm_t ptls_mbedtls_aes128ecb; + extern ptls_cipher_algorithm_t ptls_mbedtls_aes256ecb; + extern ptls_cipher_algorithm_t ptls_mbedtls_aes128ctr; + extern ptls_cipher_algorithm_t ptls_mbedtls_aes256ctr; + extern ptls_cipher_algorithm_t ptls_mbedtls_chacha20; -extern ptls_aead_algorithm_t ptls_mbedtls_aes128gcm; -extern ptls_aead_algorithm_t ptls_mbedtls_aes256gcm; -extern ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305; + extern ptls_aead_algorithm_t ptls_mbedtls_aes128gcm; + extern ptls_aead_algorithm_t ptls_mbedtls_aes256gcm; + extern ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305; - -extern ptls_cipher_suite_t ptls_mbedtls_aes128gcmsha256; -#if defined(MBEDTLS_SHA384_C) -extern ptls_cipher_suite_t ptls_mbedtls_aes256gcmsha384; -#endif -extern ptls_cipher_suite_t ptls_mbedtls_chacha20poly1305sha256; - -void ptls_mbedtls_random_bytes(void* buf, size_t len); + int ptls_mbedtls_init(); + void ptls_mbedtls_free(); + void ptls_mbedtls_random_bytes(void* buf, size_t len); #ifdef __cplusplus } diff --git a/lib/ptls_mbedtls.c b/lib/ptls_mbedtls.c index 73e4df486..a01f8902b 100644 --- a/lib/ptls_mbedtls.c +++ b/lib/ptls_mbedtls.c @@ -10,21 +10,37 @@ #include "mbedtls/build_info.h" #include "psa/crypto.h" #include "psa/crypto_struct.h" -#include "mbedtls/sha256.h" -#include "mbedtls/sha512.h" -#include "mbedtls/aes.h" + #include "mbedtls/chacha20.h" +#include "mbedtls/ecdh.h" + +/* Init and free functions. Init should be used before starting using +* library functions. Free should be used before leaving the program. +*/ + +void ptls_mbedtls_free() +{ + mbedtls_psa_crypto_free(); +} + +int ptls_mbedtls_init() +{ + int ret = 0; + psa_status_t status; + if ((status = psa_crypto_init()) != PSA_SUCCESS) { + ret = -1; + } + + return ret; +} /* Random number generator. * This is a call to the PSA random number generator, which according * to the documentation meets cryptographic requirements. */ - void ptls_mbedtls_random_bytes(void* buf, size_t len) { - if (psa_generate_random((uint8_t*)buf, len) != 0) { - memset(buf, 0, len); - } + psa_generate_random((uint8_t*)buf, len); } /* Definitions for hash algorithms. @@ -42,72 +58,85 @@ void ptls_mbedtls_random_bytes(void* buf, size_t len) * */ -typedef struct st_ptls_mbedtls_sha256_ctx_t { +typedef struct st_ptls_mbedtls_hash_ctx_t { ptls_hash_context_t super; - mbedtls_sha256_context mctx; -} ptls_mbedtls_sha256_ctx_t; + psa_algorithm_t alg; + size_t hash_size; + psa_hash_operation_t operation; +} ptls_mbedtls_hash_ctx_t; -static void ptls_mbedtls_sha256_update(struct st_ptls_hash_context_t* _ctx, const void* src, size_t len) +static void ptls_mbedtls_hash_update(struct st_ptls_hash_context_t* _ctx, const void* src, size_t len) { - ptls_mbedtls_sha256_ctx_t* ctx = (ptls_mbedtls_sha256_ctx_t*)_ctx; + ptls_mbedtls_hash_ctx_t* ctx = (ptls_mbedtls_hash_ctx_t*)_ctx; - (void)mbedtls_sha256_update(&ctx->mctx, (const uint8_t*)src, len); + (void) psa_hash_update(&ctx->operation, (const uint8_t *) src, len); } -static void ptls_mbedtls_sha256_final(struct st_ptls_hash_context_t* _ctx, void* md, ptls_hash_final_mode_t mode); +static void ptls_mbedtls_hash_final(struct st_ptls_hash_context_t* _ctx, void* md, ptls_hash_final_mode_t mode); -static struct st_ptls_hash_context_t* ptls_mbedtls_sha256_clone(struct st_ptls_hash_context_t* _src) +static struct st_ptls_hash_context_t* ptls_mbedtls_hash_clone(struct st_ptls_hash_context_t* _src) { - ptls_mbedtls_sha256_ctx_t* ctx = (ptls_mbedtls_sha256_ctx_t*)malloc(sizeof(ptls_mbedtls_sha256_ctx_t)); + ptls_mbedtls_hash_ctx_t* ctx = (ptls_mbedtls_hash_ctx_t*)malloc(sizeof(ptls_mbedtls_hash_ctx_t)); + const ptls_mbedtls_hash_ctx_t* src = (const ptls_mbedtls_hash_ctx_t*)_src; if (ctx != NULL) { - ptls_mbedtls_sha256_ctx_t* src = (ptls_mbedtls_sha256_ctx_t*)_src; - memset(&ctx->mctx, 0, sizeof(mbedtls_sha256_context)); - ctx->super.clone_ = ptls_mbedtls_sha256_clone; - ctx->super.update = ptls_mbedtls_sha256_update; - ctx->super.final = ptls_mbedtls_sha256_final; - mbedtls_sha256_clone(&ctx->mctx, &src->mctx); + ptls_mbedtls_hash_ctx_t* src = (ptls_mbedtls_hash_ctx_t*)_src; + memset(&ctx->operation, 0, sizeof(mbedtls_sha256_context)); + ctx->super.clone_ = ptls_mbedtls_hash_clone; + ctx->super.update = ptls_mbedtls_hash_update; + ctx->super.final = ptls_mbedtls_hash_final; + ctx->alg = src->alg; + ctx->hash_size = src->hash_size; + if (psa_hash_clone(&src->operation, &ctx->operation) != 0) { + free(ctx); + ctx = NULL; + } } return (ptls_hash_context_t*)ctx; } -static void ptls_mbedtls_sha256_final(struct st_ptls_hash_context_t* _ctx, void* md, ptls_hash_final_mode_t mode) +static void ptls_mbedtls_hash_final(struct st_ptls_hash_context_t* _ctx, void* md, ptls_hash_final_mode_t mode) { - ptls_mbedtls_sha256_ctx_t* ctx = (ptls_mbedtls_sha256_ctx_t*)_ctx; + ptls_mbedtls_hash_ctx_t* ctx = (ptls_mbedtls_hash_ctx_t*)_ctx; if (mode == PTLS_HASH_FINAL_MODE_SNAPSHOT) { - struct st_ptls_hash_context_t* cloned = ptls_mbedtls_sha256_clone(_ctx); + struct st_ptls_hash_context_t* cloned = ptls_mbedtls_hash_clone(_ctx); if (cloned != NULL) { - ptls_mbedtls_sha256_final(cloned, md, PTLS_HASH_FINAL_MODE_FREE); + ptls_mbedtls_hash_final(cloned, md, PTLS_HASH_FINAL_MODE_FREE); } } else { if (md != NULL) { - (void)mbedtls_sha256_finish(&ctx->mctx, (uint8_t*)md); + size_t hash_length = 0; + if (psa_hash_finish(&ctx->operation, md, ctx->hash_size, &hash_length) != 0) { + memset(md, 0, ctx->hash_size); + } } if (mode == PTLS_HASH_FINAL_MODE_FREE) { - mbedtls_sha256_free(&ctx->mctx); + (void)psa_hash_abort(&ctx->operation); free(ctx); } else { /* if mode = reset, reset the context */ - mbedtls_sha256_init(&ctx->mctx); - mbedtls_sha256_starts(&ctx->mctx, 0 /* is224 = 0 */); + memset(&ctx->operation, 0, sizeof(ctx->operation)); + (void)psa_hash_setup(&ctx->operation, ctx->alg); } } } -ptls_hash_context_t* ptls_mbedtls_sha256_create(void) +ptls_hash_context_t* ptls_mbedtls_hash_create(psa_algorithm_t alg, size_t hash_size) { - ptls_mbedtls_sha256_ctx_t* ctx = (ptls_mbedtls_sha256_ctx_t*)malloc(sizeof(ptls_mbedtls_sha256_ctx_t)); + ptls_mbedtls_hash_ctx_t* ctx = (ptls_mbedtls_hash_ctx_t*)malloc(sizeof(ptls_mbedtls_hash_ctx_t)); if (ctx != NULL) { - memset(&ctx->mctx, 0, sizeof(mbedtls_sha256_context)); - ctx->super.clone_ = ptls_mbedtls_sha256_clone; - ctx->super.update = ptls_mbedtls_sha256_update; - ctx->super.final = ptls_mbedtls_sha256_final; - if (mbedtls_sha256_starts(&ctx->mctx, 0 /* is224 = 0 */) != 0) { + memset(&ctx->operation, 0, sizeof(ctx->operation)); + ctx->alg = alg; + ctx->hash_size = hash_size; + ctx->super.clone_ = ptls_mbedtls_hash_clone; + ctx->super.update = ptls_mbedtls_hash_update; + ctx->super.final = ptls_mbedtls_hash_final; + if (psa_hash_setup(&ctx->operation, alg) != 0){ free(ctx); ctx = NULL; } @@ -115,96 +144,19 @@ ptls_hash_context_t* ptls_mbedtls_sha256_create(void) return (ptls_hash_context_t*)ctx; } -ptls_hash_algorithm_t ptls_mbedtls_sha256 = {"sha256", PTLS_SHA256_BLOCK_SIZE, PTLS_SHA256_DIGEST_SIZE, ptls_mbedtls_sha256_create, -PTLS_ZERO_DIGEST_SHA256}; - - -/* SHA 512 follows the same general architecture as SHA 256. - * The SHA 384 module is using the same code, with an option to - * deliver a shorter hash. - */ - - -typedef struct st_ptls_mbedtls_sha512_ctx_t { - ptls_hash_context_t super; - mbedtls_sha512_context mctx; - int is384; -} ptls_mbedtls_sha512_ctx_t; - -static void ptls_mbedtls_sha512_update(struct st_ptls_hash_context_t* _ctx, const void* src, size_t len) -{ - ptls_mbedtls_sha512_ctx_t* ctx = (ptls_mbedtls_sha512_ctx_t*)_ctx; - - (void)mbedtls_sha512_update(&ctx->mctx, (const uint8_t*)src, len); -} - -static void ptls_mbedtls_sha512_final(struct st_ptls_hash_context_t* _ctx, void* md, ptls_hash_final_mode_t mode); - -static struct st_ptls_hash_context_t* ptls_mbedtls_sha512_clone(struct st_ptls_hash_context_t* _src) +ptls_hash_context_t* ptls_mbedtls_sha256_create(void) { - ptls_mbedtls_sha512_ctx_t* ctx = (ptls_mbedtls_sha512_ctx_t*)malloc(sizeof(ptls_mbedtls_sha512_ctx_t)); - - if (ctx != NULL) { - ptls_mbedtls_sha512_ctx_t* src = (ptls_mbedtls_sha512_ctx_t*)_src; - memset(&ctx->mctx, 0, sizeof(mbedtls_sha512_context)); - ctx->super.clone_ = ptls_mbedtls_sha512_clone; - ctx->super.update = ptls_mbedtls_sha512_update; - ctx->super.final = ptls_mbedtls_sha512_final; - mbedtls_sha512_clone(&ctx->mctx, &src->mctx); - } - return (ptls_hash_context_t*)ctx; + return ptls_mbedtls_hash_create(PSA_ALG_SHA_256, PTLS_SHA256_DIGEST_SIZE); } -static void ptls_mbedtls_sha512_final(struct st_ptls_hash_context_t* _ctx, void* md, ptls_hash_final_mode_t mode) +ptls_hash_context_t* ptls_mbedtls_sha512_create(void) { - ptls_mbedtls_sha512_ctx_t* ctx = (ptls_mbedtls_sha512_ctx_t*)_ctx; - - if (mode == PTLS_HASH_FINAL_MODE_SNAPSHOT) { - struct st_ptls_hash_context_t* cloned = ptls_mbedtls_sha512_clone(_ctx); - - if (cloned != NULL) { - ptls_mbedtls_sha512_final(cloned, md, PTLS_HASH_FINAL_MODE_FREE); - } - } else { - if (md != NULL) { - (void)mbedtls_sha512_finish(&ctx->mctx, (uint8_t*)md); - } - - if (mode == PTLS_HASH_FINAL_MODE_FREE) { - mbedtls_sha512_free(&ctx->mctx); - free(ctx); - } - else { - /* if mode = reset, reset the context */ - mbedtls_sha512_init(&ctx->mctx); - mbedtls_sha512_starts(&ctx->mctx, ctx->is384); - } - } + return ptls_mbedtls_hash_create(PSA_ALG_SHA_512, PTLS_SHA512_DIGEST_SIZE); } -ptls_hash_context_t* ptls_mbedtls_sha512_384_create(int is384) -{ - ptls_mbedtls_sha512_ctx_t* ctx = (ptls_mbedtls_sha512_ctx_t*)malloc(sizeof(ptls_mbedtls_sha512_ctx_t)); - if (ctx != NULL) { - memset(&ctx->mctx, 0, sizeof(mbedtls_sha512_context)); - ctx->super.clone_ = ptls_mbedtls_sha512_clone; - ctx->super.update = ptls_mbedtls_sha512_update; - ctx->super.final = ptls_mbedtls_sha512_final; - ctx->is384 = is384; - - if (mbedtls_sha512_starts(&ctx->mctx, is384) != 0) { - free(ctx); - ctx = NULL; - } - } - return (ptls_hash_context_t*)ctx; -} - -ptls_hash_context_t* ptls_mbedtls_sha512_create(void) -{ - return ptls_mbedtls_sha512_384_create(0); -} +ptls_hash_algorithm_t ptls_mbedtls_sha256 = {"sha256", PTLS_SHA256_BLOCK_SIZE, PTLS_SHA256_DIGEST_SIZE, ptls_mbedtls_sha256_create, +PTLS_ZERO_DIGEST_SHA256}; ptls_hash_algorithm_t ptls_mbedtls_sha512 = {"SHA512", PTLS_SHA512_BLOCK_SIZE, PTLS_SHA512_DIGEST_SIZE, ptls_mbedtls_sha512_create, PTLS_ZERO_DIGEST_SHA512}; @@ -212,7 +164,7 @@ PTLS_ZERO_DIGEST_SHA512}; #if defined(MBEDTLS_SHA384_C) ptls_hash_context_t* ptls_mbedtls_sha384_create(void) { - return ptls_mbedtls_sha512_384_create(1); + return ptls_mbedtls_hash_create(PSA_ALG_SHA_384, PTLS_SHA384_DIGEST_SIZE); } ptls_hash_algorithm_t ptls_mbedtls_sha384 = {"SHA384", PTLS_SHA384_BLOCK_SIZE, @@ -220,179 +172,196 @@ PTLS_SHA384_DIGEST_SIZE, ptls_mbedtls_sha384_create, PTLS_ZERO_DIGEST_SHA384}; #endif /* MBEDTLS_SHA384_C */ -/* definitions for symmetric crypto algorithms. -* Each algorithm (ECB or CTR) is represented by an "algorithm" -* entry in which the 'setup" function is used to initialize -* The "setup" function creates an object of type -* ptls_cipher_context_t, with three function pointers: -* -* void (*do_dispose)(struct st_ptls_cipher_context_t *ctx); -* void (*do_init)(struct st_ptls_cipher_context_t *ctx, const void *iv); -* void (*do_transform)(struct st_ptls_cipher_context_t *ctx, void *output, const void *input, size_t len); -* -* "do_init" sets the IV value. In CTR mode, this is the nonce value, which -* will be incremented after each block. In CTR mode, this also sets the -* "stream block". -* - */ - -struct st_ptls_mbedtls_aes_context_t { +/* +* Generic implementation of a cipher using the PSA API +*/ +struct st_ptls_mbedtls_cipher_context_t { ptls_cipher_context_t super; - mbedtls_aes_context aes_ctx; - uint8_t nonce_counter[16]; - uint8_t stream_block[16]; - int is_enc; /* MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT */ + psa_algorithm_t alg; + size_t iv_length; + int is_enc; + int is_op_in_progress; + mbedtls_svc_key_id_t key; + psa_cipher_operation_t operation; }; -static void ptls_mbedtls_aes_ctr_init(ptls_cipher_context_t *_ctx, const void *iv) + +static void ptls_mbedtls_cipher_init(ptls_cipher_context_t *_ctx, const void *iv) { - struct st_ptls_mbedtls_aes_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; + struct st_ptls_mbedtls_cipher_context_t *ctx = (struct st_ptls_mbedtls_cipher_context_t *)_ctx; + + if (ctx->is_op_in_progress) { + psa_cipher_abort(&ctx->operation); + ctx->is_op_in_progress = 0; + } - if (iv == NULL) { - memset(ctx->nonce_counter, 0, 16); + memset(&ctx->operation, 0, sizeof(ctx->operation)); + if (ctx->is_enc) { + (void)psa_cipher_encrypt_setup(&ctx->operation, ctx->key, ctx->alg); } else { - memcpy(ctx->nonce_counter, iv, 16); + (void)psa_cipher_decrypt_setup(&ctx->operation, ctx->key, ctx->alg); } - memset(ctx->stream_block, 0, 16); -} - -static void ptls_mbedtls_aes_ecb_transform(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t len) -{ - struct st_ptls_mbedtls_aes_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; - - /* Call the encryption */ - if (mbedtls_aes_crypt_ecb(&ctx->aes_ctx, ctx->is_enc, (const uint8_t*)input, (uint8_t*)output) != 0) { - memset(output, 0, len); + if (ctx->iv_length > 0) { + (void)psa_cipher_set_iv(&ctx->operation, (const uint8_t*)iv, ctx->iv_length); } + ctx->is_op_in_progress = 1; } -static void ptls_mbedtls_aes_ctr_transform(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t len) +static void ptls_mbedtls_cipher_transform(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t len) { - struct st_ptls_mbedtls_aes_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; - size_t nc_off = 0; + struct st_ptls_mbedtls_cipher_context_t *ctx = (struct st_ptls_mbedtls_cipher_context_t *)_ctx; + size_t outlen = 0; - if (mbedtls_aes_crypt_ctr(&ctx->aes_ctx, len, &nc_off, ctx->nonce_counter, ctx->stream_block, - (const uint8_t*)input, (uint8_t*)output) != 0) { - memset(output, 0, len); - } + (void) psa_cipher_update(&ctx->operation, (const uint8_t*)input, len, (uint8_t*)output, len, &outlen); } -static void ptls_mbedtls_aes_ctr_dispose(ptls_cipher_context_t *_ctx) +static void ptls_mbedtls_cipher_dispose(ptls_cipher_context_t *_ctx) { - struct st_ptls_mbedtls_aes_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; - mbedtls_aes_free(&ctx->aes_ctx); + struct st_ptls_mbedtls_cipher_context_t *ctx = (struct st_ptls_mbedtls_cipher_context_t *)_ctx; + if (ctx->is_op_in_progress) { + psa_cipher_abort(&ctx->operation); + ctx->is_op_in_progress = 0; + } + psa_destroy_key(ctx->key); } -static int ptls_mbedtls_cipher_setup_crypto_aes(ptls_cipher_context_t* _ctx, int is_enc, const void* key, unsigned int keybits) +static int ptls_mbedtls_cipher_setup_key(mbedtls_svc_key_id_t* key_id, int is_enc, psa_algorithm_t alg, psa_key_type_t key_type, + size_t key_bits, uint8_t * key_bytes) { - struct st_ptls_mbedtls_aes_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; int ret = 0; - memset(ctx->nonce_counter, 0, 16); - memset(ctx->stream_block, 0, 16); - - ctx->super.do_dispose = ptls_mbedtls_aes_ctr_dispose; - ctx->super.do_init = ptls_mbedtls_aes_ctr_init; - ctx->super.do_transform = NULL; - - mbedtls_aes_init(&ctx->aes_ctx); - if (is_enc) { - ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, key, keybits); - ctx->is_enc = MBEDTLS_AES_ENCRYPT; - } - else { - ret = mbedtls_aes_setkey_dec(&ctx->aes_ctx, key, keybits); - ctx->is_enc = MBEDTLS_AES_DECRYPT; + psa_set_key_usage_flags(&attributes, + (is_enc)?PSA_KEY_USAGE_ENCRYPT:PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, key_type); + psa_set_key_bits(&attributes, key_bits); + /* Import key */ + if (psa_import_key(&attributes, key_bytes, key_bits / 8, + key_id) != PSA_SUCCESS) { + ret = PTLS_ERROR_LIBRARY; } return ret; - } -static int ptls_mbedtls_cipher_setup_crypto_aes128_ecb(ptls_cipher_context_t *_ctx, int is_enc, const void *key) +static int ptls_mbedtls_cipher_setup_crypto(ptls_cipher_context_t* _ctx, int is_enc, const void* key_bytes, + psa_algorithm_t alg, size_t iv_length, psa_key_type_t key_type, size_t key_bits) { - struct st_ptls_mbedtls_aes_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; - int ret = ptls_mbedtls_cipher_setup_crypto_aes(_ctx, is_enc, key, 128); + struct st_ptls_mbedtls_cipher_context_t *ctx = (struct st_ptls_mbedtls_cipher_context_t *)_ctx; + int ret = 0; - if (ret == 0) { - ctx->super.do_transform = ptls_mbedtls_aes_ecb_transform; - } + ctx->alg = alg; + ctx->is_enc = is_enc; + ctx->iv_length = iv_length; - return ret; -} + /* Initialize the key attributes */ + ret = ptls_mbedtls_cipher_setup_key(&ctx->key, is_enc, alg, key_type, key_bits, key_bytes); + /* Finish initializing the context */ + ctx->super.do_dispose = ptls_mbedtls_cipher_dispose; + ctx->super.do_init = ptls_mbedtls_cipher_init; + ctx->super.do_transform = NULL; -static int ptls_mbedtls_cipher_setup_crypto_aes128_ctr(ptls_cipher_context_t *_ctx, int is_enc, const void *key) -{ -#ifdef _WINDOWS - UNREFERENCED_PARAMETER(is_enc); -#endif - struct st_ptls_mbedtls_aes_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; - int ret = ptls_mbedtls_cipher_setup_crypto_aes(_ctx, 1, key, 128); /* No difference between CTR encrypt and decrypt */ if (ret == 0) { - ctx->super.do_transform = ptls_mbedtls_aes_ctr_transform; + ctx->super.do_transform = ptls_mbedtls_cipher_transform; } return ret; } -static int ptls_mbedtls_cipher_setup_crypto_aes256_ecb(ptls_cipher_context_t *_ctx, int is_enc, const void *key) +/* +* Implementation of AES128_ECB using the PSA API: +*/ +static int ptls_mbedtls_cipher_setup_aes128_ecb(ptls_cipher_context_t *_ctx, int is_enc, const void *key_bytes) { - struct st_ptls_mbedtls_aes_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; - int ret = ptls_mbedtls_cipher_setup_crypto_aes(_ctx, is_enc, key, 256); + return ptls_mbedtls_cipher_setup_crypto(_ctx, is_enc, key_bytes, + PSA_ALG_ECB_NO_PADDING, 0, PSA_KEY_TYPE_AES, 128); +} - if (ret == 0) { - ctx->super.do_transform = ptls_mbedtls_aes_ecb_transform; - } +ptls_cipher_algorithm_t ptls_mbedtls_aes128ecb = { + "AES128-ECB", + PTLS_AES128_KEY_SIZE, + PTLS_AES_BLOCK_SIZE, + 0 /* iv size */, + sizeof(struct st_ptls_mbedtls_cipher_context_t), + ptls_mbedtls_cipher_setup_aes128_ecb}; - return ret; +/* +* Implementation of AES256_ECB using the PSA API: +*/ +static int ptls_mbedtls_cipher_setup_aes256_ecb(ptls_cipher_context_t *_ctx, int is_enc, const void *key_bytes) +{ + return ptls_mbedtls_cipher_setup_crypto(_ctx, is_enc, key_bytes, + PSA_ALG_ECB_NO_PADDING, 0, PSA_KEY_TYPE_AES, 256); } -static int ptls_mbedtls_cipher_setup_crypto_aes256_ctr(ptls_cipher_context_t *_ctx, int is_enc, const void *key) -{ -#ifdef _WINDOWS - UNREFERENCED_PARAMETER(is_enc); -#endif - struct st_ptls_mbedtls_aes_context_t *ctx = (struct st_ptls_mbedtls_aes_context_t *)_ctx; - int ret = ptls_mbedtls_cipher_setup_crypto_aes(_ctx, 1, key, 256); /* No difference between CTR encrypt and decrypt */ +ptls_cipher_algorithm_t ptls_mbedtls_aes256ecb = { + "AES256-ECB", + PTLS_AES128_KEY_SIZE, + PTLS_AES_BLOCK_SIZE, + 0 /* iv size */, + sizeof(struct st_ptls_mbedtls_cipher_context_t), + ptls_mbedtls_cipher_setup_aes256_ecb}; - if (ret == 0) { - ctx->super.do_transform = ptls_mbedtls_aes_ctr_transform; - } +/* +* Implementation of AES128_CTR using the PSA API: +*/ - return ret; +static int ptls_mbedtls_cipher_setup_aes128_ctr(ptls_cipher_context_t *_ctx, int is_enc, const void *key_bytes) +{ + return ptls_mbedtls_cipher_setup_crypto(_ctx, is_enc, key_bytes, + PSA_ALG_CTR, 16, PSA_KEY_TYPE_AES, 128); } -ptls_cipher_algorithm_t ptls_mbedtls_aes128ecb = { - "AES128-ECB", +ptls_cipher_algorithm_t ptls_mbedtls_aes128ctr = { + "AES128-CTR", PTLS_AES128_KEY_SIZE, PTLS_AES_BLOCK_SIZE, - 0 /* iv size */, - sizeof(struct st_ptls_mbedtls_aes_context_t), - ptls_mbedtls_cipher_setup_crypto_aes128_ecb}; - -ptls_cipher_algorithm_t ptls_mbedtls_aes256ecb = {"AES256-ECB", -PTLS_AES256_KEY_SIZE, -PTLS_AES_BLOCK_SIZE, -0 /* iv size */, -sizeof(struct st_ptls_mbedtls_aes_context_t), -ptls_mbedtls_cipher_setup_crypto_aes256_ecb}; - -ptls_cipher_algorithm_t ptls_mbedtls_aes128ctr = {"AES128-CTR", -PTLS_AES128_KEY_SIZE, -PTLS_AES_BLOCK_SIZE, -0 /* iv size */, -sizeof(struct st_ptls_mbedtls_aes_context_t), -ptls_mbedtls_cipher_setup_crypto_aes128_ctr}; - -ptls_cipher_algorithm_t ptls_mbedtls_aes256ctr = {"AES256-CTR", -PTLS_AES256_KEY_SIZE, -PTLS_AES_BLOCK_SIZE, -0 /* iv size */, -sizeof(struct st_ptls_mbedtls_aes_context_t), -ptls_mbedtls_cipher_setup_crypto_aes256_ctr}; + 16 /* iv size */, + sizeof(struct st_ptls_mbedtls_cipher_context_t), + ptls_mbedtls_cipher_setup_aes128_ctr}; + +/* +* Implementation of AES128_CTR using the PSA API: +*/ +static int ptls_mbedtls_cipher_setup_aes256_ctr(ptls_cipher_context_t *_ctx, int is_enc, const void *key_bytes) +{ + return ptls_mbedtls_cipher_setup_crypto(_ctx, is_enc, key_bytes, + PSA_ALG_CTR, 16, PSA_KEY_TYPE_AES, 256); +} + +ptls_cipher_algorithm_t ptls_mbedtls_aes256ctr = { + "AES128-CTR", + PTLS_AES256_KEY_SIZE, + PTLS_AES_BLOCK_SIZE, + 16 /* iv size */, + sizeof(struct st_ptls_mbedtls_cipher_context_t), + ptls_mbedtls_cipher_setup_aes256_ctr}; + + +#if 0 +/* +* Implementation of CHACHA20 using the PSA API. +* This is disabled for now, as there seems to be an issue when +* setting the 16 bytes long IV that we need. +*/ +static int ptls_mbedtls_cipher_setup_crypto_chacha20(ptls_cipher_context_t *_ctx, int is_enc, const void *key_bytes) +{ + return ptls_mbedtls_cipher_setup_crypto(_ctx, is_enc, key_bytes, + PSA_ALG_STREAM_CIPHER, 16, PSA_KEY_TYPE_CHACHA20, 256); +} + +ptls_cipher_algorithm_t ptls_mbedtls_chacha20 = { + "CHACHA20", PTLS_CHACHA20_KEY_SIZE, 1 /* block size */, PTLS_CHACHA20_IV_SIZE, sizeof(struct st_ptls_mbedtls_cipher_context_t), + ptls_mbedtls_cipher_setup_crypto_chacha20}; +#else +/* Implementation of ChaCha20 using the low level ChaCha20 API. +* TODO: remove this and the reference to chacha20.h as soon as +* the IV bug in the generic implementation is fixed. +*/ struct st_ptls_mbedtls_chacha20_context_t { ptls_cipher_context_t super; mbedtls_chacha20_context mctx; @@ -445,7 +414,7 @@ static int ptls_mbedtls_cipher_setup_crypto_chacha20(ptls_cipher_context_t *_ctx ptls_cipher_algorithm_t ptls_mbedtls_chacha20 = { "CHACHA20", PTLS_CHACHA20_KEY_SIZE, 1 /* block size */, PTLS_CHACHA20_IV_SIZE, sizeof(struct st_ptls_mbedtls_chacha20_context_t), ptls_mbedtls_cipher_setup_crypto_chacha20}; - +#endif /* Definitions of AEAD algorithms. * @@ -780,19 +749,118 @@ ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305 = { ptls_mbedtls_aead_setup_crypto }; -ptls_cipher_suite_t ptls_mbedtls_aes128gcmsha256 = {.id = PTLS_CIPHER_SUITE_AES_128_GCM_SHA256, -.name = PTLS_CIPHER_SUITE_NAME_AES_128_GCM_SHA256, -.aead = &ptls_mbedtls_aes128gcm, -.hash = &ptls_mbedtls_sha256}; +/* Key exchange algorithms. +* The Picotls framework defines these algorithms as ptls_key_exchange_algorithm_t, +* a structure containing two function pointers: +* +* int (*create)(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **ctx); +* int (*exchange)(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_iovec_t *pubkey, ptls_iovec_t *secret, +* ptls_iovec_t peerkey); +* The "create" call is used on the client. It documents the ptls_key_exchange_context_t, which contains +* the public key prepared by the client, as an iovec, and a function pointer: +* +* int (*on_exchange)(struct st_ptls_key_exchange_context_t **keyex, int release, ptls_iovec_t *secret, ptls_iovec_t peerkey); +* +* The public key of the client is passed to the server an ends up as "peerkey" argument to the (exchange) function. +* That function documents the server's public key, and the secret coputed by combining server and client key. +* +* When the client receives the server hello, the stack calls the "on_exchange" callback, passing the context +* previously created by the client and the public key of the peer, so the client can compute its own +* version of the secret. +* +* The following code uses the MbedTLS API to create the "create", "exchange" and "on_exchange" functions. +*/ -#if defined(MBEDTLS_SHA384_C) -ptls_cipher_suite_t ptls_mbedtls_aes256gcmsha384 = {.id = PTLS_CIPHER_SUITE_AES_256_GCM_SHA384, -.name = PTLS_CIPHER_SUITE_NAME_AES_256_GCM_SHA384, -.aead = &ptls_mbedtls_aes256gcm, -.hash = &ptls_mbedtls_sha384}; +/* TODO: use the PSA API, +* psa_generate_key +* +*/ +#define PTLS_MBEDTLS_ECDH_PUBKEY_MAX 129 +#define TYPE_MBEDTLS_ECDH_UNCOMPRESSED_PUBLIC_KEY 4 + +struct ptls_mbedtls_ecdh_key_exchange_context_t { + ptls_key_exchange_context_t super; + mbedtls_ecdh_context ecdh_ctx; + uint8_t pub[PTLS_MBEDTLS_ECDH_PUBKEY_MAX]; +}; + +#if 0 +static int ptls_mbedtls_ecdh_gen_public(struct ptls_mbedtls_ecdh_key_exchange_context_t * ctx) +{ + int ret = 0; + ret = mbedtls_ecdh_setup(&ctx->ecdh_ctx, ctx->group_id /* MBEDTLS_ECP_DP_CURVE25519 */); + if (ret == 0) { + ret = mbedtls_ecdh_make_params(&ctx->ecdh_ctx, &cli_olen, cli_to_srv, + sizeof(cli_to_srv), + mbedtls_ctr_drbg_random, &ptls_mbedtls_ctr_drbg); + } +} #endif -ptls_cipher_suite_t ptls_mbedtls_chacha20poly1305sha256 = {.id = PTLS_CIPHER_SUITE_CHACHA20_POLY1305_SHA256, -.name = PTLS_CIPHER_SUITE_NAME_CHACHA20_POLY1305_SHA256, -.aead = &ptls_mbedtls_chacha20poly1305, -.hash = &ptls_mbedtls_sha256}; \ No newline at end of file +static int ptls_mbedtls_exchange_id_from_tls(int tls_id) +{ + int mbedtls_id = MBEDTLS_ECP_DP_NONE; + switch (tls_id) { + case PTLS_GROUP_SECP256R1: + mbedtls_id = MBEDTLS_ECP_DP_SECP256R1; + break; + case PTLS_GROUP_SECP384R1: + mbedtls_id = MBEDTLS_ECP_DP_SECP384R1; + break; + case PTLS_GROUP_SECP521R1: + mbedtls_id = MBEDTLS_ECP_DP_SECP521R1; + break; + case PTLS_GROUP_X25519: + mbedtls_id = MBEDTLS_ECP_DP_CURVE25519; + break; + case PTLS_GROUP_X448: + mbedtls_id = MBEDTLS_ECP_DP_CURVE448; + break; + default: + break; + } + return mbedtls_id; +} + +#if 0 +static int ptls_mbedtls_ecdh_on_exchange( + struct st_ptls_key_exchange_context_t** keyex, int release, ptls_iovec_t* secret, ptls_iovec_t peerkey) +{ + +} + +static int ptls_mbedtls_ecdh_create(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **keyex) +{ + /* TODO: simplify */ + struct ptls_mbedtls_ecdh_key_exchange_context_t *ctx; + int ret = 0; + int mbedtls_id = ptls_mbedtls_exchange_id_from_tls(algo->id); + + if (mbedtls_id == MBEDTLS_ECP_DP_NONE) { + return PTLS_ERROR_NOT_AVAILABLE; + } + if ((ctx = (struct ptls_mbedtls_ecdh_key_exchange_context_t*)malloc(sizeof(*ctx))) == NULL) { + return PTLS_ERROR_NO_MEMORY; + } + ctx->super = (ptls_key_exchange_context_t){algo, ptls_iovec_init(ctx->pub, sizeof(ctx->pub)), ptls_mbedtls_ecdh_on_exchange}; + ret = mbedtls_ecdh_setup(&ctx->ecdh_ctx, mbedtls_id); + ctx->pub[0] = TYPE_MBEDTLS_ECDH_UNCOMPRESSED_PUBLIC_KEY; + + + + + return 0; + + + + + + + + if (ret == 0) { + ret = mbedtls_ecdh_make_params(&ctx->ecdh_ctx, &cli_olen, cli_to_srv, + sizeof(cli_to_srv), + mbedtls_ctr_drbg_random, &ptls_mbedtls_ctr_drbg); + } +} +#endif \ No newline at end of file From c112fc51029f0fcf234cd5c09095494594a9219a Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Tue, 12 Sep 2023 18:58:06 -0700 Subject: [PATCH 36/84] Fix test random --- t/ptls_mbedtls.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/t/ptls_mbedtls.c b/t/ptls_mbedtls.c index 0dec6fed9..f472f83b5 100644 --- a/t/ptls_mbedtls.c +++ b/t/ptls_mbedtls.c @@ -37,7 +37,9 @@ #include "picotls/minicrypto.h" #include "../deps/picotest/picotest.h" -static int test_random() +#define PTLS_MBEDTLS_RANDOM_TEST_LENGTH 1021; + +static int random_trial() { /* The random test is just trying to check that we call the API properly. * This is done by getting a vector of 1021 bytes, computing the sum of @@ -65,6 +67,15 @@ static int test_random() return ret; } +static void test_random(void) +{ + if (random_trial() != 0) { + ok(!"fail"); + return; + } + ok(!!"success"); +} + static int hash_trial(ptls_hash_algorithm_t* algo, const uint8_t* input, size_t len1, size_t len2, uint8_t* final_hash) { int ret = 0; From d91376594fdf69e31ded906acf97eacc0b00d996 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Tue, 12 Sep 2023 19:02:48 -0700 Subject: [PATCH 37/84] Fix typo --- t/ptls_mbedtls.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/t/ptls_mbedtls.c b/t/ptls_mbedtls.c index f472f83b5..ebd1d8c86 100644 --- a/t/ptls_mbedtls.c +++ b/t/ptls_mbedtls.c @@ -37,8 +37,6 @@ #include "picotls/minicrypto.h" #include "../deps/picotest/picotest.h" -#define PTLS_MBEDTLS_RANDOM_TEST_LENGTH 1021; - static int random_trial() { /* The random test is just trying to check that we call the API properly. @@ -50,14 +48,14 @@ static int random_trial() * Note that this does not actually test the random generator. */ - uint8_t buf[PTLS_MBEDTLS_RANDOM_TEST_LENGTH]; + uint8_t buf[1021]; uint64_t sum = 0; const uint64_t max_sum_1021 = 149505; const uint64_t min_sum_1021 = 110849; int ret = 0; - ptls_mbedtls_random_bytes(buf, PTLS_MBEDTLS_RANDOM_TEST_LENGTH); - for (size_t i = 0; i < PTLS_MBEDTLS_RANDOM_TEST_LENGTH; i++) { + ptls_mbedtls_random_bytes(buf, sizeof(buf)); + for (size_t i = 0; i < sizeof(buf); i++) { sum += buf[i]; } if (sum > max_sum_1021 || sum < min_sum_1021) { From 0a3dccb5aca4627a5e287af998b6cb6f5ad8f585 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 13 Sep 2023 22:38:37 -0700 Subject: [PATCH 38/84] Add code of sec256r1 --- include/picotls/ptls_mbedtls.h | 2 + lib/ptls_mbedtls.c | 209 +++++++++++++++++++++++---------- 2 files changed, 150 insertions(+), 61 deletions(-) diff --git a/include/picotls/ptls_mbedtls.h b/include/picotls/ptls_mbedtls.h index 93dba6e25..aff76ae31 100644 --- a/include/picotls/ptls_mbedtls.h +++ b/include/picotls/ptls_mbedtls.h @@ -43,6 +43,8 @@ extern "C" { extern ptls_aead_algorithm_t ptls_mbedtls_aes256gcm; extern ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305; + extern ptls_key_exchange_algorithm_t ptls_mbedtls_secp256r1; + int ptls_mbedtls_init(); void ptls_mbedtls_free(); void ptls_mbedtls_random_bytes(void* buf, size_t len); diff --git a/lib/ptls_mbedtls.c b/lib/ptls_mbedtls.c index a01f8902b..b48de0c48 100644 --- a/lib/ptls_mbedtls.c +++ b/lib/ptls_mbedtls.c @@ -10,8 +10,10 @@ #include "mbedtls/build_info.h" #include "psa/crypto.h" #include "psa/crypto_struct.h" +#include "psa/crypto_values.h" #include "mbedtls/chacha20.h" + #include "mbedtls/ecdh.h" /* Init and free functions. Init should be used before starting using @@ -227,7 +229,7 @@ static void ptls_mbedtls_cipher_dispose(ptls_cipher_context_t *_ctx) } static int ptls_mbedtls_cipher_setup_key(mbedtls_svc_key_id_t* key_id, int is_enc, psa_algorithm_t alg, psa_key_type_t key_type, - size_t key_bits, uint8_t * key_bytes) + size_t key_bits, const uint8_t * key_bytes) { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; int ret = 0; @@ -257,7 +259,7 @@ static int ptls_mbedtls_cipher_setup_crypto(ptls_cipher_context_t* _ctx, int is_ ctx->iv_length = iv_length; /* Initialize the key attributes */ - ret = ptls_mbedtls_cipher_setup_key(&ctx->key, is_enc, alg, key_type, key_bits, key_bytes); + ret = ptls_mbedtls_cipher_setup_key(&ctx->key, is_enc, alg, key_type, key_bits, (const uint8_t *)key_bytes); /* Finish initializing the context */ ctx->super.do_dispose = ptls_mbedtls_cipher_dispose; ctx->super.do_init = ptls_mbedtls_cipher_init; @@ -762,7 +764,7 @@ ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305 = { * int (*on_exchange)(struct st_ptls_key_exchange_context_t **keyex, int release, ptls_iovec_t *secret, ptls_iovec_t peerkey); * * The public key of the client is passed to the server an ends up as "peerkey" argument to the (exchange) function. -* That function documents the server's public key, and the secret coputed by combining server and client key. +* That function documents the server's public key, and the secret computed by combining server and client key. * * When the client receives the server hello, the stack calls the "on_exchange" callback, passing the context * previously created by the client and the public key of the peer, so the client can compute its own @@ -778,89 +780,174 @@ ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305 = { #define PTLS_MBEDTLS_ECDH_PUBKEY_MAX 129 #define TYPE_MBEDTLS_ECDH_UNCOMPRESSED_PUBLIC_KEY 4 -struct ptls_mbedtls_ecdh_key_exchange_context_t { +struct ptls_mbedtls_key_exchange_context_t { ptls_key_exchange_context_t super; - mbedtls_ecdh_context ecdh_ctx; + psa_algorithm_t psa_alg; + psa_ecc_family_t curve; + size_t curve_bits; + size_t secret_size; + psa_key_id_t private_key; uint8_t pub[PTLS_MBEDTLS_ECDH_PUBKEY_MAX]; }; -#if 0 -static int ptls_mbedtls_ecdh_gen_public(struct ptls_mbedtls_ecdh_key_exchange_context_t * ctx) +/* Set a private key for key exchange. For now, we only support ECC +*/ + +static int ptls_mbedtls_key_exchange_set_private_key(psa_key_id_t * private_key, + psa_algorithm_t psa_alg, psa_ecc_family_t curve, size_t curve_bits) { + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; int ret = 0; - ret = mbedtls_ecdh_setup(&ctx->ecdh_ctx, ctx->group_id /* MBEDTLS_ECP_DP_CURVE25519 */); - if (ret == 0) { - ret = mbedtls_ecdh_make_params(&ctx->ecdh_ctx, &cli_olen, cli_to_srv, - sizeof(cli_to_srv), - mbedtls_ctr_drbg_random, &ptls_mbedtls_ctr_drbg); + + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE); + psa_set_key_algorithm(&attributes, psa_alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve) ); + psa_set_key_bits(&attributes, curve_bits); + if (psa_generate_key(&attributes, private_key) != 0) { + ret = -1; } + return ret; } -#endif -static int ptls_mbedtls_exchange_id_from_tls(int tls_id) -{ - int mbedtls_id = MBEDTLS_ECP_DP_NONE; - switch (tls_id) { - case PTLS_GROUP_SECP256R1: - mbedtls_id = MBEDTLS_ECP_DP_SECP256R1; - break; - case PTLS_GROUP_SECP384R1: - mbedtls_id = MBEDTLS_ECP_DP_SECP384R1; - break; - case PTLS_GROUP_SECP521R1: - mbedtls_id = MBEDTLS_ECP_DP_SECP521R1; - break; - case PTLS_GROUP_X25519: - mbedtls_id = MBEDTLS_ECP_DP_CURVE25519; - break; - case PTLS_GROUP_X448: - mbedtls_id = MBEDTLS_ECP_DP_CURVE448; - break; - default: - break; - } - return mbedtls_id; +/* +* The key agreement is done by calling psa_raw_key_agreement +psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, +psa_key_id_t private_key, +const uint8_t * peer_key, +size_t peer_key_length, +uint8_t * output, +size_t output_size, +size_t * output_length); +*/ + +int ptls_mbedtls_key_exchange_on_exchange(struct st_ptls_key_exchange_context_t** _pctx, int release, ptls_iovec_t* secret, ptls_iovec_t peerkey) +{ + int ret = 0; + struct ptls_mbedtls_key_exchange_context_t *keyex = (struct ptls_mbedtls_key_exchange_context_t *)*_pctx; + + if (secret != NULL) { + uint8_t* secbytes = (uint8_t*)malloc(keyex->secret_size); + + if (secbytes == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + } + else { + size_t olen; + if (psa_raw_key_agreement(keyex->psa_alg, keyex->private_key, (const uint8_t*)peerkey.base, peerkey.len, + secbytes, keyex->secret_size, &olen) == 0) { + *secret = ptls_iovec_init(secbytes, keyex->secret_size); + } + else { + free(secbytes); + ret = PTLS_ERROR_LIBRARY; + } + } + } + if (release) { + /* Clear the private key */ + psa_destroy_key(keyex->private_key); + /* Set context to NULL */ + *_pctx = NULL; + /* TODO: check whether allocated memory should be freed */ + } + + return ret; } -#if 0 -static int ptls_mbedtls_ecdh_on_exchange( - struct st_ptls_key_exchange_context_t** keyex, int release, ptls_iovec_t* secret, ptls_iovec_t peerkey) +int ptls_mbedtls_key_exchange_create(const struct st_ptls_key_exchange_algorithm_t* algo, ptls_key_exchange_context_t** ctx, + psa_algorithm_t psa_alg, psa_ecc_family_t curve, size_t curve_bits, size_t secret_size) { + struct ptls_mbedtls_key_exchange_context_t *keyex; + size_t olen = 0; + if ((keyex = (struct ptls_mbedtls_key_exchange_context_t *)malloc(sizeof(struct ptls_mbedtls_key_exchange_context_t))) == NULL) + return PTLS_ERROR_NO_MEMORY; + /* Initialize the exchange context based on the algorithm definition */ + keyex->psa_alg = psa_alg; + keyex->curve = curve; + keyex->curve_bits = curve_bits; + keyex->secret_size = secret_size; + /* Initialize the private key and format the public key */ + if (ptls_mbedtls_key_exchange_set_private_key(&keyex->private_key, psa_alg, curve, curve_bits) != 0){ + free(keyex); + *ctx = NULL; + return PTLS_ERROR_LIBRARY; + } + /* According to the doc, format of public key is same as picotls */ + if (psa_export_public_key(keyex->private_key, keyex->pub, sizeof(keyex->pub), &olen) != 0) { + psa_destroy_key(keyex->private_key); + free(keyex); + *ctx = NULL; + return PTLS_ERROR_LIBRARY; + } + keyex->super.pubkey= ptls_iovec_init(keyex->pub, olen); + /* Initialize the ptls exchange context */ + keyex->super.algo = algo; + keyex->super.on_exchange = ptls_mbedtls_key_exchange_on_exchange; + *ctx = (ptls_key_exchange_context_t*)keyex; + return 0; } -static int ptls_mbedtls_ecdh_create(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **keyex) +static int ptls_mbedtls_key_exchange_exchange(const struct st_ptls_key_exchange_algorithm_t* algo, ptls_iovec_t* pubkey, ptls_iovec_t* secret, + ptls_iovec_t peerkey, psa_algorithm_t psa_alg, psa_ecc_family_t curve, size_t curve_bits, size_t secret_size) { - /* TODO: simplify */ - struct ptls_mbedtls_ecdh_key_exchange_context_t *ctx; + /* generate a local private key for the selected algorithm */ + psa_key_id_t private_key; + size_t pubkey_len; + uint8_t* pubkey_bytes = NULL; + size_t secret_len; + uint8_t* secret_bytes = (uint8_t*)malloc(secret_size); int ret = 0; - int mbedtls_id = ptls_mbedtls_exchange_id_from_tls(algo->id); - if (mbedtls_id == MBEDTLS_ECP_DP_NONE) { - return PTLS_ERROR_NOT_AVAILABLE; + if (secret_bytes == NULL) { + return PTLS_ERROR_NO_MEMORY; } - if ((ctx = (struct ptls_mbedtls_ecdh_key_exchange_context_t*)malloc(sizeof(*ctx))) == NULL) { + pubkey_bytes = (uint8_t*)malloc(PTLS_MBEDTLS_ECDH_PUBKEY_MAX); + if (pubkey_bytes == NULL){ + free(secret_bytes); return PTLS_ERROR_NO_MEMORY; } - ctx->super = (ptls_key_exchange_context_t){algo, ptls_iovec_init(ctx->pub, sizeof(ctx->pub)), ptls_mbedtls_ecdh_on_exchange}; - ret = mbedtls_ecdh_setup(&ctx->ecdh_ctx, mbedtls_id); - ctx->pub[0] = TYPE_MBEDTLS_ECDH_UNCOMPRESSED_PUBLIC_KEY; - - - - - return 0; - + if (ptls_mbedtls_key_exchange_set_private_key(&private_key, psa_alg, curve, curve_bits) != 0) { + free(secret_bytes); + free(pubkey_bytes); + return PTLS_ERROR_LIBRARY; + } + /* Export public key and call key agrement function */ + if (psa_export_public_key(private_key, pubkey_bytes, PTLS_MBEDTLS_ECDH_PUBKEY_MAX, &pubkey_len) == 0 && + psa_raw_key_agreement(psa_alg, private_key, (const uint8_t*)peerkey.base, peerkey.len, + secret_bytes, secret_size, &secret_len) == 0) { + *secret = ptls_iovec_init(secret_bytes, secret_len); + *pubkey = ptls_iovec_init(pubkey_bytes, pubkey_len); + } + else { + free(secret_bytes); + free(pubkey_bytes); + return PTLS_ERROR_LIBRARY; + } + psa_destroy_key(private_key); + return ret; +} +/* Instantiation of the generic API with secp256r1 +*/ +static int ptls_mbedtls_secp256r1_create(const struct st_ptls_key_exchange_algorithm_t* algo, ptls_key_exchange_context_t** ctx) +{ + return ptls_mbedtls_key_exchange_create(algo, ctx, + PSA_ALG_ECDH, PSA_ECC_FAMILY_SECP_R1, 256, 32); +} - if (ret == 0) { - ret = mbedtls_ecdh_make_params(&ctx->ecdh_ctx, &cli_olen, cli_to_srv, - sizeof(cli_to_srv), - mbedtls_ctr_drbg_random, &ptls_mbedtls_ctr_drbg); - } +static int ptls_mbedtls_secp256r1_exchange(const struct st_ptls_key_exchange_algorithm_t* algo, ptls_iovec_t* pubkey, ptls_iovec_t* secret, + ptls_iovec_t peerkey) +{ + return ptls_mbedtls_key_exchange_exchange(algo, pubkey, secret, peerkey, + PSA_ALG_ECDH, PSA_ECC_FAMILY_SECP_R1, 256, 32); } -#endif \ No newline at end of file + +ptls_key_exchange_algorithm_t ptls_mbedtls_secp256r1 = {.id = PTLS_GROUP_SECP256R1, +.name = PTLS_GROUP_NAME_SECP256R1, +.create = ptls_mbedtls_secp256r1_create, +.exchange = ptls_mbedtls_secp256r1_exchange}; \ No newline at end of file From 1c24153be3f8f68cca85bd5454aa6e26cb7aee94 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Wed, 13 Sep 2023 23:08:17 -0700 Subject: [PATCH 39/84] Simplify aead setup --- lib/ptls_mbedtls.c | 58 +++++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 34 deletions(-) diff --git a/lib/ptls_mbedtls.c b/lib/ptls_mbedtls.c index b48de0c48..32a13f4ae 100644 --- a/lib/ptls_mbedtls.c +++ b/lib/ptls_mbedtls.c @@ -625,37 +625,17 @@ size_t ptls_mbedtls_aead_do_decrypt(struct st_ptls_aead_context_t* _ctx, void* o return o_len; } -static int ptls_mbedtls_aead_setup_crypto(ptls_aead_context_t *_ctx, int is_enc, const void *key_bytes, const void *iv) +static int ptls_mbedtls_aead_setup_crypto(ptls_aead_context_t *_ctx, int is_enc, const void *key_bytes, const void *iv, + psa_algorithm_t psa_alg, size_t key_bits, psa_key_type_t key_type) { int ret = 0; struct ptls_mbedtls_aead_context_t* ctx = (struct ptls_mbedtls_aead_context_t*)_ctx; - size_t key_bits; - psa_key_type_t key_type; + /* set mbed specific context to NULL, just to be sure */ memset(&ctx->mctx, 0, sizeof(struct ptls_mbedtls_aead_param_t)); - - /* deduce the PSA algorithm from the name */ - if (strcmp(ctx->super.algo->name, "AES128-GCM") == 0) { - ctx->mctx.alg = PSA_ALG_GCM; - key_bits = 128; - key_type = PSA_KEY_TYPE_AES; - } else if (strcmp(ctx->super.algo->name, "AES256-GCM") == 0) { - ctx->mctx.alg = PSA_ALG_GCM; - key_bits = 256; - key_type = PSA_KEY_TYPE_AES; - } else if (strcmp(ctx->super.algo->name, "AES128-GCM_8") == 0) { - ctx->mctx.alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 8); - key_bits = 128; - key_type = PSA_KEY_TYPE_AES; - } else if (strcmp(ctx->super.algo->name, "CHACHA20-POLY1305") == 0) { - ctx->mctx.alg = PSA_ALG_CHACHA20_POLY1305; - key_bits = 256; - key_type = PSA_KEY_TYPE_CHACHA20; - } else { - ret = PTLS_ERROR_LIBRARY; - } + ctx->mctx.alg = psa_alg; /* Initialize the key attributes */ if (ret == 0) { @@ -703,6 +683,11 @@ static int ptls_mbedtls_aead_setup_crypto(ptls_aead_context_t *_ctx, int is_enc, return ret; } +static int ptls_mbedtls_aead_setup_aes128gcm(ptls_aead_context_t* _ctx, int is_enc, const void* key_bytes, const void* iv) +{ + return ptls_mbedtls_aead_setup_crypto(_ctx, is_enc, key_bytes, iv, PSA_ALG_GCM, 128, PSA_KEY_TYPE_AES); +} + ptls_aead_algorithm_t ptls_mbedtls_aes128gcm = { "AES128-GCM", PTLS_AESGCM_CONFIDENTIALITY_LIMIT, @@ -716,9 +701,14 @@ ptls_aead_algorithm_t ptls_mbedtls_aes128gcm = { 0, 0, sizeof(struct ptls_mbedtls_aead_context_t), - ptls_mbedtls_aead_setup_crypto + ptls_mbedtls_aead_setup_aes128gcm }; +static int ptls_mbedtls_aead_setup_aes256gcm(ptls_aead_context_t* _ctx, int is_enc, const void* key_bytes, const void* iv) +{ + return ptls_mbedtls_aead_setup_crypto(_ctx, is_enc, key_bytes, iv, PSA_ALG_GCM, 256, PSA_KEY_TYPE_AES); +} + ptls_aead_algorithm_t ptls_mbedtls_aes256gcm = { "AES256-GCM", PTLS_AESGCM_CONFIDENTIALITY_LIMIT, @@ -732,9 +722,14 @@ ptls_aead_algorithm_t ptls_mbedtls_aes256gcm = { 0, 0, sizeof(struct ptls_mbedtls_aead_context_t), - ptls_mbedtls_aead_setup_crypto + ptls_mbedtls_aead_setup_aes256gcm }; +static int ptls_mbedtls_aead_setup_chacha20poly1305(ptls_aead_context_t* _ctx, int is_enc, const void* key_bytes, const void* iv) +{ + return ptls_mbedtls_aead_setup_crypto(_ctx, is_enc, key_bytes, iv, PSA_ALG_CHACHA20_POLY1305, 256, PSA_KEY_TYPE_CHACHA20); +} + ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305 = { "CHACHA20-POLY1305", PTLS_CHACHA20POLY1305_CONFIDENTIALITY_LIMIT, @@ -748,7 +743,7 @@ ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305 = { 0, 0, sizeof(struct ptls_mbedtls_aead_context_t), - ptls_mbedtls_aead_setup_crypto + ptls_mbedtls_aead_setup_chacha20poly1305 }; /* Key exchange algorithms. @@ -770,15 +765,10 @@ ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305 = { * previously created by the client and the public key of the peer, so the client can compute its own * version of the secret. * -* The following code uses the MbedTLS API to create the "create", "exchange" and "on_exchange" functions. +* The following code uses the MbedTLS PSA API to create the "create", "exchange" and "on_exchange" functions. */ -/* TODO: use the PSA API, -* psa_generate_key -* -*/ -#define PTLS_MBEDTLS_ECDH_PUBKEY_MAX 129 -#define TYPE_MBEDTLS_ECDH_UNCOMPRESSED_PUBLIC_KEY 4 +#define PTLS_MBEDTLS_ECDH_PUBKEY_MAX 129 struct ptls_mbedtls_key_exchange_context_t { ptls_key_exchange_context_t super; From 3cd437be3c576c7781693d5fb19406167de1e0c6 Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Thu, 14 Sep 2023 12:38:42 -0700 Subject: [PATCH 40/84] Add x25519 --- include/picotls/ptls_mbedtls.h | 5 +++ lib/ptls_mbedtls.c | 62 ++++++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/include/picotls/ptls_mbedtls.h b/include/picotls/ptls_mbedtls.h index aff76ae31..b35ad39d3 100644 --- a/include/picotls/ptls_mbedtls.h +++ b/include/picotls/ptls_mbedtls.h @@ -43,7 +43,12 @@ extern "C" { extern ptls_aead_algorithm_t ptls_mbedtls_aes256gcm; extern ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305; + extern ptls_cipher_suite_t ptls_mbedtls_aes128gcmsha256; + extern ptls_cipher_suite_t ptls_mbedtls_aes256gcmsha384; + extern ptls_cipher_suite_t ptls_mbedtls_chacha20poly1305sha256; + extern ptls_key_exchange_algorithm_t ptls_mbedtls_secp256r1; + extern ptls_key_exchange_algorithm_t ptls_mbedtls_x25519; int ptls_mbedtls_init(); void ptls_mbedtls_free(); diff --git a/lib/ptls_mbedtls.c b/lib/ptls_mbedtls.c index 32a13f4ae..c38cfd0ec 100644 --- a/lib/ptls_mbedtls.c +++ b/lib/ptls_mbedtls.c @@ -1,3 +1,25 @@ +/* +* Copyright (c) 2023, Christian Huitema +* +* 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 _WINDOWS #include "wincompat.h" #endif @@ -704,6 +726,11 @@ ptls_aead_algorithm_t ptls_mbedtls_aes128gcm = { ptls_mbedtls_aead_setup_aes128gcm }; +ptls_cipher_suite_t ptls_mbedtls_aes128gcmsha256 = {.id = PTLS_CIPHER_SUITE_AES_128_GCM_SHA256, +.name = PTLS_CIPHER_SUITE_NAME_AES_128_GCM_SHA256, +.aead = &ptls_mbedtls_aes128gcm, +.hash = &ptls_mbedtls_sha256}; + static int ptls_mbedtls_aead_setup_aes256gcm(ptls_aead_context_t* _ctx, int is_enc, const void* key_bytes, const void* iv) { return ptls_mbedtls_aead_setup_crypto(_ctx, is_enc, key_bytes, iv, PSA_ALG_GCM, 256, PSA_KEY_TYPE_AES); @@ -725,6 +752,12 @@ ptls_aead_algorithm_t ptls_mbedtls_aes256gcm = { ptls_mbedtls_aead_setup_aes256gcm }; +ptls_cipher_suite_t ptls_mbedtls_aes256gcmsha384 = { + .id = PTLS_CIPHER_SUITE_AES_256_GCM_SHA384, + .name = PTLS_CIPHER_SUITE_NAME_AES_256_GCM_SHA384, + .aead = &ptls_mbedtls_aes256gcm, + .hash = &ptls_mbedtls_sha384}; + static int ptls_mbedtls_aead_setup_chacha20poly1305(ptls_aead_context_t* _ctx, int is_enc, const void* key_bytes, const void* iv) { return ptls_mbedtls_aead_setup_crypto(_ctx, is_enc, key_bytes, iv, PSA_ALG_CHACHA20_POLY1305, 256, PSA_KEY_TYPE_CHACHA20); @@ -746,6 +779,11 @@ ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305 = { ptls_mbedtls_aead_setup_chacha20poly1305 }; +ptls_cipher_suite_t ptls_mbedtls_chacha20poly1305sha256 = {.id = PTLS_CIPHER_SUITE_CHACHA20_POLY1305_SHA256, +.name = PTLS_CIPHER_SUITE_NAME_CHACHA20_POLY1305_SHA256, +.aead = &ptls_mbedtls_chacha20poly1305, +.hash = &ptls_mbedtls_sha256}; + /* Key exchange algorithms. * The Picotls framework defines these algorithms as ptls_key_exchange_algorithm_t, * a structure containing two function pointers: @@ -922,7 +960,7 @@ static int ptls_mbedtls_key_exchange_exchange(const struct st_ptls_key_exchange_ return ret; } -/* Instantiation of the generic API with secp256r1 +/* Instantiation of the generic key exchange API with secp256r1 */ static int ptls_mbedtls_secp256r1_create(const struct st_ptls_key_exchange_algorithm_t* algo, ptls_key_exchange_context_t** ctx) { @@ -940,4 +978,24 @@ static int ptls_mbedtls_secp256r1_exchange(const struct st_ptls_key_exchange_alg ptls_key_exchange_algorithm_t ptls_mbedtls_secp256r1 = {.id = PTLS_GROUP_SECP256R1, .name = PTLS_GROUP_NAME_SECP256R1, .create = ptls_mbedtls_secp256r1_create, -.exchange = ptls_mbedtls_secp256r1_exchange}; \ No newline at end of file +.exchange = ptls_mbedtls_secp256r1_exchange}; + +/* Instantiation of the generic key exchange API with x25519 +*/ +static int ptls_mbedtls_x25519_create(const struct st_ptls_key_exchange_algorithm_t* algo, ptls_key_exchange_context_t** ctx) +{ + return ptls_mbedtls_key_exchange_create(algo, ctx, + PSA_ALG_ECDH, PSA_ECC_FAMILY_MONTGOMERY, 255, 32); +} + +static int ptls_mbedtls_x25519_exchange(const struct st_ptls_key_exchange_algorithm_t* algo, ptls_iovec_t* pubkey, ptls_iovec_t* secret, + ptls_iovec_t peerkey) +{ + return ptls_mbedtls_key_exchange_exchange(algo, pubkey, secret, peerkey, + PSA_ALG_ECDH, PSA_ECC_FAMILY_MONTGOMERY, 255, 32); +} + +ptls_key_exchange_algorithm_t ptls_mbedtls_x25519 = {.id = PTLS_GROUP_X25519, +.name = PTLS_GROUP_NAME_X25519, +.create = ptls_mbedtls_x25519_create, +.exchange = ptls_mbedtls_x25519_exchange}; From eec837c34f578370199740b42500f8a5e70dc1ab Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Thu, 14 Sep 2023 13:42:28 -0700 Subject: [PATCH 41/84] Add test of mbedtls key exchanges --- t/ptls_mbedtls.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/t/ptls_mbedtls.c b/t/ptls_mbedtls.c index ebd1d8c86..ac6ea9ba6 100644 --- a/t/ptls_mbedtls.c +++ b/t/ptls_mbedtls.c @@ -36,6 +36,7 @@ #include "picotls/ptls_mbedtls.h" #include "picotls/minicrypto.h" #include "../deps/picotest/picotest.h" +#include "test.h" static int random_trial() { @@ -401,6 +402,24 @@ static void test_chacha20poly1305_sha256(void) ok(!!"success"); } +static void test_secp256r1(void) +{ + test_key_exchange(&ptls_mbedtls_secp256r1, &ptls_minicrypto_secp256r1); + test_key_exchange(&ptls_minicrypto_secp256r1, &ptls_mbedtls_secp256r1); +} + +static void test_x25519(void) +{ + test_key_exchange(&ptls_mbedtls_x25519, &ptls_minicrypto_x25519); + test_key_exchange(&ptls_minicrypto_x25519, &ptls_mbedtls_x25519); +} + +static void test_key_exchanges(void) +{ + subtest("secp256r1", test_secp256r1); + subtest("x25519", test_x25519); +} + int main(int argc, char **argv) { /* Initialize the PSA crypto library. */ @@ -426,6 +445,7 @@ int main(int argc, char **argv) subtest("aes256gcm_sha384", test_aes256gcm_sha384); #endif subtest("chacha20poly1305_sha256", test_chacha20poly1305_sha256); + subtest("key_exchanges", test_key_exchanges); /* Deinitialize the PSA crypto library. */ mbedtls_psa_crypto_free(); From cc9364ed5014c86b3da67f9da35a682c160698fd Mon Sep 17 00:00:00 2001 From: Christian Huitema Date: Thu, 14 Sep 2023 14:43:50 -0700 Subject: [PATCH 42/84] Fix reference to test_key_exchange --- t/ptls_mbedtls.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/t/ptls_mbedtls.c b/t/ptls_mbedtls.c index ac6ea9ba6..61815b016 100644 --- a/t/ptls_mbedtls.c +++ b/t/ptls_mbedtls.c @@ -36,7 +36,6 @@ #include "picotls/ptls_mbedtls.h" #include "picotls/minicrypto.h" #include "../deps/picotest/picotest.h" -#include "test.h" static int random_trial() { @@ -402,6 +401,42 @@ static void test_chacha20poly1305_sha256(void) ok(!!"success"); } +/* Test key exchange. This is a cut and paste of the "test_key_exchange" + * defined in test.h and openssl.c, because referring to that common code + * causes a link error. + */ +static void test_key_exchange(ptls_key_exchange_algorithm_t *client, ptls_key_exchange_algorithm_t *server) +{ + ptls_key_exchange_context_t *ctx; + ptls_iovec_t client_secret, server_pubkey, server_secret; + int ret; + + /* fail */ + ret = server->exchange(server, &server_pubkey, &server_secret, (ptls_iovec_t){NULL}); + ok(ret != 0); + + /* perform ecdh */ + ret = client->create(client, &ctx); + ok(ret == 0); + ret = server->exchange(server, &server_pubkey, &server_secret, ctx->pubkey); + ok(ret == 0); + ret = ctx->on_exchange(&ctx, 1, &client_secret, server_pubkey); + ok(ret == 0); + ok(client_secret.len == server_secret.len); + ok(memcmp(client_secret.base, server_secret.base, client_secret.len) == 0); + + free(client_secret.base); + free(server_pubkey.base); + free(server_secret.base); + + /* client abort */ + ret = client->create(client, &ctx); + ok(ret == 0); + ret = ctx->on_exchange(&ctx, 1, NULL, ptls_iovec_init(NULL, 0)); + ok(ret == 0); + ok(ctx == NULL); +} + static void test_secp256r1(void) { test_key_exchange(&ptls_mbedtls_secp256r1, &ptls_minicrypto_secp256r1); From 07b73c943b6c60c763f57283ff45b405719e9141 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Fri, 3 Nov 2023 18:30:54 +0900 Subject: [PATCH 43/84] clang-format --- include/picotls/ptls_mbedtls.h | 78 ++-- lib/ptls_mbedtls.c | 673 +++++++++++++++------------------ t/ptls_mbedtls.c | 116 +++--- t/ptlsbench.c | 6 +- 4 files changed, 414 insertions(+), 459 deletions(-) diff --git a/include/picotls/ptls_mbedtls.h b/include/picotls/ptls_mbedtls.h index b35ad39d3..ac16ab221 100644 --- a/include/picotls/ptls_mbedtls.h +++ b/include/picotls/ptls_mbedtls.h @@ -1,24 +1,24 @@ /* -* Copyright (c) 2023, Christian Huitema -* -* 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. -*/ + * Copyright (c) 2023, Christian Huitema + * + * 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 picotls_mbedtls_h #define picotls_mbedtls_h @@ -27,32 +27,32 @@ extern "C" { #endif #include "picotls.h" - extern ptls_hash_algorithm_t ptls_mbedtls_sha256; - extern ptls_hash_algorithm_t ptls_mbedtls_sha512; +extern ptls_hash_algorithm_t ptls_mbedtls_sha256; +extern ptls_hash_algorithm_t ptls_mbedtls_sha512; #if defined(MBEDTLS_SHA384_C) - extern ptls_hash_algorithm_t ptls_mbedtls_sha384; +extern ptls_hash_algorithm_t ptls_mbedtls_sha384; #endif - extern ptls_cipher_algorithm_t ptls_mbedtls_aes128ecb; - extern ptls_cipher_algorithm_t ptls_mbedtls_aes256ecb; - extern ptls_cipher_algorithm_t ptls_mbedtls_aes128ctr; - extern ptls_cipher_algorithm_t ptls_mbedtls_aes256ctr; - extern ptls_cipher_algorithm_t ptls_mbedtls_chacha20; +extern ptls_cipher_algorithm_t ptls_mbedtls_aes128ecb; +extern ptls_cipher_algorithm_t ptls_mbedtls_aes256ecb; +extern ptls_cipher_algorithm_t ptls_mbedtls_aes128ctr; +extern ptls_cipher_algorithm_t ptls_mbedtls_aes256ctr; +extern ptls_cipher_algorithm_t ptls_mbedtls_chacha20; - extern ptls_aead_algorithm_t ptls_mbedtls_aes128gcm; - extern ptls_aead_algorithm_t ptls_mbedtls_aes256gcm; - extern ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305; +extern ptls_aead_algorithm_t ptls_mbedtls_aes128gcm; +extern ptls_aead_algorithm_t ptls_mbedtls_aes256gcm; +extern ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305; - extern ptls_cipher_suite_t ptls_mbedtls_aes128gcmsha256; - extern ptls_cipher_suite_t ptls_mbedtls_aes256gcmsha384; - extern ptls_cipher_suite_t ptls_mbedtls_chacha20poly1305sha256; +extern ptls_cipher_suite_t ptls_mbedtls_aes128gcmsha256; +extern ptls_cipher_suite_t ptls_mbedtls_aes256gcmsha384; +extern ptls_cipher_suite_t ptls_mbedtls_chacha20poly1305sha256; - extern ptls_key_exchange_algorithm_t ptls_mbedtls_secp256r1; - extern ptls_key_exchange_algorithm_t ptls_mbedtls_x25519; +extern ptls_key_exchange_algorithm_t ptls_mbedtls_secp256r1; +extern ptls_key_exchange_algorithm_t ptls_mbedtls_x25519; - int ptls_mbedtls_init(); - void ptls_mbedtls_free(); - void ptls_mbedtls_random_bytes(void* buf, size_t len); +int ptls_mbedtls_init(); +void ptls_mbedtls_free(); +void ptls_mbedtls_random_bytes(void *buf, size_t len); #ifdef __cplusplus } diff --git a/lib/ptls_mbedtls.c b/lib/ptls_mbedtls.c index c38cfd0ec..ea9ca1b0e 100644 --- a/lib/ptls_mbedtls.c +++ b/lib/ptls_mbedtls.c @@ -1,24 +1,24 @@ /* -* Copyright (c) 2023, Christian Huitema -* -* 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. -*/ + * Copyright (c) 2023, Christian Huitema + * + * 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 _WINDOWS #include "wincompat.h" @@ -39,8 +39,8 @@ #include "mbedtls/ecdh.h" /* Init and free functions. Init should be used before starting using -* library functions. Free should be used before leaving the program. -*/ + * library functions. Free should be used before leaving the program. + */ void ptls_mbedtls_free() { @@ -59,28 +59,28 @@ int ptls_mbedtls_init() } /* Random number generator. -* This is a call to the PSA random number generator, which according -* to the documentation meets cryptographic requirements. -*/ -void ptls_mbedtls_random_bytes(void* buf, size_t len) + * This is a call to the PSA random number generator, which according + * to the documentation meets cryptographic requirements. + */ +void ptls_mbedtls_random_bytes(void *buf, size_t len) { - psa_generate_random((uint8_t*)buf, len); + psa_generate_random((uint8_t *)buf, len); } /* Definitions for hash algorithms. -* In Picotls, these are described by the stucture -* ptls_hash_algorithm_t, which include the function -* pointer for creation of the hash context. -* -* The structure contains a function pointer to the -* "create" function that creates a hash operation, -* which itself contains three function pointers: -* -* void (*update)(struct st_ptls_hash_context_t *ctx, const void *src, size_t len); -* void (*final)(struct st_ptls_hash_context_t *ctx, void *md, ptls_hash_final_mode_t mode); -* struct st_ptls_hash_context_t *(*clone_)(struct st_ptls_hash_context_t *src); -* -*/ + * In Picotls, these are described by the stucture + * ptls_hash_algorithm_t, which include the function + * pointer for creation of the hash context. + * + * The structure contains a function pointer to the + * "create" function that creates a hash operation, + * which itself contains three function pointers: + * + * void (*update)(struct st_ptls_hash_context_t *ctx, const void *src, size_t len); + * void (*final)(struct st_ptls_hash_context_t *ctx, void *md, ptls_hash_final_mode_t mode); + * struct st_ptls_hash_context_t *(*clone_)(struct st_ptls_hash_context_t *src); + * + */ typedef struct st_ptls_mbedtls_hash_ctx_t { ptls_hash_context_t super; @@ -89,22 +89,22 @@ typedef struct st_ptls_mbedtls_hash_ctx_t { psa_hash_operation_t operation; } ptls_mbedtls_hash_ctx_t; -static void ptls_mbedtls_hash_update(struct st_ptls_hash_context_t* _ctx, const void* src, size_t len) +static void ptls_mbedtls_hash_update(struct st_ptls_hash_context_t *_ctx, const void *src, size_t len) { - ptls_mbedtls_hash_ctx_t* ctx = (ptls_mbedtls_hash_ctx_t*)_ctx; + ptls_mbedtls_hash_ctx_t *ctx = (ptls_mbedtls_hash_ctx_t *)_ctx; - (void) psa_hash_update(&ctx->operation, (const uint8_t *) src, len); + (void)psa_hash_update(&ctx->operation, (const uint8_t *)src, len); } -static void ptls_mbedtls_hash_final(struct st_ptls_hash_context_t* _ctx, void* md, ptls_hash_final_mode_t mode); +static void ptls_mbedtls_hash_final(struct st_ptls_hash_context_t *_ctx, void *md, ptls_hash_final_mode_t mode); -static struct st_ptls_hash_context_t* ptls_mbedtls_hash_clone(struct st_ptls_hash_context_t* _src) +static struct st_ptls_hash_context_t *ptls_mbedtls_hash_clone(struct st_ptls_hash_context_t *_src) { - ptls_mbedtls_hash_ctx_t* ctx = (ptls_mbedtls_hash_ctx_t*)malloc(sizeof(ptls_mbedtls_hash_ctx_t)); - const ptls_mbedtls_hash_ctx_t* src = (const ptls_mbedtls_hash_ctx_t*)_src; + ptls_mbedtls_hash_ctx_t *ctx = (ptls_mbedtls_hash_ctx_t *)malloc(sizeof(ptls_mbedtls_hash_ctx_t)); + const ptls_mbedtls_hash_ctx_t *src = (const ptls_mbedtls_hash_ctx_t *)_src; if (ctx != NULL) { - ptls_mbedtls_hash_ctx_t* src = (ptls_mbedtls_hash_ctx_t*)_src; + ptls_mbedtls_hash_ctx_t *src = (ptls_mbedtls_hash_ctx_t *)_src; memset(&ctx->operation, 0, sizeof(mbedtls_sha256_context)); ctx->super.clone_ = ptls_mbedtls_hash_clone; ctx->super.update = ptls_mbedtls_hash_update; @@ -116,15 +116,15 @@ static struct st_ptls_hash_context_t* ptls_mbedtls_hash_clone(struct st_ptls_has ctx = NULL; } } - return (ptls_hash_context_t*)ctx; + return (ptls_hash_context_t *)ctx; } -static void ptls_mbedtls_hash_final(struct st_ptls_hash_context_t* _ctx, void* md, ptls_hash_final_mode_t mode) +static void ptls_mbedtls_hash_final(struct st_ptls_hash_context_t *_ctx, void *md, ptls_hash_final_mode_t mode) { - ptls_mbedtls_hash_ctx_t* ctx = (ptls_mbedtls_hash_ctx_t*)_ctx; + ptls_mbedtls_hash_ctx_t *ctx = (ptls_mbedtls_hash_ctx_t *)_ctx; if (mode == PTLS_HASH_FINAL_MODE_SNAPSHOT) { - struct st_ptls_hash_context_t* cloned = ptls_mbedtls_hash_clone(_ctx); + struct st_ptls_hash_context_t *cloned = ptls_mbedtls_hash_clone(_ctx); if (cloned != NULL) { ptls_mbedtls_hash_final(cloned, md, PTLS_HASH_FINAL_MODE_FREE); @@ -140,8 +140,7 @@ static void ptls_mbedtls_hash_final(struct st_ptls_hash_context_t* _ctx, void* m if (mode == PTLS_HASH_FINAL_MODE_FREE) { (void)psa_hash_abort(&ctx->operation); free(ctx); - } - else { + } else { /* if mode = reset, reset the context */ memset(&ctx->operation, 0, sizeof(ctx->operation)); (void)psa_hash_setup(&ctx->operation, ctx->alg); @@ -149,9 +148,9 @@ static void ptls_mbedtls_hash_final(struct st_ptls_hash_context_t* _ctx, void* m } } -ptls_hash_context_t* ptls_mbedtls_hash_create(psa_algorithm_t alg, size_t hash_size) +ptls_hash_context_t *ptls_mbedtls_hash_create(psa_algorithm_t alg, size_t hash_size) { - ptls_mbedtls_hash_ctx_t* ctx = (ptls_mbedtls_hash_ctx_t*)malloc(sizeof(ptls_mbedtls_hash_ctx_t)); + ptls_mbedtls_hash_ctx_t *ctx = (ptls_mbedtls_hash_ctx_t *)malloc(sizeof(ptls_mbedtls_hash_ctx_t)); if (ctx != NULL) { memset(&ctx->operation, 0, sizeof(ctx->operation)); @@ -160,45 +159,43 @@ ptls_hash_context_t* ptls_mbedtls_hash_create(psa_algorithm_t alg, size_t hash_s ctx->super.clone_ = ptls_mbedtls_hash_clone; ctx->super.update = ptls_mbedtls_hash_update; ctx->super.final = ptls_mbedtls_hash_final; - if (psa_hash_setup(&ctx->operation, alg) != 0){ + if (psa_hash_setup(&ctx->operation, alg) != 0) { free(ctx); ctx = NULL; } } - return (ptls_hash_context_t*)ctx; + return (ptls_hash_context_t *)ctx; } -ptls_hash_context_t* ptls_mbedtls_sha256_create(void) +ptls_hash_context_t *ptls_mbedtls_sha256_create(void) { return ptls_mbedtls_hash_create(PSA_ALG_SHA_256, PTLS_SHA256_DIGEST_SIZE); } -ptls_hash_context_t* ptls_mbedtls_sha512_create(void) +ptls_hash_context_t *ptls_mbedtls_sha512_create(void) { return ptls_mbedtls_hash_create(PSA_ALG_SHA_512, PTLS_SHA512_DIGEST_SIZE); } - ptls_hash_algorithm_t ptls_mbedtls_sha256 = {"sha256", PTLS_SHA256_BLOCK_SIZE, PTLS_SHA256_DIGEST_SIZE, ptls_mbedtls_sha256_create, -PTLS_ZERO_DIGEST_SHA256}; + PTLS_ZERO_DIGEST_SHA256}; ptls_hash_algorithm_t ptls_mbedtls_sha512 = {"SHA512", PTLS_SHA512_BLOCK_SIZE, PTLS_SHA512_DIGEST_SIZE, ptls_mbedtls_sha512_create, -PTLS_ZERO_DIGEST_SHA512}; + PTLS_ZERO_DIGEST_SHA512}; #if defined(MBEDTLS_SHA384_C) -ptls_hash_context_t* ptls_mbedtls_sha384_create(void) +ptls_hash_context_t *ptls_mbedtls_sha384_create(void) { return ptls_mbedtls_hash_create(PSA_ALG_SHA_384, PTLS_SHA384_DIGEST_SIZE); } -ptls_hash_algorithm_t ptls_mbedtls_sha384 = {"SHA384", PTLS_SHA384_BLOCK_SIZE, -PTLS_SHA384_DIGEST_SIZE, ptls_mbedtls_sha384_create, -PTLS_ZERO_DIGEST_SHA384}; +ptls_hash_algorithm_t ptls_mbedtls_sha384 = {"SHA384", PTLS_SHA384_BLOCK_SIZE, PTLS_SHA384_DIGEST_SIZE, ptls_mbedtls_sha384_create, + PTLS_ZERO_DIGEST_SHA384}; #endif /* MBEDTLS_SHA384_C */ /* -* Generic implementation of a cipher using the PSA API -*/ + * Generic implementation of a cipher using the PSA API + */ struct st_ptls_mbedtls_cipher_context_t { ptls_cipher_context_t super; psa_algorithm_t alg; @@ -209,7 +206,6 @@ struct st_ptls_mbedtls_cipher_context_t { psa_cipher_operation_t operation; }; - static void ptls_mbedtls_cipher_init(ptls_cipher_context_t *_ctx, const void *iv) { struct st_ptls_mbedtls_cipher_context_t *ctx = (struct st_ptls_mbedtls_cipher_context_t *)_ctx; @@ -222,12 +218,11 @@ static void ptls_mbedtls_cipher_init(ptls_cipher_context_t *_ctx, const void *iv memset(&ctx->operation, 0, sizeof(ctx->operation)); if (ctx->is_enc) { (void)psa_cipher_encrypt_setup(&ctx->operation, ctx->key, ctx->alg); - } - else { + } else { (void)psa_cipher_decrypt_setup(&ctx->operation, ctx->key, ctx->alg); } if (ctx->iv_length > 0) { - (void)psa_cipher_set_iv(&ctx->operation, (const uint8_t*)iv, ctx->iv_length); + (void)psa_cipher_set_iv(&ctx->operation, (const uint8_t *)iv, ctx->iv_length); } ctx->is_op_in_progress = 1; } @@ -237,7 +232,7 @@ static void ptls_mbedtls_cipher_transform(ptls_cipher_context_t *_ctx, void *out struct st_ptls_mbedtls_cipher_context_t *ctx = (struct st_ptls_mbedtls_cipher_context_t *)_ctx; size_t outlen = 0; - (void) psa_cipher_update(&ctx->operation, (const uint8_t*)input, len, (uint8_t*)output, len, &outlen); + (void)psa_cipher_update(&ctx->operation, (const uint8_t *)input, len, (uint8_t *)output, len, &outlen); } static void ptls_mbedtls_cipher_dispose(ptls_cipher_context_t *_ctx) @@ -250,28 +245,26 @@ static void ptls_mbedtls_cipher_dispose(ptls_cipher_context_t *_ctx) psa_destroy_key(ctx->key); } -static int ptls_mbedtls_cipher_setup_key(mbedtls_svc_key_id_t* key_id, int is_enc, psa_algorithm_t alg, psa_key_type_t key_type, - size_t key_bits, const uint8_t * key_bytes) +static int ptls_mbedtls_cipher_setup_key(mbedtls_svc_key_id_t *key_id, int is_enc, psa_algorithm_t alg, psa_key_type_t key_type, + size_t key_bits, const uint8_t *key_bytes) { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; int ret = 0; - psa_set_key_usage_flags(&attributes, - (is_enc)?PSA_KEY_USAGE_ENCRYPT:PSA_KEY_USAGE_DECRYPT); + psa_set_key_usage_flags(&attributes, (is_enc) ? PSA_KEY_USAGE_ENCRYPT : PSA_KEY_USAGE_DECRYPT); psa_set_key_algorithm(&attributes, alg); psa_set_key_type(&attributes, key_type); psa_set_key_bits(&attributes, key_bits); /* Import key */ - if (psa_import_key(&attributes, key_bytes, key_bits / 8, - key_id) != PSA_SUCCESS) { + if (psa_import_key(&attributes, key_bytes, key_bits / 8, key_id) != PSA_SUCCESS) { ret = PTLS_ERROR_LIBRARY; } return ret; } -static int ptls_mbedtls_cipher_setup_crypto(ptls_cipher_context_t* _ctx, int is_enc, const void* key_bytes, - psa_algorithm_t alg, size_t iv_length, psa_key_type_t key_type, size_t key_bits) +static int ptls_mbedtls_cipher_setup_crypto(ptls_cipher_context_t *_ctx, int is_enc, const void *key_bytes, psa_algorithm_t alg, + size_t iv_length, psa_key_type_t key_type, size_t key_bits) { struct st_ptls_mbedtls_cipher_context_t *ctx = (struct st_ptls_mbedtls_cipher_context_t *)_ctx; int ret = 0; @@ -287,7 +280,6 @@ static int ptls_mbedtls_cipher_setup_crypto(ptls_cipher_context_t* _ctx, int is_ ctx->super.do_init = ptls_mbedtls_cipher_init; ctx->super.do_transform = NULL; - if (ret == 0) { ctx->super.do_transform = ptls_mbedtls_cipher_transform; } @@ -296,75 +288,66 @@ static int ptls_mbedtls_cipher_setup_crypto(ptls_cipher_context_t* _ctx, int is_ } /* -* Implementation of AES128_ECB using the PSA API: -*/ + * Implementation of AES128_ECB using the PSA API: + */ static int ptls_mbedtls_cipher_setup_aes128_ecb(ptls_cipher_context_t *_ctx, int is_enc, const void *key_bytes) { - return ptls_mbedtls_cipher_setup_crypto(_ctx, is_enc, key_bytes, - PSA_ALG_ECB_NO_PADDING, 0, PSA_KEY_TYPE_AES, 128); + return ptls_mbedtls_cipher_setup_crypto(_ctx, is_enc, key_bytes, PSA_ALG_ECB_NO_PADDING, 0, PSA_KEY_TYPE_AES, 128); } -ptls_cipher_algorithm_t ptls_mbedtls_aes128ecb = { - "AES128-ECB", - PTLS_AES128_KEY_SIZE, - PTLS_AES_BLOCK_SIZE, - 0 /* iv size */, - sizeof(struct st_ptls_mbedtls_cipher_context_t), - ptls_mbedtls_cipher_setup_aes128_ecb}; +ptls_cipher_algorithm_t ptls_mbedtls_aes128ecb = {"AES128-ECB", + PTLS_AES128_KEY_SIZE, + PTLS_AES_BLOCK_SIZE, + 0 /* iv size */, + sizeof(struct st_ptls_mbedtls_cipher_context_t), + ptls_mbedtls_cipher_setup_aes128_ecb}; /* -* Implementation of AES256_ECB using the PSA API: -*/ + * Implementation of AES256_ECB using the PSA API: + */ static int ptls_mbedtls_cipher_setup_aes256_ecb(ptls_cipher_context_t *_ctx, int is_enc, const void *key_bytes) { - return ptls_mbedtls_cipher_setup_crypto(_ctx, is_enc, key_bytes, - PSA_ALG_ECB_NO_PADDING, 0, PSA_KEY_TYPE_AES, 256); + return ptls_mbedtls_cipher_setup_crypto(_ctx, is_enc, key_bytes, PSA_ALG_ECB_NO_PADDING, 0, PSA_KEY_TYPE_AES, 256); } -ptls_cipher_algorithm_t ptls_mbedtls_aes256ecb = { - "AES256-ECB", - PTLS_AES128_KEY_SIZE, - PTLS_AES_BLOCK_SIZE, - 0 /* iv size */, - sizeof(struct st_ptls_mbedtls_cipher_context_t), - ptls_mbedtls_cipher_setup_aes256_ecb}; +ptls_cipher_algorithm_t ptls_mbedtls_aes256ecb = {"AES256-ECB", + PTLS_AES128_KEY_SIZE, + PTLS_AES_BLOCK_SIZE, + 0 /* iv size */, + sizeof(struct st_ptls_mbedtls_cipher_context_t), + ptls_mbedtls_cipher_setup_aes256_ecb}; /* -* Implementation of AES128_CTR using the PSA API: -*/ + * Implementation of AES128_CTR using the PSA API: + */ static int ptls_mbedtls_cipher_setup_aes128_ctr(ptls_cipher_context_t *_ctx, int is_enc, const void *key_bytes) { - return ptls_mbedtls_cipher_setup_crypto(_ctx, is_enc, key_bytes, - PSA_ALG_CTR, 16, PSA_KEY_TYPE_AES, 128); + return ptls_mbedtls_cipher_setup_crypto(_ctx, is_enc, key_bytes, PSA_ALG_CTR, 16, PSA_KEY_TYPE_AES, 128); } -ptls_cipher_algorithm_t ptls_mbedtls_aes128ctr = { - "AES128-CTR", - PTLS_AES128_KEY_SIZE, - PTLS_AES_BLOCK_SIZE, - 16 /* iv size */, - sizeof(struct st_ptls_mbedtls_cipher_context_t), - ptls_mbedtls_cipher_setup_aes128_ctr}; +ptls_cipher_algorithm_t ptls_mbedtls_aes128ctr = {"AES128-CTR", + PTLS_AES128_KEY_SIZE, + PTLS_AES_BLOCK_SIZE, + 16 /* iv size */, + sizeof(struct st_ptls_mbedtls_cipher_context_t), + ptls_mbedtls_cipher_setup_aes128_ctr}; /* -* Implementation of AES128_CTR using the PSA API: -*/ + * Implementation of AES128_CTR using the PSA API: + */ static int ptls_mbedtls_cipher_setup_aes256_ctr(ptls_cipher_context_t *_ctx, int is_enc, const void *key_bytes) { - return ptls_mbedtls_cipher_setup_crypto(_ctx, is_enc, key_bytes, - PSA_ALG_CTR, 16, PSA_KEY_TYPE_AES, 256); + return ptls_mbedtls_cipher_setup_crypto(_ctx, is_enc, key_bytes, PSA_ALG_CTR, 16, PSA_KEY_TYPE_AES, 256); } -ptls_cipher_algorithm_t ptls_mbedtls_aes256ctr = { - "AES128-CTR", - PTLS_AES256_KEY_SIZE, - PTLS_AES_BLOCK_SIZE, - 16 /* iv size */, - sizeof(struct st_ptls_mbedtls_cipher_context_t), - ptls_mbedtls_cipher_setup_aes256_ctr}; - +ptls_cipher_algorithm_t ptls_mbedtls_aes256ctr = {"AES128-CTR", + PTLS_AES256_KEY_SIZE, + PTLS_AES_BLOCK_SIZE, + 16 /* iv size */, + sizeof(struct st_ptls_mbedtls_cipher_context_t), + ptls_mbedtls_cipher_setup_aes256_ctr}; #if 0 /* @@ -383,9 +366,9 @@ ptls_cipher_algorithm_t ptls_mbedtls_chacha20 = { ptls_mbedtls_cipher_setup_crypto_chacha20}; #else /* Implementation of ChaCha20 using the low level ChaCha20 API. -* TODO: remove this and the reference to chacha20.h as soon as -* the IV bug in the generic implementation is fixed. -*/ + * TODO: remove this and the reference to chacha20.h as soon as + * the IV bug in the generic implementation is fixed. + */ struct st_ptls_mbedtls_chacha20_context_t { ptls_cipher_context_t super; mbedtls_chacha20_context mctx; @@ -394,18 +377,17 @@ struct st_ptls_mbedtls_chacha20_context_t { static void ptls_mbedtls_chacha20_init(ptls_cipher_context_t *_ctx, const void *v_iv) { struct st_ptls_mbedtls_chacha20_context_t *ctx = (struct st_ptls_mbedtls_chacha20_context_t *)_ctx; - const uint8_t* iv = (const uint8_t*)v_iv; + const uint8_t *iv = (const uint8_t *)v_iv; uint32_t ctr = iv[0] | ((uint32_t)iv[1] << 8) | ((uint32_t)iv[2] << 16) | ((uint32_t)iv[3] << 24); - (void)mbedtls_chacha20_starts(&ctx->mctx, (const uint8_t*)(iv+4), ctr); + (void)mbedtls_chacha20_starts(&ctx->mctx, (const uint8_t *)(iv + 4), ctr); } static void ptls_mbedtls_chacha20_transform(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t len) { struct st_ptls_mbedtls_chacha20_context_t *ctx = (struct st_ptls_mbedtls_chacha20_context_t *)_ctx; - if (mbedtls_chacha20_update(&ctx->mctx, len, - (const uint8_t*)input, (uint8_t*)output) != 0) { + if (mbedtls_chacha20_update(&ctx->mctx, len, (const uint8_t *)input, (uint8_t *)output) != 0) { memset(output, 0, len); } } @@ -422,7 +404,7 @@ static int ptls_mbedtls_cipher_setup_crypto_chacha20(ptls_cipher_context_t *_ctx int ret = 0; mbedtls_chacha20_init(&ctx->mctx); - ret = mbedtls_chacha20_setkey(&ctx->mctx, (const uint8_t*)key); + ret = mbedtls_chacha20_setkey(&ctx->mctx, (const uint8_t *)key); ctx->super.do_dispose = ptls_mbedtls_chacha20_dispose; ctx->super.do_init = ptls_mbedtls_chacha20_init; @@ -435,44 +417,47 @@ static int ptls_mbedtls_cipher_setup_crypto_chacha20(ptls_cipher_context_t *_ctx return ret; } -ptls_cipher_algorithm_t ptls_mbedtls_chacha20 = { - "CHACHA20", PTLS_CHACHA20_KEY_SIZE, 1 /* block size */, PTLS_CHACHA20_IV_SIZE, sizeof(struct st_ptls_mbedtls_chacha20_context_t), - ptls_mbedtls_cipher_setup_crypto_chacha20}; +ptls_cipher_algorithm_t ptls_mbedtls_chacha20 = {"CHACHA20", + PTLS_CHACHA20_KEY_SIZE, + 1 /* block size */, + PTLS_CHACHA20_IV_SIZE, + sizeof(struct st_ptls_mbedtls_chacha20_context_t), + ptls_mbedtls_cipher_setup_crypto_chacha20}; #endif /* Definitions of AEAD algorithms. -* -* For the picotls API, AEAD algorithms are created by calling: -* -* ptls_aead_context_t *ptls_aead_new(ptls_aead_algorithm_t *aead, -* ptls_hash_algorithm_t *hash, int is_enc, const void *secret, -* const char *label_prefix) -* That procedure will allocate memory and create keys, and then call -* a provider specific function: -* -* if (aead->setup_crypto(ctx, is_enc, key, iv) != 0) { -* free(ctx); -* return NULL; -* } -* -* The function will finish completing the aead structure, perform -* initialization, and then document the function pointers: -* -* ctx->super.dispose_crypto: release all resourc -* ctx->super.do_get_iv: return IV -* ctx->super.do_set_iv: set IV value -* ctx->super.do_decrypt: decrypt function -* ctx->super.do_encrypt_init: start encrypting one message -* ctx->super.do_encrypt_update: feed more ciphertext to descriptor -* ctx->super.do_encrypt_final: finalize encryption, including AEAD checksum -* ctx->super.do_encrypt: single shot variant of init/update/final -* ctx->super.do_encrypt_v: scatter gather version of do encrypt -* -* The aead context also documents the underlying "ECB" and "CTR" modes. -* In QUIC, these are used for PN encryption. -* -* TODO: declare other algorithms besides AES128_GCM -*/ + * + * For the picotls API, AEAD algorithms are created by calling: + * + * ptls_aead_context_t *ptls_aead_new(ptls_aead_algorithm_t *aead, + * ptls_hash_algorithm_t *hash, int is_enc, const void *secret, + * const char *label_prefix) + * That procedure will allocate memory and create keys, and then call + * a provider specific function: + * + * if (aead->setup_crypto(ctx, is_enc, key, iv) != 0) { + * free(ctx); + * return NULL; + * } + * + * The function will finish completing the aead structure, perform + * initialization, and then document the function pointers: + * + * ctx->super.dispose_crypto: release all resourc + * ctx->super.do_get_iv: return IV + * ctx->super.do_set_iv: set IV value + * ctx->super.do_decrypt: decrypt function + * ctx->super.do_encrypt_init: start encrypting one message + * ctx->super.do_encrypt_update: feed more ciphertext to descriptor + * ctx->super.do_encrypt_final: finalize encryption, including AEAD checksum + * ctx->super.do_encrypt: single shot variant of init/update/final + * ctx->super.do_encrypt_v: scatter gather version of do encrypt + * + * The aead context also documents the underlying "ECB" and "CTR" modes. + * In QUIC, these are used for PN encryption. + * + * TODO: declare other algorithms besides AES128_GCM + */ struct ptls_mbedtls_aead_param_t { uint8_t static_iv[PTLS_MAX_IV_SIZE]; @@ -488,10 +473,9 @@ struct ptls_mbedtls_aead_context_t { struct ptls_mbedtls_aead_param_t mctx; }; -void ptls_mbedtls_aead_dispose_crypto(struct st_ptls_aead_context_t* _ctx) +void ptls_mbedtls_aead_dispose_crypto(struct st_ptls_aead_context_t *_ctx) { - struct ptls_mbedtls_aead_context_t* ctx = - (struct ptls_mbedtls_aead_context_t*)_ctx; + struct ptls_mbedtls_aead_context_t *ctx = (struct ptls_mbedtls_aead_context_t *)_ctx; if (ctx->mctx.is_op_in_progress) { psa_aead_abort(&ctx->mctx.op); ctx->mctx.is_op_in_progress = 0; @@ -499,31 +483,27 @@ void ptls_mbedtls_aead_dispose_crypto(struct st_ptls_aead_context_t* _ctx) psa_destroy_key(ctx->mctx.key); } - static void ptls_mbedtls_aead_get_iv(ptls_aead_context_t *_ctx, void *iv) { - struct ptls_mbedtls_aead_context_t* ctx = - (struct ptls_mbedtls_aead_context_t*)_ctx; + struct ptls_mbedtls_aead_context_t *ctx = (struct ptls_mbedtls_aead_context_t *)_ctx; memcpy(iv, ctx->mctx.static_iv, ctx->super.algo->iv_size); } static void ptls_mbedtls_aead_set_iv(ptls_aead_context_t *_ctx, const void *iv) { - struct ptls_mbedtls_aead_context_t* ctx = - (struct ptls_mbedtls_aead_context_t*)_ctx; + struct ptls_mbedtls_aead_context_t *ctx = (struct ptls_mbedtls_aead_context_t *)_ctx; memcpy(ctx->mctx.static_iv, iv, ctx->super.algo->iv_size); } -void ptls_mbedtls_aead_do_encrypt_init(struct st_ptls_aead_context_t* _ctx, uint64_t seq, const void* aad, size_t aadlen) +void ptls_mbedtls_aead_do_encrypt_init(struct st_ptls_aead_context_t *_ctx, uint64_t seq, const void *aad, size_t aadlen) { - struct ptls_mbedtls_aead_context_t* ctx = - (struct ptls_mbedtls_aead_context_t*)_ctx; + struct ptls_mbedtls_aead_context_t *ctx = (struct ptls_mbedtls_aead_context_t *)_ctx; psa_status_t status; if (ctx->mctx.is_op_in_progress) { - psa_aead_abort(&ctx->mctx.op); /* required on errors, harmless on success */ + psa_aead_abort(&ctx->mctx.op); /* required on errors, harmless on success */ ctx->mctx.is_op_in_progress = 0; } @@ -544,31 +524,29 @@ void ptls_mbedtls_aead_do_encrypt_init(struct st_ptls_aead_context_t* _ctx, uint } if (status != PSA_SUCCESS) { - psa_aead_abort(&ctx->mctx.op); /* required on errors, harmless on success */ + psa_aead_abort(&ctx->mctx.op); /* required on errors, harmless on success */ ctx->mctx.is_op_in_progress = 0; } } -size_t ptls_mbedtls_aead_do_encrypt_update(struct st_ptls_aead_context_t* _ctx, void* output, const void* input, size_t inlen) +size_t ptls_mbedtls_aead_do_encrypt_update(struct st_ptls_aead_context_t *_ctx, void *output, const void *input, size_t inlen) { size_t olen = 0; - struct ptls_mbedtls_aead_context_t* ctx = - (struct ptls_mbedtls_aead_context_t*)_ctx; + struct ptls_mbedtls_aead_context_t *ctx = (struct ptls_mbedtls_aead_context_t *)_ctx; if (ctx->mctx.is_op_in_progress) { size_t available = inlen + ctx->mctx.extra_bytes; - psa_status_t status = psa_aead_update(&ctx->mctx.op, input, inlen, (uint8_t *)output, available + ctx->super.algo->tag_size, &olen); + psa_status_t status = + psa_aead_update(&ctx->mctx.op, input, inlen, (uint8_t *)output, available + ctx->super.algo->tag_size, &olen); if (status == PSA_SUCCESS) { if (olen < available) { ctx->mctx.extra_bytes = available - olen; - } - else { + } else { ctx->mctx.extra_bytes = 0; } - } - else { - psa_aead_abort(&ctx->mctx.op); /* required on errors */ + } else { + psa_aead_abort(&ctx->mctx.op); /* required on errors */ ctx->mctx.is_op_in_progress = 0; } } @@ -576,38 +554,36 @@ size_t ptls_mbedtls_aead_do_encrypt_update(struct st_ptls_aead_context_t* _ctx, return olen; } -size_t ptls_mbedtls_aead_do_encrypt_final(struct st_ptls_aead_context_t* _ctx, void* output) +size_t ptls_mbedtls_aead_do_encrypt_final(struct st_ptls_aead_context_t *_ctx, void *output) { size_t olen = 0; - struct ptls_mbedtls_aead_context_t* ctx = - (struct ptls_mbedtls_aead_context_t*)_ctx; + struct ptls_mbedtls_aead_context_t *ctx = (struct ptls_mbedtls_aead_context_t *)_ctx; if (ctx->mctx.is_op_in_progress) { unsigned char tag[PSA_AEAD_TAG_MAX_SIZE]; size_t olen_tag = 0; size_t available = ctx->mctx.extra_bytes; - uint8_t* p = (uint8_t*)output; - psa_status_t status = psa_aead_finish(&ctx->mctx.op, p, available + ctx->super.algo->tag_size, &olen, - tag, sizeof(tag), &olen_tag); + uint8_t *p = (uint8_t *)output; + psa_status_t status = + psa_aead_finish(&ctx->mctx.op, p, available + ctx->super.algo->tag_size, &olen, tag, sizeof(tag), &olen_tag); if (status == PSA_SUCCESS) { p += olen; memcpy(p, tag, ctx->super.algo->tag_size); olen += ctx->super.algo->tag_size; - } - else { - psa_aead_abort(&ctx->mctx.op); /* required on errors */ + } else { + psa_aead_abort(&ctx->mctx.op); /* required on errors */ } ctx->mctx.is_op_in_progress = 0; } - return(olen); + return (olen); } -void ptls_mbedtls_aead_do_encrypt_v(struct st_ptls_aead_context_t* _ctx, void* output, ptls_iovec_t* input, size_t incnt, uint64_t seq, - const void* aad, size_t aadlen) +void ptls_mbedtls_aead_do_encrypt_v(struct st_ptls_aead_context_t *_ctx, void *output, ptls_iovec_t *input, size_t incnt, + uint64_t seq, const void *aad, size_t aadlen) { - unsigned char* p = (uint8_t*)output; + unsigned char *p = (uint8_t *)output; ptls_mbedtls_aead_do_encrypt_init(_ctx, seq, aad, aadlen); @@ -618,29 +594,28 @@ void ptls_mbedtls_aead_do_encrypt_v(struct st_ptls_aead_context_t* _ctx, void* o (void)ptls_mbedtls_aead_do_encrypt_final(_ctx, p); } -void ptls_mbedtls_aead_do_encrypt(struct st_ptls_aead_context_t* _ctx, void* output, const void* input, size_t inlen, uint64_t seq, - const void* aad, size_t aadlen, ptls_aead_supplementary_encryption_t* supp) +void ptls_mbedtls_aead_do_encrypt(struct st_ptls_aead_context_t *_ctx, void *output, const void *input, size_t inlen, uint64_t seq, + const void *aad, size_t aadlen, ptls_aead_supplementary_encryption_t *supp) { ptls_iovec_t in_v; - in_v.base = (uint8_t*)input; + in_v.base = (uint8_t *)input; in_v.len = inlen; ptls_mbedtls_aead_do_encrypt_v(_ctx, output, &in_v, 1, seq, aad, aadlen); } -size_t ptls_mbedtls_aead_do_decrypt(struct st_ptls_aead_context_t* _ctx, void* output, const void* input, size_t inlen, uint64_t seq, - const void* aad, size_t aadlen) +size_t ptls_mbedtls_aead_do_decrypt(struct st_ptls_aead_context_t *_ctx, void *output, const void *input, size_t inlen, + uint64_t seq, const void *aad, size_t aadlen) { size_t o_len = 0; uint8_t iv[PTLS_MAX_IV_SIZE]; - struct ptls_mbedtls_aead_context_t* ctx = - (struct ptls_mbedtls_aead_context_t*)_ctx; + struct ptls_mbedtls_aead_context_t *ctx = (struct ptls_mbedtls_aead_context_t *)_ctx; psa_status_t status; /* set the nonce. */ ptls_aead__build_iv(ctx->super.algo, iv, ctx->mctx.static_iv, seq); - status = psa_aead_decrypt(ctx->mctx.key, ctx->mctx.alg, iv, ctx->super.algo->iv_size, (uint8_t*)aad, aadlen, - (uint8_t*)input, inlen, (uint8_t*)output, inlen, &o_len); + status = psa_aead_decrypt(ctx->mctx.key, ctx->mctx.alg, iv, ctx->super.algo->iv_size, (uint8_t *)aad, aadlen, (uint8_t *)input, + inlen, (uint8_t *)output, inlen, &o_len); if (status != PSA_SUCCESS) { o_len = inlen + 1; } @@ -648,12 +623,10 @@ size_t ptls_mbedtls_aead_do_decrypt(struct st_ptls_aead_context_t* _ctx, void* o } static int ptls_mbedtls_aead_setup_crypto(ptls_aead_context_t *_ctx, int is_enc, const void *key_bytes, const void *iv, - psa_algorithm_t psa_alg, size_t key_bits, psa_key_type_t key_type) + psa_algorithm_t psa_alg, size_t key_bits, psa_key_type_t key_type) { int ret = 0; - struct ptls_mbedtls_aead_context_t* ctx = - (struct ptls_mbedtls_aead_context_t*)_ctx; - + struct ptls_mbedtls_aead_context_t *ctx = (struct ptls_mbedtls_aead_context_t *)_ctx; /* set mbed specific context to NULL, just to be sure */ memset(&ctx->mctx, 0, sizeof(struct ptls_mbedtls_aead_param_t)); @@ -662,14 +635,12 @@ static int ptls_mbedtls_aead_setup_crypto(ptls_aead_context_t *_ctx, int is_enc, /* Initialize the key attributes */ if (ret == 0) { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_set_key_usage_flags(&attributes, - (is_enc)?PSA_KEY_USAGE_ENCRYPT:PSA_KEY_USAGE_DECRYPT); + psa_set_key_usage_flags(&attributes, (is_enc) ? PSA_KEY_USAGE_ENCRYPT : PSA_KEY_USAGE_DECRYPT); psa_set_key_algorithm(&attributes, ctx->mctx.alg); psa_set_key_type(&attributes, key_type); psa_set_key_bits(&attributes, key_bits); /* Import key */ - if (psa_import_key(&attributes, key_bytes, key_bits / 8, - &ctx->mctx.key) != PSA_SUCCESS) { + if (psa_import_key(&attributes, key_bytes, key_bits / 8, &ctx->mctx.key) != PSA_SUCCESS) { ret = PTLS_ERROR_LIBRARY; } } @@ -678,8 +649,7 @@ static int ptls_mbedtls_aead_setup_crypto(ptls_aead_context_t *_ctx, int is_enc, /* Store the static IV */ if (ctx->super.algo->iv_size > PTLS_MAX_IV_SIZE) { ret = PTLS_ERROR_LIBRARY; - } - else { + } else { memcpy(ctx->mctx.static_iv, iv, ctx->super.algo->iv_size); ctx->mctx.is_op_in_progress = 0; } @@ -693,8 +663,7 @@ static int ptls_mbedtls_aead_setup_crypto(ptls_aead_context_t *_ctx, int is_enc, ctx->super.do_encrypt_final = ptls_mbedtls_aead_do_encrypt_final; ctx->super.do_encrypt = ptls_mbedtls_aead_do_encrypt; ctx->super.do_encrypt_v = ptls_mbedtls_aead_do_encrypt_v; - } - else { + } else { ctx->super.do_decrypt = ptls_mbedtls_aead_do_decrypt; } ctx->super.dispose_crypto = ptls_mbedtls_aead_dispose_crypto; @@ -705,112 +674,105 @@ static int ptls_mbedtls_aead_setup_crypto(ptls_aead_context_t *_ctx, int is_enc, return ret; } -static int ptls_mbedtls_aead_setup_aes128gcm(ptls_aead_context_t* _ctx, int is_enc, const void* key_bytes, const void* iv) +static int ptls_mbedtls_aead_setup_aes128gcm(ptls_aead_context_t *_ctx, int is_enc, const void *key_bytes, const void *iv) { return ptls_mbedtls_aead_setup_crypto(_ctx, is_enc, key_bytes, iv, PSA_ALG_GCM, 128, PSA_KEY_TYPE_AES); } -ptls_aead_algorithm_t ptls_mbedtls_aes128gcm = { - "AES128-GCM", - PTLS_AESGCM_CONFIDENTIALITY_LIMIT, - PTLS_AESGCM_INTEGRITY_LIMIT, - &ptls_mbedtls_aes128ctr, - &ptls_mbedtls_aes128ecb, - PTLS_AES128_KEY_SIZE, - PTLS_AESGCM_IV_SIZE, - PTLS_AESGCM_TAG_SIZE, - {PTLS_TLS12_AESGCM_FIXED_IV_SIZE, PTLS_TLS12_AESGCM_RECORD_IV_SIZE}, - 0, - 0, - sizeof(struct ptls_mbedtls_aead_context_t), - ptls_mbedtls_aead_setup_aes128gcm -}; +ptls_aead_algorithm_t ptls_mbedtls_aes128gcm = {"AES128-GCM", + PTLS_AESGCM_CONFIDENTIALITY_LIMIT, + PTLS_AESGCM_INTEGRITY_LIMIT, + &ptls_mbedtls_aes128ctr, + &ptls_mbedtls_aes128ecb, + PTLS_AES128_KEY_SIZE, + PTLS_AESGCM_IV_SIZE, + PTLS_AESGCM_TAG_SIZE, + {PTLS_TLS12_AESGCM_FIXED_IV_SIZE, PTLS_TLS12_AESGCM_RECORD_IV_SIZE}, + 0, + 0, + sizeof(struct ptls_mbedtls_aead_context_t), + ptls_mbedtls_aead_setup_aes128gcm}; ptls_cipher_suite_t ptls_mbedtls_aes128gcmsha256 = {.id = PTLS_CIPHER_SUITE_AES_128_GCM_SHA256, -.name = PTLS_CIPHER_SUITE_NAME_AES_128_GCM_SHA256, -.aead = &ptls_mbedtls_aes128gcm, -.hash = &ptls_mbedtls_sha256}; + .name = PTLS_CIPHER_SUITE_NAME_AES_128_GCM_SHA256, + .aead = &ptls_mbedtls_aes128gcm, + .hash = &ptls_mbedtls_sha256}; -static int ptls_mbedtls_aead_setup_aes256gcm(ptls_aead_context_t* _ctx, int is_enc, const void* key_bytes, const void* iv) +static int ptls_mbedtls_aead_setup_aes256gcm(ptls_aead_context_t *_ctx, int is_enc, const void *key_bytes, const void *iv) { return ptls_mbedtls_aead_setup_crypto(_ctx, is_enc, key_bytes, iv, PSA_ALG_GCM, 256, PSA_KEY_TYPE_AES); } -ptls_aead_algorithm_t ptls_mbedtls_aes256gcm = { - "AES256-GCM", - PTLS_AESGCM_CONFIDENTIALITY_LIMIT, - PTLS_AESGCM_INTEGRITY_LIMIT, - &ptls_mbedtls_aes256ctr, - &ptls_mbedtls_aes256ecb, - PTLS_AES256_KEY_SIZE, - PTLS_AESGCM_IV_SIZE, - PTLS_AESGCM_TAG_SIZE, - {PTLS_TLS12_AESGCM_FIXED_IV_SIZE, PTLS_TLS12_AESGCM_RECORD_IV_SIZE}, - 0, - 0, - sizeof(struct ptls_mbedtls_aead_context_t), - ptls_mbedtls_aead_setup_aes256gcm -}; +ptls_aead_algorithm_t ptls_mbedtls_aes256gcm = {"AES256-GCM", + PTLS_AESGCM_CONFIDENTIALITY_LIMIT, + PTLS_AESGCM_INTEGRITY_LIMIT, + &ptls_mbedtls_aes256ctr, + &ptls_mbedtls_aes256ecb, + PTLS_AES256_KEY_SIZE, + PTLS_AESGCM_IV_SIZE, + PTLS_AESGCM_TAG_SIZE, + {PTLS_TLS12_AESGCM_FIXED_IV_SIZE, PTLS_TLS12_AESGCM_RECORD_IV_SIZE}, + 0, + 0, + sizeof(struct ptls_mbedtls_aead_context_t), + ptls_mbedtls_aead_setup_aes256gcm}; -ptls_cipher_suite_t ptls_mbedtls_aes256gcmsha384 = { - .id = PTLS_CIPHER_SUITE_AES_256_GCM_SHA384, - .name = PTLS_CIPHER_SUITE_NAME_AES_256_GCM_SHA384, - .aead = &ptls_mbedtls_aes256gcm, - .hash = &ptls_mbedtls_sha384}; +ptls_cipher_suite_t ptls_mbedtls_aes256gcmsha384 = {.id = PTLS_CIPHER_SUITE_AES_256_GCM_SHA384, + .name = PTLS_CIPHER_SUITE_NAME_AES_256_GCM_SHA384, + .aead = &ptls_mbedtls_aes256gcm, + .hash = &ptls_mbedtls_sha384}; -static int ptls_mbedtls_aead_setup_chacha20poly1305(ptls_aead_context_t* _ctx, int is_enc, const void* key_bytes, const void* iv) +static int ptls_mbedtls_aead_setup_chacha20poly1305(ptls_aead_context_t *_ctx, int is_enc, const void *key_bytes, const void *iv) { return ptls_mbedtls_aead_setup_crypto(_ctx, is_enc, key_bytes, iv, PSA_ALG_CHACHA20_POLY1305, 256, PSA_KEY_TYPE_CHACHA20); } -ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305 = { - "CHACHA20-POLY1305", - PTLS_CHACHA20POLY1305_CONFIDENTIALITY_LIMIT, - PTLS_CHACHA20POLY1305_INTEGRITY_LIMIT, - &ptls_mbedtls_chacha20, - NULL, - PTLS_CHACHA20_KEY_SIZE, - PTLS_CHACHA20POLY1305_IV_SIZE, - PTLS_CHACHA20POLY1305_TAG_SIZE, - {PTLS_TLS12_CHACHAPOLY_FIXED_IV_SIZE, PTLS_TLS12_CHACHAPOLY_RECORD_IV_SIZE}, - 0, - 0, - sizeof(struct ptls_mbedtls_aead_context_t), - ptls_mbedtls_aead_setup_chacha20poly1305 -}; +ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305 = {"CHACHA20-POLY1305", + PTLS_CHACHA20POLY1305_CONFIDENTIALITY_LIMIT, + PTLS_CHACHA20POLY1305_INTEGRITY_LIMIT, + &ptls_mbedtls_chacha20, + NULL, + PTLS_CHACHA20_KEY_SIZE, + PTLS_CHACHA20POLY1305_IV_SIZE, + PTLS_CHACHA20POLY1305_TAG_SIZE, + {PTLS_TLS12_CHACHAPOLY_FIXED_IV_SIZE, PTLS_TLS12_CHACHAPOLY_RECORD_IV_SIZE}, + 0, + 0, + sizeof(struct ptls_mbedtls_aead_context_t), + ptls_mbedtls_aead_setup_chacha20poly1305}; ptls_cipher_suite_t ptls_mbedtls_chacha20poly1305sha256 = {.id = PTLS_CIPHER_SUITE_CHACHA20_POLY1305_SHA256, -.name = PTLS_CIPHER_SUITE_NAME_CHACHA20_POLY1305_SHA256, -.aead = &ptls_mbedtls_chacha20poly1305, -.hash = &ptls_mbedtls_sha256}; + .name = PTLS_CIPHER_SUITE_NAME_CHACHA20_POLY1305_SHA256, + .aead = &ptls_mbedtls_chacha20poly1305, + .hash = &ptls_mbedtls_sha256}; /* Key exchange algorithms. -* The Picotls framework defines these algorithms as ptls_key_exchange_algorithm_t, -* a structure containing two function pointers: -* -* int (*create)(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **ctx); -* int (*exchange)(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_iovec_t *pubkey, ptls_iovec_t *secret, -* ptls_iovec_t peerkey); -* The "create" call is used on the client. It documents the ptls_key_exchange_context_t, which contains -* the public key prepared by the client, as an iovec, and a function pointer: -* -* int (*on_exchange)(struct st_ptls_key_exchange_context_t **keyex, int release, ptls_iovec_t *secret, ptls_iovec_t peerkey); -* -* The public key of the client is passed to the server an ends up as "peerkey" argument to the (exchange) function. -* That function documents the server's public key, and the secret computed by combining server and client key. -* -* When the client receives the server hello, the stack calls the "on_exchange" callback, passing the context -* previously created by the client and the public key of the peer, so the client can compute its own -* version of the secret. -* -* The following code uses the MbedTLS PSA API to create the "create", "exchange" and "on_exchange" functions. -*/ - -#define PTLS_MBEDTLS_ECDH_PUBKEY_MAX 129 + * The Picotls framework defines these algorithms as ptls_key_exchange_algorithm_t, + * a structure containing two function pointers: + * + * int (*create)(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **ctx); + * int (*exchange)(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_iovec_t *pubkey, ptls_iovec_t *secret, + * ptls_iovec_t peerkey); + * The "create" call is used on the client. It documents the ptls_key_exchange_context_t, which contains + * the public key prepared by the client, as an iovec, and a function pointer: + * + * int (*on_exchange)(struct st_ptls_key_exchange_context_t **keyex, int release, ptls_iovec_t *secret, ptls_iovec_t peerkey); + * + * The public key of the client is passed to the server an ends up as "peerkey" argument to the (exchange) function. + * That function documents the server's public key, and the secret computed by combining server and client key. + * + * When the client receives the server hello, the stack calls the "on_exchange" callback, passing the context + * previously created by the client and the public key of the peer, so the client can compute its own + * version of the secret. + * + * The following code uses the MbedTLS PSA API to create the "create", "exchange" and "on_exchange" functions. + */ + +#define PTLS_MBEDTLS_ECDH_PUBKEY_MAX 129 struct ptls_mbedtls_key_exchange_context_t { ptls_key_exchange_context_t super; - psa_algorithm_t psa_alg; + psa_algorithm_t psa_alg; psa_ecc_family_t curve; size_t curve_bits; size_t secret_size; @@ -819,17 +781,17 @@ struct ptls_mbedtls_key_exchange_context_t { }; /* Set a private key for key exchange. For now, we only support ECC -*/ + */ -static int ptls_mbedtls_key_exchange_set_private_key(psa_key_id_t * private_key, - psa_algorithm_t psa_alg, psa_ecc_family_t curve, size_t curve_bits) +static int ptls_mbedtls_key_exchange_set_private_key(psa_key_id_t *private_key, psa_algorithm_t psa_alg, psa_ecc_family_t curve, + size_t curve_bits) { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; int ret = 0; psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE); psa_set_key_algorithm(&attributes, psa_alg); - psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve) ); + psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve)); psa_set_key_bits(&attributes, curve_bits); if (psa_generate_key(&attributes, private_key) != 0) { ret = -1; @@ -848,24 +810,23 @@ size_t output_size, size_t * output_length); */ -int ptls_mbedtls_key_exchange_on_exchange(struct st_ptls_key_exchange_context_t** _pctx, int release, ptls_iovec_t* secret, ptls_iovec_t peerkey) +int ptls_mbedtls_key_exchange_on_exchange(struct st_ptls_key_exchange_context_t **_pctx, int release, ptls_iovec_t *secret, + ptls_iovec_t peerkey) { int ret = 0; struct ptls_mbedtls_key_exchange_context_t *keyex = (struct ptls_mbedtls_key_exchange_context_t *)*_pctx; if (secret != NULL) { - uint8_t* secbytes = (uint8_t*)malloc(keyex->secret_size); + uint8_t *secbytes = (uint8_t *)malloc(keyex->secret_size); if (secbytes == NULL) { ret = PTLS_ERROR_NO_MEMORY; - } - else { + } else { size_t olen; - if (psa_raw_key_agreement(keyex->psa_alg, keyex->private_key, (const uint8_t*)peerkey.base, peerkey.len, - secbytes, keyex->secret_size, &olen) == 0) { + if (psa_raw_key_agreement(keyex->psa_alg, keyex->private_key, (const uint8_t *)peerkey.base, peerkey.len, secbytes, + keyex->secret_size, &olen) == 0) { *secret = ptls_iovec_init(secbytes, keyex->secret_size); - } - else { + } else { free(secbytes); ret = PTLS_ERROR_LIBRARY; } @@ -882,8 +843,8 @@ int ptls_mbedtls_key_exchange_on_exchange(struct st_ptls_key_exchange_context_t* return ret; } -int ptls_mbedtls_key_exchange_create(const struct st_ptls_key_exchange_algorithm_t* algo, ptls_key_exchange_context_t** ctx, - psa_algorithm_t psa_alg, psa_ecc_family_t curve, size_t curve_bits, size_t secret_size) +int ptls_mbedtls_key_exchange_create(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **ctx, + psa_algorithm_t psa_alg, psa_ecc_family_t curve, size_t curve_bits, size_t secret_size) { struct ptls_mbedtls_key_exchange_context_t *keyex; size_t olen = 0; @@ -896,7 +857,7 @@ int ptls_mbedtls_key_exchange_create(const struct st_ptls_key_exchange_algorithm keyex->curve_bits = curve_bits; keyex->secret_size = secret_size; /* Initialize the private key and format the public key */ - if (ptls_mbedtls_key_exchange_set_private_key(&keyex->private_key, psa_alg, curve, curve_bits) != 0){ + if (ptls_mbedtls_key_exchange_set_private_key(&keyex->private_key, psa_alg, curve, curve_bits) != 0) { free(keyex); *ctx = NULL; return PTLS_ERROR_LIBRARY; @@ -908,30 +869,31 @@ int ptls_mbedtls_key_exchange_create(const struct st_ptls_key_exchange_algorithm *ctx = NULL; return PTLS_ERROR_LIBRARY; } - keyex->super.pubkey= ptls_iovec_init(keyex->pub, olen); + keyex->super.pubkey = ptls_iovec_init(keyex->pub, olen); /* Initialize the ptls exchange context */ keyex->super.algo = algo; keyex->super.on_exchange = ptls_mbedtls_key_exchange_on_exchange; - *ctx = (ptls_key_exchange_context_t*)keyex; + *ctx = (ptls_key_exchange_context_t *)keyex; return 0; } -static int ptls_mbedtls_key_exchange_exchange(const struct st_ptls_key_exchange_algorithm_t* algo, ptls_iovec_t* pubkey, ptls_iovec_t* secret, - ptls_iovec_t peerkey, psa_algorithm_t psa_alg, psa_ecc_family_t curve, size_t curve_bits, size_t secret_size) +static int ptls_mbedtls_key_exchange_exchange(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_iovec_t *pubkey, + ptls_iovec_t *secret, ptls_iovec_t peerkey, psa_algorithm_t psa_alg, + psa_ecc_family_t curve, size_t curve_bits, size_t secret_size) { /* generate a local private key for the selected algorithm */ psa_key_id_t private_key; size_t pubkey_len; - uint8_t* pubkey_bytes = NULL; + uint8_t *pubkey_bytes = NULL; size_t secret_len; - uint8_t* secret_bytes = (uint8_t*)malloc(secret_size); + uint8_t *secret_bytes = (uint8_t *)malloc(secret_size); int ret = 0; if (secret_bytes == NULL) { return PTLS_ERROR_NO_MEMORY; } - pubkey_bytes = (uint8_t*)malloc(PTLS_MBEDTLS_ECDH_PUBKEY_MAX); - if (pubkey_bytes == NULL){ + pubkey_bytes = (uint8_t *)malloc(PTLS_MBEDTLS_ECDH_PUBKEY_MAX); + if (pubkey_bytes == NULL) { free(secret_bytes); return PTLS_ERROR_NO_MEMORY; } @@ -944,12 +906,11 @@ static int ptls_mbedtls_key_exchange_exchange(const struct st_ptls_key_exchange_ /* Export public key and call key agrement function */ if (psa_export_public_key(private_key, pubkey_bytes, PTLS_MBEDTLS_ECDH_PUBKEY_MAX, &pubkey_len) == 0 && - psa_raw_key_agreement(psa_alg, private_key, (const uint8_t*)peerkey.base, peerkey.len, - secret_bytes, secret_size, &secret_len) == 0) { + psa_raw_key_agreement(psa_alg, private_key, (const uint8_t *)peerkey.base, peerkey.len, secret_bytes, secret_size, + &secret_len) == 0) { *secret = ptls_iovec_init(secret_bytes, secret_len); *pubkey = ptls_iovec_init(pubkey_bytes, pubkey_len); - } - else { + } else { free(secret_bytes); free(pubkey_bytes); return PTLS_ERROR_LIBRARY; @@ -961,41 +922,37 @@ static int ptls_mbedtls_key_exchange_exchange(const struct st_ptls_key_exchange_ } /* Instantiation of the generic key exchange API with secp256r1 -*/ -static int ptls_mbedtls_secp256r1_create(const struct st_ptls_key_exchange_algorithm_t* algo, ptls_key_exchange_context_t** ctx) + */ +static int ptls_mbedtls_secp256r1_create(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **ctx) { - return ptls_mbedtls_key_exchange_create(algo, ctx, - PSA_ALG_ECDH, PSA_ECC_FAMILY_SECP_R1, 256, 32); + return ptls_mbedtls_key_exchange_create(algo, ctx, PSA_ALG_ECDH, PSA_ECC_FAMILY_SECP_R1, 256, 32); } -static int ptls_mbedtls_secp256r1_exchange(const struct st_ptls_key_exchange_algorithm_t* algo, ptls_iovec_t* pubkey, ptls_iovec_t* secret, - ptls_iovec_t peerkey) +static int ptls_mbedtls_secp256r1_exchange(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_iovec_t *pubkey, + ptls_iovec_t *secret, ptls_iovec_t peerkey) { - return ptls_mbedtls_key_exchange_exchange(algo, pubkey, secret, peerkey, - PSA_ALG_ECDH, PSA_ECC_FAMILY_SECP_R1, 256, 32); + return ptls_mbedtls_key_exchange_exchange(algo, pubkey, secret, peerkey, PSA_ALG_ECDH, PSA_ECC_FAMILY_SECP_R1, 256, 32); } ptls_key_exchange_algorithm_t ptls_mbedtls_secp256r1 = {.id = PTLS_GROUP_SECP256R1, -.name = PTLS_GROUP_NAME_SECP256R1, -.create = ptls_mbedtls_secp256r1_create, -.exchange = ptls_mbedtls_secp256r1_exchange}; + .name = PTLS_GROUP_NAME_SECP256R1, + .create = ptls_mbedtls_secp256r1_create, + .exchange = ptls_mbedtls_secp256r1_exchange}; /* Instantiation of the generic key exchange API with x25519 -*/ -static int ptls_mbedtls_x25519_create(const struct st_ptls_key_exchange_algorithm_t* algo, ptls_key_exchange_context_t** ctx) + */ +static int ptls_mbedtls_x25519_create(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **ctx) { - return ptls_mbedtls_key_exchange_create(algo, ctx, - PSA_ALG_ECDH, PSA_ECC_FAMILY_MONTGOMERY, 255, 32); + return ptls_mbedtls_key_exchange_create(algo, ctx, PSA_ALG_ECDH, PSA_ECC_FAMILY_MONTGOMERY, 255, 32); } -static int ptls_mbedtls_x25519_exchange(const struct st_ptls_key_exchange_algorithm_t* algo, ptls_iovec_t* pubkey, ptls_iovec_t* secret, - ptls_iovec_t peerkey) +static int ptls_mbedtls_x25519_exchange(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_iovec_t *pubkey, + ptls_iovec_t *secret, ptls_iovec_t peerkey) { - return ptls_mbedtls_key_exchange_exchange(algo, pubkey, secret, peerkey, - PSA_ALG_ECDH, PSA_ECC_FAMILY_MONTGOMERY, 255, 32); + return ptls_mbedtls_key_exchange_exchange(algo, pubkey, secret, peerkey, PSA_ALG_ECDH, PSA_ECC_FAMILY_MONTGOMERY, 255, 32); } ptls_key_exchange_algorithm_t ptls_mbedtls_x25519 = {.id = PTLS_GROUP_X25519, -.name = PTLS_GROUP_NAME_X25519, -.create = ptls_mbedtls_x25519_create, -.exchange = ptls_mbedtls_x25519_exchange}; + .name = PTLS_GROUP_NAME_X25519, + .create = ptls_mbedtls_x25519_create, + .exchange = ptls_mbedtls_x25519_exchange}; diff --git a/t/ptls_mbedtls.c b/t/ptls_mbedtls.c index 61815b016..7bd44a23b 100644 --- a/t/ptls_mbedtls.c +++ b/t/ptls_mbedtls.c @@ -1,24 +1,24 @@ /* -* Copyright (c) 2023, Christian Huitema -* -* 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. -*/ + * Copyright (c) 2023, Christian Huitema + * + * 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 _WINDOWS #include "wincompat.h" @@ -39,14 +39,14 @@ static int random_trial() { - /* The random test is just trying to check that we call the API properly. - * This is done by getting a vector of 1021 bytes, computing the sum of - * all values, and comparing to theoretical min and max, - * computed as average +- 8*standard deviation for sum of 1021 terms. - * 8 random deviations results in an extremely low probability of random - * failure. - * Note that this does not actually test the random generator. - */ + /* The random test is just trying to check that we call the API properly. + * This is done by getting a vector of 1021 bytes, computing the sum of + * all values, and comparing to theoretical min and max, + * computed as average +- 8*standard deviation for sum of 1021 terms. + * 8 random deviations results in an extremely low probability of random + * failure. + * Note that this does not actually test the random generator. + */ uint8_t buf[1021]; uint64_t sum = 0; @@ -74,10 +74,10 @@ static void test_random(void) ok(!!"success"); } -static int hash_trial(ptls_hash_algorithm_t* algo, const uint8_t* input, size_t len1, size_t len2, uint8_t* final_hash) +static int hash_trial(ptls_hash_algorithm_t *algo, const uint8_t *input, size_t len1, size_t len2, uint8_t *final_hash) { int ret = 0; - ptls_hash_context_t* hash_ctx = algo->create(); + ptls_hash_context_t *hash_ctx = algo->create(); hash_ctx->update(hash_ctx, input, len1); if (len2 > 0) { @@ -88,11 +88,11 @@ static int hash_trial(ptls_hash_algorithm_t* algo, const uint8_t* input, size_t return ret; } -static int hash_reset_trial(ptls_hash_algorithm_t* algo, const uint8_t* input, size_t len1, size_t len2, - uint8_t* hash1, uint8_t* hash2) +static int hash_reset_trial(ptls_hash_algorithm_t *algo, const uint8_t *input, size_t len1, size_t len2, uint8_t *hash1, + uint8_t *hash2) { int ret = 0; - ptls_hash_context_t* hash_ctx = algo->create(); + ptls_hash_context_t *hash_ctx = algo->create(); hash_ctx->update(hash_ctx, input, len1); hash_ctx->final(hash_ctx, hash1, PTLS_HASH_FINAL_MODE_RESET); @@ -102,7 +102,7 @@ static int hash_reset_trial(ptls_hash_algorithm_t* algo, const uint8_t* input, s return ret; } -static int test_hash(ptls_hash_algorithm_t* algo, ptls_hash_algorithm_t* ref) +static int test_hash(ptls_hash_algorithm_t *algo, ptls_hash_algorithm_t *ref) { int ret = 0; uint8_t input[1234]; @@ -139,8 +139,7 @@ static int test_hash(ptls_hash_algorithm_t* algo, ptls_hash_algorithm_t* ref) if (ret == 0) { if (memcmp(hash1, href1, ref->digest_size) != 0) { ret = -1; - } - else if (memcmp(hash2, href2, ref->digest_size) != 0) { + } else if (memcmp(hash2, href2, ref->digest_size) != 0) { ret = -1; } } @@ -148,10 +147,11 @@ static int test_hash(ptls_hash_algorithm_t* algo, ptls_hash_algorithm_t* ref) return ret; } -static int cipher_trial(ptls_cipher_algorithm_t * cipher, const uint8_t * key, const uint8_t * iv, int is_enc, const uint8_t * v_in, uint8_t * v_out1, uint8_t * v_out2, size_t len) +static int cipher_trial(ptls_cipher_algorithm_t *cipher, const uint8_t *key, const uint8_t *iv, int is_enc, const uint8_t *v_in, + uint8_t *v_out1, uint8_t *v_out2, size_t len) { int ret = 0; - ptls_cipher_context_t* test_cipher = ptls_cipher_new(cipher, is_enc, key); + ptls_cipher_context_t *test_cipher = ptls_cipher_new(cipher, is_enc, key); if (test_cipher == NULL) { ret = -1; } else { @@ -169,7 +169,7 @@ static int cipher_trial(ptls_cipher_algorithm_t * cipher, const uint8_t * key, c return ret; } -static int test_cipher(ptls_cipher_algorithm_t * cipher, ptls_cipher_algorithm_t * cipher_ref) +static int test_cipher(ptls_cipher_algorithm_t *cipher, ptls_cipher_algorithm_t *cipher_ref) { uint8_t key[32]; uint8_t iv[16]; @@ -190,8 +190,7 @@ static int test_cipher(ptls_cipher_algorithm_t * cipher, ptls_cipher_algorithm_t if (ret == 0) { if (memcmp(v_out_1a, v_out_1b, 16) != 0) { ret = -1; - } - else if (memcmp(v_out_2a, v_out_2b, 16) != 0) { + } else if (memcmp(v_out_2a, v_out_2b, 16) != 0) { ret = -1; } } @@ -202,8 +201,7 @@ static int test_cipher(ptls_cipher_algorithm_t * cipher, ptls_cipher_algorithm_t if (ret == 0) { if (memcmp(v_out_1a, v_out_1d, 16) != 0) { ret = -1; - } - else if (memcmp(v_out_2d, v_in, 16) != 0) { + } else if (memcmp(v_out_2d, v_in, 16) != 0) { ret = -1; } } @@ -211,12 +209,12 @@ static int test_cipher(ptls_cipher_algorithm_t * cipher, ptls_cipher_algorithm_t return ret; } -static int label_test(ptls_hash_algorithm_t * hash, uint8_t * v_out, size_t o_len, const uint8_t * secret, - char const * label, char const * label_prefix) +static int label_test(ptls_hash_algorithm_t *hash, uint8_t *v_out, size_t o_len, const uint8_t *secret, char const *label, + char const *label_prefix) { uint8_t h_val_v[32]; - ptls_iovec_t h_val = { 0 }; - ptls_iovec_t s_vec = { 0 }; + ptls_iovec_t h_val = {0}; + ptls_iovec_t s_vec = {0}; s_vec.base = (uint8_t *)secret; s_vec.len = 32; h_val.base = h_val_v; @@ -227,13 +225,13 @@ static int label_test(ptls_hash_algorithm_t * hash, uint8_t * v_out, size_t o_le return 0; } -static int test_label(ptls_hash_algorithm_t* hash, ptls_hash_algorithm_t* ref) +static int test_label(ptls_hash_algorithm_t *hash, ptls_hash_algorithm_t *ref) { int ret = 0; uint8_t v_out[16], v_ref[16]; uint8_t secret[32]; - char const* label = "label"; - char const* label_prefix = "label_prefix"; + char const *label = "label"; + char const *label_prefix = "label_prefix"; memset(secret, 0x5e, sizeof(secret)); ret = label_test(hash, v_out, 16, secret, label, label_prefix); @@ -249,23 +247,21 @@ static int test_label(ptls_hash_algorithm_t* hash, ptls_hash_algorithm_t* ref) return ret; } -static int aead_trial(ptls_aead_algorithm_t * algo, ptls_hash_algorithm_t * hash, const uint8_t * secret, int is_enc, - const uint8_t * v_in, size_t len, uint8_t * aad, size_t aad_len, uint64_t seq, uint8_t * v_out, size_t * o_len) +static int aead_trial(ptls_aead_algorithm_t *algo, ptls_hash_algorithm_t *hash, const uint8_t *secret, int is_enc, + const uint8_t *v_in, size_t len, uint8_t *aad, size_t aad_len, uint64_t seq, uint8_t *v_out, size_t *o_len) { int ret = 0; - ptls_aead_context_t* aead = ptls_aead_new(algo, hash, is_enc, secret, "test_aead"); + ptls_aead_context_t *aead = ptls_aead_new(algo, hash, is_enc, secret, "test_aead"); if (aead == NULL) { ret = -1; - } - else{ + } else { if (is_enc) { *o_len = ptls_aead_encrypt(aead, v_out, v_in, len, seq, aad, aad_len); if (*o_len != len + algo->tag_size) { ret = -1; } - } - else { + } else { *o_len = ptls_aead_decrypt(aead, v_out, v_in, len, seq, aad, aad_len); if (*o_len != len - algo->tag_size) { ret = -1; @@ -276,7 +272,8 @@ static int aead_trial(ptls_aead_algorithm_t * algo, ptls_hash_algorithm_t * hash return ret; } -static int test_aead(ptls_aead_algorithm_t* algo, ptls_hash_algorithm_t* hash, ptls_aead_algorithm_t* ref, ptls_hash_algorithm_t* hash_ref) +static int test_aead(ptls_aead_algorithm_t *algo, ptls_hash_algorithm_t *hash, ptls_aead_algorithm_t *ref, + ptls_hash_algorithm_t *hash_ref) { uint8_t secret[64]; uint8_t v_in[1234]; @@ -395,7 +392,8 @@ static void test_aes256gcm_sha384(void) static void test_chacha20poly1305_sha256(void) { - if (test_aead(&ptls_mbedtls_chacha20poly1305, &ptls_mbedtls_sha256, &ptls_minicrypto_chacha20poly1305, &ptls_minicrypto_sha256) != 0) { + if (test_aead(&ptls_mbedtls_chacha20poly1305, &ptls_mbedtls_sha256, &ptls_minicrypto_chacha20poly1305, + &ptls_minicrypto_sha256) != 0) { ok(!"fail"); } ok(!!"success"); diff --git a/t/ptlsbench.c b/t/ptlsbench.c index 8fdb6fdb7..9e4bc1efd 100644 --- a/t/ptlsbench.c +++ b/t/ptlsbench.c @@ -281,11 +281,11 @@ static ptls_bench_entry_t aead_list[] = { {"openssl", "aes128gcm", &ptls_openssl_aes128gcm, &ptls_minicrypto_sha256, 1}, {"openssl", "aes256gcm", &ptls_openssl_aes256gcm, &ptls_minicrypto_sha384, 1}, #ifdef PTLS_HAVE_MBEDTLS - {"mbedtls", "aes128gcm",& ptls_mbedtls_aes128gcm,& ptls_mbedtls_sha256, 1}, + {"mbedtls", "aes128gcm", &ptls_mbedtls_aes128gcm, &ptls_mbedtls_sha256, 1}, #if defined(MBEDTLS_SHA384_C) - { "mbedtls", "aes256gcm", &ptls_mbedtls_aes256gcm, &ptls_mbedtls_sha384, 1 }, + {"mbedtls", "aes256gcm", &ptls_mbedtls_aes256gcm, &ptls_mbedtls_sha384, 1}, #endif - { "mbedtls", "chacha20poly1305", &ptls_mbedtls_chacha20poly1305, &ptls_mbedtls_sha256, 1 }, + {"mbedtls", "chacha20poly1305", &ptls_mbedtls_chacha20poly1305, &ptls_mbedtls_sha256, 1}, #endif }; From 08e53195053edaad679cffbf31fd87d60b2c095b Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Fri, 3 Nov 2023 18:33:35 +0900 Subject: [PATCH 44/84] rename files following the convention that backends use just the backend name --- include/picotls/{ptls_mbedtls.h => mbedtls.h} | 0 lib/{ptls_mbedtls.c => mbedtls.c} | 0 t/{ptls_mbedtls.c => mbedtls.c} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename include/picotls/{ptls_mbedtls.h => mbedtls.h} (100%) rename lib/{ptls_mbedtls.c => mbedtls.c} (100%) rename t/{ptls_mbedtls.c => mbedtls.c} (100%) diff --git a/include/picotls/ptls_mbedtls.h b/include/picotls/mbedtls.h similarity index 100% rename from include/picotls/ptls_mbedtls.h rename to include/picotls/mbedtls.h diff --git a/lib/ptls_mbedtls.c b/lib/mbedtls.c similarity index 100% rename from lib/ptls_mbedtls.c rename to lib/mbedtls.c diff --git a/t/ptls_mbedtls.c b/t/mbedtls.c similarity index 100% rename from t/ptls_mbedtls.c rename to t/mbedtls.c From 939eb5d7c72695285845e39481c7f50c277a060e Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Fri, 3 Nov 2023 18:34:46 +0900 Subject: [PATCH 45/84] `()` in a prototype means any number of args, no zero --- include/picotls/mbedtls.h | 4 ++-- lib/mbedtls.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/picotls/mbedtls.h b/include/picotls/mbedtls.h index ac16ab221..dcc71faef 100644 --- a/include/picotls/mbedtls.h +++ b/include/picotls/mbedtls.h @@ -50,8 +50,8 @@ extern ptls_cipher_suite_t ptls_mbedtls_chacha20poly1305sha256; extern ptls_key_exchange_algorithm_t ptls_mbedtls_secp256r1; extern ptls_key_exchange_algorithm_t ptls_mbedtls_x25519; -int ptls_mbedtls_init(); -void ptls_mbedtls_free(); +int ptls_mbedtls_init(void); +void ptls_mbedtls_free(void); void ptls_mbedtls_random_bytes(void *buf, size_t len); #ifdef __cplusplus diff --git a/lib/mbedtls.c b/lib/mbedtls.c index ea9ca1b0e..feca0a552 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -42,12 +42,12 @@ * library functions. Free should be used before leaving the program. */ -void ptls_mbedtls_free() +void ptls_mbedtls_free(void) { mbedtls_psa_crypto_free(); } -int ptls_mbedtls_init() +int ptls_mbedtls_init(void) { int ret = 0; psa_status_t status; From c9dcc3e59e28029020d6097434c4aa32b61cd03f Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Fri, 3 Nov 2023 18:39:27 +0900 Subject: [PATCH 46/84] ensure that MBEDTLS_SHA384_C is detected regardless of include order --- include/picotls/mbedtls.h | 3 +++ lib/mbedtls.c | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/picotls/mbedtls.h b/include/picotls/mbedtls.h index dcc71faef..5dc8a52d5 100644 --- a/include/picotls/mbedtls.h +++ b/include/picotls/mbedtls.h @@ -25,6 +25,9 @@ #ifdef __cplusplus extern "C" { #endif + +#include "mbedtls/mbedtls_config.h" +#include "mbedtls/build_info.h" #include "picotls.h" extern ptls_hash_algorithm_t ptls_mbedtls_sha256; diff --git a/lib/mbedtls.c b/lib/mbedtls.c index feca0a552..11720fd85 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -28,8 +28,6 @@ #include #include #include -#include "mbedtls/mbedtls_config.h" -#include "mbedtls/build_info.h" #include "psa/crypto.h" #include "psa/crypto_struct.h" #include "psa/crypto_values.h" From bcf9f71f2345378c4cd719240cc5d596be4b2dd2 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Fri, 3 Nov 2023 18:42:04 +0900 Subject: [PATCH 47/84] API doc goes into .h --- include/picotls/mbedtls.h | 7 +++++++ lib/mbedtls.c | 8 -------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/include/picotls/mbedtls.h b/include/picotls/mbedtls.h index 5dc8a52d5..b4435943c 100644 --- a/include/picotls/mbedtls.h +++ b/include/picotls/mbedtls.h @@ -28,6 +28,7 @@ extern "C" { #include "mbedtls/mbedtls_config.h" #include "mbedtls/build_info.h" + #include "picotls.h" extern ptls_hash_algorithm_t ptls_mbedtls_sha256; @@ -53,7 +54,13 @@ extern ptls_cipher_suite_t ptls_mbedtls_chacha20poly1305sha256; extern ptls_key_exchange_algorithm_t ptls_mbedtls_secp256r1; extern ptls_key_exchange_algorithm_t ptls_mbedtls_x25519; +/** + * Init should be used before starting using library functions. + */ int ptls_mbedtls_init(void); +/** + * Free should be used before leaving the program. + */ void ptls_mbedtls_free(void); void ptls_mbedtls_random_bytes(void *buf, size_t len); diff --git a/lib/mbedtls.c b/lib/mbedtls.c index 11720fd85..dc24922b2 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -36,10 +36,6 @@ #include "mbedtls/ecdh.h" -/* Init and free functions. Init should be used before starting using - * library functions. Free should be used before leaving the program. - */ - void ptls_mbedtls_free(void) { mbedtls_psa_crypto_free(); @@ -56,10 +52,6 @@ int ptls_mbedtls_init(void) return ret; } -/* Random number generator. - * This is a call to the PSA random number generator, which according - * to the documentation meets cryptographic requirements. - */ void ptls_mbedtls_random_bytes(void *buf, size_t len) { psa_generate_random((uint8_t *)buf, len); From cdd6c954ec82db199e5212bf93a59de532f1861e Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Fri, 3 Nov 2023 19:15:56 +0900 Subject: [PATCH 48/84] add capability to define custom clone functions for hash contexts --- include/picotls.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/include/picotls.h b/include/picotls.h index b701e780b..374543054 100644 --- a/include/picotls.h +++ b/include/picotls.h @@ -1763,6 +1763,10 @@ char *ptls_jsonescape(char *buf, const char *s, size_t len); * the default get_time callback */ extern ptls_get_time_t ptls_get_time; +/** + * default hash clone function that calls memcpy + */ +static void ptls_hash_clone_memcpy(void *dst, const void *src, size_t size); #if defined(PICOTLS_USE_DTRACE) && PICOTLS_USE_DTRACE /** * @@ -1919,7 +1923,14 @@ inline size_t ptls_aead_decrypt(ptls_aead_context_t *ctx, void *output, const vo return ctx->do_decrypt(ctx, output, input, inlen, seq, aad, aadlen); } +inline void ptls_hash_clone_memcpy(void *dst, const void *src, size_t size) +{ + memcpy(dst, src, size); +} + #define ptls_define_hash(name, ctx_type, init_func, update_func, final_func) \ + ptls_define_hash6(name, ctx_type, init_func, update_func, final_func, ptls_hash_clone_memcpy) +#define ptls_define_hash6(name, ctx_type, init_func, update_func, final_func, clone_func) \ \ struct name##_context_t { \ ptls_hash_context_t super; \ @@ -1962,7 +1973,8 @@ inline size_t ptls_aead_decrypt(ptls_aead_context_t *ctx, void *output, const vo struct name##_context_t *dst, *src = (struct name##_context_t *)_src; \ if ((dst = malloc(sizeof(*dst))) == NULL) \ return NULL; \ - *dst = *src; \ + dst->super = src->super; \ + clone_func(&dst->ctx, &src->ctx, sizeof(dst->ctx)); \ return &dst->super; \ } \ \ From 86266adce6a4e49453c1dca0d6b8acafd7c16d3e Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Sat, 4 Nov 2023 05:38:11 +0100 Subject: [PATCH 49/84] [xcode] add files --- picotls.xcodeproj/project.pbxproj | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/picotls.xcodeproj/project.pbxproj b/picotls.xcodeproj/project.pbxproj index 6882e1977..67ddebfdd 100644 --- a/picotls.xcodeproj/project.pbxproj +++ b/picotls.xcodeproj/project.pbxproj @@ -205,6 +205,10 @@ 081F00CC291A358800534A86 /* asn1.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = asn1.h; sourceTree = ""; }; 081F00CD291A358800534A86 /* pembase64.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pembase64.h; sourceTree = ""; }; 081F00CE291A358800534A86 /* ptlsbcrypt.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ptlsbcrypt.h; sourceTree = ""; }; + 0883D32A2AF601A700B711CC /* mbedtls.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mbedtls.c; sourceTree = ""; }; + 0883D32B2AF601B900B711CC /* mbedtls.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mbedtls.c; sourceTree = ""; }; + 0883D32C2AF601CB00B711CC /* mbedtls.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mbedtls.h; sourceTree = ""; }; + 0883D32D2AF6020300B711CC /* ptlsbench.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ptlsbench.c; sourceTree = ""; }; 08A835E12995E04100D872CE /* chacha20poly1305.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = chacha20poly1305.h; sourceTree = ""; }; 08A835EB2996971300D872CE /* boringssl-adjust.cmake */ = {isa = PBXFileReference; lastKnownFileType = text; path = "boringssl-adjust.cmake"; sourceTree = ""; }; 08B3298229419DFC009D6766 /* ech-live.t */ = {isa = PBXFileReference; lastKnownFileType = text; path = "ech-live.t"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.perl; }; @@ -402,7 +406,6 @@ 106530BD1D998624005B2C60 /* lib */, E95EBCC2227E82BA0022C32D /* misc */, E95EBCC0227B71170022C32D /* picotls-probes.d */, - E992F79920E99A080008154D /* src */, 106530C41D9B1A0E005B2C60 /* t */, 106530B31D9985E0005B2C60 /* Products */, E973651D246E37300039AA49 /* Frameworks */, @@ -443,6 +446,7 @@ E97577022212405D00D1EF74 /* ffx.c */, E9B43DBF24619D1700824E51 /* fusion.c */, 08F0FDF52910F67A00EE657D /* hpke.c */, + 0883D32B2AF601B900B711CC /* mbedtls.c */, E949EF272073629300511ECA /* minicrypto-pem.c */, 106530C21D9B004B005B2C60 /* openssl.c */, E99B75DF1F5CDDB500CF503E /* pembase64.c */, @@ -461,9 +465,11 @@ 08B3298229419DFC009D6766 /* ech-live.t */, E9B43DE224619D7E00824E51 /* fusion.c */, 081F00C92918823200534A86 /* hpke.c */, + 0883D32A2AF601A700B711CC /* mbedtls.c */, 1059003D1DC8D4E300FB4085 /* minicrypto.c */, 106530C51D9B1A98005B2C60 /* openssl.c */, 106530E91D9B7C13005B2C60 /* picotls.c */, + 0883D32D2AF6020300B711CC /* ptlsbench.c */, 106530E61D9B7AF6005B2C60 /* test.h */, E9E3849C1F0748DD00D50990 /* util.h */, ); @@ -496,6 +502,7 @@ E9E4B1292180514000514B47 /* certificate_compression.h */, E97577002212405300D1EF74 /* ffx.h */, E9B43DE62461A06800824E51 /* fusion.h */, + 0883D32C2AF601CB00B711CC /* mbedtls.h */, 1059004F1DC8D64E00FB4085 /* minicrypto.h */, 106530ED1D9CEFF7005B2C60 /* openssl.h */, 081F00CD291A358800534A86 /* pembase64.h */, @@ -538,13 +545,6 @@ name = Frameworks; sourceTree = ""; }; - E992F79920E99A080008154D /* src */ = { - isa = PBXGroup; - children = ( - ); - path = src; - sourceTree = ""; - }; E9F20BDF22E34B210018D260 /* cifra */ = { isa = PBXGroup; children = ( From cb3e51c5e88748a44eb094c035530d246f19f3bb Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Sat, 4 Nov 2023 05:38:20 +0100 Subject: [PATCH 50/84] rename (amends 08e5319) --- CMakeLists.txt | 4 ++-- t/mbedtls.c | 2 +- t/ptlsbench.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a40ca4ad6..0e816e57f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -208,11 +208,11 @@ IF (WITH_MBEDTLS) message(STATUS "mbedtls/include: ${MBEDTLS_INCLUDE_DIRS}") message(STATUS "mbedtls libraries: ${MBEDTLS_LIBRARIES}") INCLUDE_DIRECTORIES(${MBEDTLS_INCLUDE_DIRS}) - ADD_LIBRARY(picotls-mbedtls lib/ptls_mbedtls.c) + ADD_LIBRARY(picotls-mbedtls lib/mbedtls.c) ADD_EXECUTABLE(test-mbedtls.t deps/picotest/picotest.c lib/picotls.c - t/ptls_mbedtls.c) + t/mbedtls.c) TARGET_LINK_LIBRARIES(test-mbedtls.t picotls-minicrypto picotls-mbedtls ${MBEDTLS_LIBRARIES}) diff --git a/t/mbedtls.c b/t/mbedtls.c index 7bd44a23b..faff669e2 100644 --- a/t/mbedtls.c +++ b/t/mbedtls.c @@ -33,7 +33,7 @@ #include "mbedtls/build_info.h" #include "psa/crypto.h" #include "psa/crypto_struct.h" -#include "picotls/ptls_mbedtls.h" +#include "picotls/mbedtls.h" #include "picotls/minicrypto.h" #include "../deps/picotest/picotest.h" diff --git a/t/ptlsbench.c b/t/ptlsbench.c index 9e4bc1efd..9d9b89d8d 100644 --- a/t/ptlsbench.c +++ b/t/ptlsbench.c @@ -62,7 +62,7 @@ #ifdef PTLS_HAVE_MBEDTLS #include "mbedtls/build_info.h" #include "psa/crypto.h" -#include "picotls/ptls_mbedtls.h" +#include "picotls/mbedtls.h" #endif /* Time in microseconds */ From e2a3a82f66126e27f92a7819c34edc0eda55cb06 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Sat, 4 Nov 2023 05:39:19 +0100 Subject: [PATCH 51/84] these files are included by `crypto.h` --- lib/mbedtls.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/mbedtls.c b/lib/mbedtls.c index dc24922b2..046925967 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -29,11 +29,7 @@ #include #include #include "psa/crypto.h" -#include "psa/crypto_struct.h" -#include "psa/crypto_values.h" - #include "mbedtls/chacha20.h" - #include "mbedtls/ecdh.h" void ptls_mbedtls_free(void) From 24bb55602388896dd6d99819d8a6db6d2d85e3d5 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Sat, 4 Nov 2023 05:39:43 +0100 Subject: [PATCH 52/84] when building picotls, picotls is not part of the system --- lib/mbedtls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mbedtls.c b/lib/mbedtls.c index 046925967..d18c088f8 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -27,10 +27,10 @@ #include #include #include -#include #include "psa/crypto.h" #include "mbedtls/chacha20.h" #include "mbedtls/ecdh.h" +#include "picotls.h" void ptls_mbedtls_free(void) { From 6d6985aa254a5b37a9081c7e6d96c44703a88d5e Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Sat, 4 Nov 2023 05:40:07 +0100 Subject: [PATCH 53/84] when building picotls, picotls is not part of the system, whereas mbedtls is --- lib/mbedtls.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/mbedtls.c b/lib/mbedtls.c index d18c088f8..f7386d397 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -27,9 +27,9 @@ #include #include #include -#include "psa/crypto.h" -#include "mbedtls/chacha20.h" -#include "mbedtls/ecdh.h" +#include +#include +#include #include "picotls.h" void ptls_mbedtls_free(void) From 967e854d32d588d2ab0219aa3900fc15e36b0b44 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Sat, 4 Nov 2023 05:57:56 +0100 Subject: [PATCH 54/84] define hash implementations using `ptls_define_hash` --- lib/mbedtls.c | 158 +++++++++++--------------------------------------- 1 file changed, 34 insertions(+), 124 deletions(-) diff --git a/lib/mbedtls.c b/lib/mbedtls.c index f7386d397..8180a8906 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -53,131 +53,41 @@ void ptls_mbedtls_random_bytes(void *buf, size_t len) psa_generate_random((uint8_t *)buf, len); } -/* Definitions for hash algorithms. - * In Picotls, these are described by the stucture - * ptls_hash_algorithm_t, which include the function - * pointer for creation of the hash context. - * - * The structure contains a function pointer to the - * "create" function that creates a hash operation, - * which itself contains three function pointers: - * - * void (*update)(struct st_ptls_hash_context_t *ctx, const void *src, size_t len); - * void (*final)(struct st_ptls_hash_context_t *ctx, void *md, ptls_hash_final_mode_t mode); - * struct st_ptls_hash_context_t *(*clone_)(struct st_ptls_hash_context_t *src); - * - */ - -typedef struct st_ptls_mbedtls_hash_ctx_t { - ptls_hash_context_t super; - psa_algorithm_t alg; - size_t hash_size; - psa_hash_operation_t operation; -} ptls_mbedtls_hash_ctx_t; - -static void ptls_mbedtls_hash_update(struct st_ptls_hash_context_t *_ctx, const void *src, size_t len) -{ - ptls_mbedtls_hash_ctx_t *ctx = (ptls_mbedtls_hash_ctx_t *)_ctx; - - (void)psa_hash_update(&ctx->operation, (const uint8_t *)src, len); -} - -static void ptls_mbedtls_hash_final(struct st_ptls_hash_context_t *_ctx, void *md, ptls_hash_final_mode_t mode); - -static struct st_ptls_hash_context_t *ptls_mbedtls_hash_clone(struct st_ptls_hash_context_t *_src) -{ - ptls_mbedtls_hash_ctx_t *ctx = (ptls_mbedtls_hash_ctx_t *)malloc(sizeof(ptls_mbedtls_hash_ctx_t)); - const ptls_mbedtls_hash_ctx_t *src = (const ptls_mbedtls_hash_ctx_t *)_src; - - if (ctx != NULL) { - ptls_mbedtls_hash_ctx_t *src = (ptls_mbedtls_hash_ctx_t *)_src; - memset(&ctx->operation, 0, sizeof(mbedtls_sha256_context)); - ctx->super.clone_ = ptls_mbedtls_hash_clone; - ctx->super.update = ptls_mbedtls_hash_update; - ctx->super.final = ptls_mbedtls_hash_final; - ctx->alg = src->alg; - ctx->hash_size = src->hash_size; - if (psa_hash_clone(&src->operation, &ctx->operation) != 0) { - free(ctx); - ctx = NULL; - } - } - return (ptls_hash_context_t *)ctx; -} - -static void ptls_mbedtls_hash_final(struct st_ptls_hash_context_t *_ctx, void *md, ptls_hash_final_mode_t mode) -{ - ptls_mbedtls_hash_ctx_t *ctx = (ptls_mbedtls_hash_ctx_t *)_ctx; - - if (mode == PTLS_HASH_FINAL_MODE_SNAPSHOT) { - struct st_ptls_hash_context_t *cloned = ptls_mbedtls_hash_clone(_ctx); - - if (cloned != NULL) { - ptls_mbedtls_hash_final(cloned, md, PTLS_HASH_FINAL_MODE_FREE); - } - } else { - if (md != NULL) { - size_t hash_length = 0; - if (psa_hash_finish(&ctx->operation, md, ctx->hash_size, &hash_length) != 0) { - memset(md, 0, ctx->hash_size); - } - } - - if (mode == PTLS_HASH_FINAL_MODE_FREE) { - (void)psa_hash_abort(&ctx->operation); - free(ctx); - } else { - /* if mode = reset, reset the context */ - memset(&ctx->operation, 0, sizeof(ctx->operation)); - (void)psa_hash_setup(&ctx->operation, ctx->alg); - } - } -} - -ptls_hash_context_t *ptls_mbedtls_hash_create(psa_algorithm_t alg, size_t hash_size) -{ - ptls_mbedtls_hash_ctx_t *ctx = (ptls_mbedtls_hash_ctx_t *)malloc(sizeof(ptls_mbedtls_hash_ctx_t)); - - if (ctx != NULL) { - memset(&ctx->operation, 0, sizeof(ctx->operation)); - ctx->alg = alg; - ctx->hash_size = hash_size; - ctx->super.clone_ = ptls_mbedtls_hash_clone; - ctx->super.update = ptls_mbedtls_hash_update; - ctx->super.final = ptls_mbedtls_hash_final; - if (psa_hash_setup(&ctx->operation, alg) != 0) { - free(ctx); - ctx = NULL; - } - } - return (ptls_hash_context_t *)ctx; -} - -ptls_hash_context_t *ptls_mbedtls_sha256_create(void) -{ - return ptls_mbedtls_hash_create(PSA_ALG_SHA_256, PTLS_SHA256_DIGEST_SIZE); -} - -ptls_hash_context_t *ptls_mbedtls_sha512_create(void) -{ - return ptls_mbedtls_hash_create(PSA_ALG_SHA_512, PTLS_SHA512_DIGEST_SIZE); -} - -ptls_hash_algorithm_t ptls_mbedtls_sha256 = {"sha256", PTLS_SHA256_BLOCK_SIZE, PTLS_SHA256_DIGEST_SIZE, ptls_mbedtls_sha256_create, - PTLS_ZERO_DIGEST_SHA256}; - -ptls_hash_algorithm_t ptls_mbedtls_sha512 = {"SHA512", PTLS_SHA512_BLOCK_SIZE, PTLS_SHA512_DIGEST_SIZE, ptls_mbedtls_sha512_create, - PTLS_ZERO_DIGEST_SHA512}; - +#define CALL_WITH_CHECK(fn, ...) \ + do { \ + if (fn(__VA_ARGS__) != PSA_SUCCESS) { \ + fprintf(stderr, PTLS_TO_STR(fn) " failed\n"); \ + abort(); \ + } \ + } while (0) + +#define DEFINE_HASH(name, name_upcase, psa_alg) \ + static void name##_do_init(psa_hash_operation_t *op) \ + { \ + *op = psa_hash_operation_init(); \ + CALL_WITH_CHECK(psa_hash_setup, op, psa_alg); \ + } \ + static void name##_do_update(psa_hash_operation_t *op, const void *src, size_t len) \ + { \ + CALL_WITH_CHECK(psa_hash_update, op, src, len); \ + } \ + static void name##_do_final(psa_hash_operation_t *op, void *md) \ + { \ + size_t unused; \ + CALL_WITH_CHECK(psa_hash_finish, op, md, PTLS_##name_upcase##_DIGEST_SIZE, &unused); \ + } \ + static void name##_do_clone(psa_hash_operation_t *dst, psa_hash_operation_t *src, size_t unused) \ + { \ + CALL_WITH_CHECK(psa_hash_clone, src, dst); \ + } \ + ptls_define_hash6(name, psa_hash_operation_t, name##_do_init, name##_do_update, name##_do_final, name##_do_clone); \ + ptls_hash_algorithm_t ptls_mbedtls_##name = {PTLS_TO_STR(name), PTLS_##name_upcase##_BLOCK_SIZE, \ + PTLS_##name_upcase##_DIGEST_SIZE, name##_create, PTLS_ZERO_DIGEST_##name_upcase}; +DEFINE_HASH(sha256, SHA256, PSA_ALG_SHA_256); +DEFINE_HASH(sha512, SHA512, PSA_ALG_SHA_512); #if defined(MBEDTLS_SHA384_C) -ptls_hash_context_t *ptls_mbedtls_sha384_create(void) -{ - return ptls_mbedtls_hash_create(PSA_ALG_SHA_384, PTLS_SHA384_DIGEST_SIZE); -} - -ptls_hash_algorithm_t ptls_mbedtls_sha384 = {"SHA384", PTLS_SHA384_BLOCK_SIZE, PTLS_SHA384_DIGEST_SIZE, ptls_mbedtls_sha384_create, - PTLS_ZERO_DIGEST_SHA384}; -#endif /* MBEDTLS_SHA384_C */ +DEFINE_HASH(sha384, SHA384, PSA_ALG_SHA_384); +#endif /* * Generic implementation of a cipher using the PSA API From 3e99858601fcd7a8bb5027c88dacbf6d788c17bc Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Sat, 4 Nov 2023 05:59:41 +0100 Subject: [PATCH 55/84] mbedtls is dependency --- include/picotls/mbedtls.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/include/picotls/mbedtls.h b/include/picotls/mbedtls.h index b4435943c..e7fc7a398 100644 --- a/include/picotls/mbedtls.h +++ b/include/picotls/mbedtls.h @@ -26,9 +26,8 @@ extern "C" { #endif -#include "mbedtls/mbedtls_config.h" -#include "mbedtls/build_info.h" - +#include +#include #include "picotls.h" extern ptls_hash_algorithm_t ptls_mbedtls_sha256; @@ -67,4 +66,4 @@ void ptls_mbedtls_random_bytes(void *buf, size_t len); #ifdef __cplusplus } #endif -#endif /* picotls_mbedtls_h */ \ No newline at end of file +#endif /* picotls_mbedtls_h */ From 68662dc703b6dd705fa1ad820264e35c41b037ae Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Sat, 4 Nov 2023 06:00:42 +0100 Subject: [PATCH 56/84] it is our convention to let the user initialize the crypto backends (see openssl) --- include/picotls/mbedtls.h | 10 ++-------- lib/mbedtls.c | 16 ---------------- 2 files changed, 2 insertions(+), 24 deletions(-) diff --git a/include/picotls/mbedtls.h b/include/picotls/mbedtls.h index e7fc7a398..3e8904c7d 100644 --- a/include/picotls/mbedtls.h +++ b/include/picotls/mbedtls.h @@ -30,6 +30,8 @@ extern "C" { #include #include "picotls.h" +/* before using any of these objects, psa_crypto_init() must be called */ + extern ptls_hash_algorithm_t ptls_mbedtls_sha256; extern ptls_hash_algorithm_t ptls_mbedtls_sha512; #if defined(MBEDTLS_SHA384_C) @@ -53,14 +55,6 @@ extern ptls_cipher_suite_t ptls_mbedtls_chacha20poly1305sha256; extern ptls_key_exchange_algorithm_t ptls_mbedtls_secp256r1; extern ptls_key_exchange_algorithm_t ptls_mbedtls_x25519; -/** - * Init should be used before starting using library functions. - */ -int ptls_mbedtls_init(void); -/** - * Free should be used before leaving the program. - */ -void ptls_mbedtls_free(void); void ptls_mbedtls_random_bytes(void *buf, size_t len); #ifdef __cplusplus diff --git a/lib/mbedtls.c b/lib/mbedtls.c index 8180a8906..aa5a31db5 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -32,22 +32,6 @@ #include #include "picotls.h" -void ptls_mbedtls_free(void) -{ - mbedtls_psa_crypto_free(); -} - -int ptls_mbedtls_init(void) -{ - int ret = 0; - psa_status_t status; - if ((status = psa_crypto_init()) != PSA_SUCCESS) { - ret = -1; - } - - return ret; -} - void ptls_mbedtls_random_bytes(void *buf, size_t len) { psa_generate_random((uint8_t *)buf, len); From e2f03c95998e7d6c328b5dd5407a6a864153a131 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Sat, 4 Nov 2023 06:01:14 +0100 Subject: [PATCH 57/84] PRNG might fail too --- lib/mbedtls.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/mbedtls.c b/lib/mbedtls.c index aa5a31db5..8dff7012b 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -32,11 +32,6 @@ #include #include "picotls.h" -void ptls_mbedtls_random_bytes(void *buf, size_t len) -{ - psa_generate_random((uint8_t *)buf, len); -} - #define CALL_WITH_CHECK(fn, ...) \ do { \ if (fn(__VA_ARGS__) != PSA_SUCCESS) { \ @@ -45,6 +40,11 @@ void ptls_mbedtls_random_bytes(void *buf, size_t len) } \ } while (0) +void ptls_mbedtls_random_bytes(void *buf, size_t len) +{ + CALL_WITH_CHECK(psa_generate_random, buf, len); +} + #define DEFINE_HASH(name, name_upcase, psa_alg) \ static void name##_do_init(psa_hash_operation_t *op) \ { \ From 21062990588be43d76ca7c5997d8608e9f4dc641 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Sat, 4 Nov 2023 07:53:39 +0100 Subject: [PATCH 58/84] reduce state of symmentric ciphers; no need to set key for every IV --- lib/mbedtls.c | 178 ++++++++++++++++++-------------------------------- 1 file changed, 64 insertions(+), 114 deletions(-) diff --git a/lib/mbedtls.c b/lib/mbedtls.c index 8dff7012b..629b6c013 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -78,156 +78,109 @@ DEFINE_HASH(sha384, SHA384, PSA_ALG_SHA_384); */ struct st_ptls_mbedtls_cipher_context_t { ptls_cipher_context_t super; - psa_algorithm_t alg; size_t iv_length; - int is_enc; - int is_op_in_progress; - mbedtls_svc_key_id_t key; - psa_cipher_operation_t operation; + psa_cipher_operation_t op; }; -static void ptls_mbedtls_cipher_init(ptls_cipher_context_t *_ctx, const void *iv) +static void cipher_init(ptls_cipher_context_t *_ctx, const void *iv) { struct st_ptls_mbedtls_cipher_context_t *ctx = (struct st_ptls_mbedtls_cipher_context_t *)_ctx; - if (ctx->is_op_in_progress) { - psa_cipher_abort(&ctx->operation); - ctx->is_op_in_progress = 0; - } - - memset(&ctx->operation, 0, sizeof(ctx->operation)); - if (ctx->is_enc) { - (void)psa_cipher_encrypt_setup(&ctx->operation, ctx->key, ctx->alg); - } else { - (void)psa_cipher_decrypt_setup(&ctx->operation, ctx->key, ctx->alg); - } - if (ctx->iv_length > 0) { - (void)psa_cipher_set_iv(&ctx->operation, (const uint8_t *)iv, ctx->iv_length); - } - ctx->is_op_in_progress = 1; + if (ctx->iv_length > 0) + CALL_WITH_CHECK(psa_cipher_set_iv, &ctx->op, iv, ctx->iv_length); } -static void ptls_mbedtls_cipher_transform(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t len) +static void cipher_transform(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t len) { struct st_ptls_mbedtls_cipher_context_t *ctx = (struct st_ptls_mbedtls_cipher_context_t *)_ctx; - size_t outlen = 0; + size_t unused = 0; - (void)psa_cipher_update(&ctx->operation, (const uint8_t *)input, len, (uint8_t *)output, len, &outlen); + CALL_WITH_CHECK(psa_cipher_update, &ctx->op, input, len, output, len, &unused); } -static void ptls_mbedtls_cipher_dispose(ptls_cipher_context_t *_ctx) +static void cipher_dispose(ptls_cipher_context_t *_ctx) { struct st_ptls_mbedtls_cipher_context_t *ctx = (struct st_ptls_mbedtls_cipher_context_t *)_ctx; - if (ctx->is_op_in_progress) { - psa_cipher_abort(&ctx->operation); - ctx->is_op_in_progress = 0; - } - psa_destroy_key(ctx->key); + + psa_cipher_abort(&ctx->op); } -static int ptls_mbedtls_cipher_setup_key(mbedtls_svc_key_id_t *key_id, int is_enc, psa_algorithm_t alg, psa_key_type_t key_type, - size_t key_bits, const uint8_t *key_bytes) +static int setup_crypto(ptls_cipher_context_t *_ctx, int is_enc, const void *key_bytes, psa_algorithm_t alg, size_t iv_length, + psa_key_type_t key_type, size_t key_bits) { + struct st_ptls_mbedtls_cipher_context_t *ctx = (struct st_ptls_mbedtls_cipher_context_t *)_ctx; + mbedtls_svc_key_id_t key; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - int ret = 0; + /* import key or fail immediately */ psa_set_key_usage_flags(&attributes, (is_enc) ? PSA_KEY_USAGE_ENCRYPT : PSA_KEY_USAGE_DECRYPT); psa_set_key_algorithm(&attributes, alg); psa_set_key_type(&attributes, key_type); psa_set_key_bits(&attributes, key_bits); - /* Import key */ - if (psa_import_key(&attributes, key_bytes, key_bits / 8, key_id) != PSA_SUCCESS) { - ret = PTLS_ERROR_LIBRARY; - } - - return ret; -} - -static int ptls_mbedtls_cipher_setup_crypto(ptls_cipher_context_t *_ctx, int is_enc, const void *key_bytes, psa_algorithm_t alg, - size_t iv_length, psa_key_type_t key_type, size_t key_bits) -{ - struct st_ptls_mbedtls_cipher_context_t *ctx = (struct st_ptls_mbedtls_cipher_context_t *)_ctx; - int ret = 0; + if (psa_import_key(&attributes, key_bytes, key_bits / 8, &key) != PSA_SUCCESS) + return PTLS_ERROR_LIBRARY; - ctx->alg = alg; - ctx->is_enc = is_enc; + /* init context */ + ctx->super.do_dispose = cipher_dispose; + ctx->super.do_init = cipher_init; + ctx->super.do_transform = cipher_transform; ctx->iv_length = iv_length; - - /* Initialize the key attributes */ - ret = ptls_mbedtls_cipher_setup_key(&ctx->key, is_enc, alg, key_type, key_bits, (const uint8_t *)key_bytes); - /* Finish initializing the context */ - ctx->super.do_dispose = ptls_mbedtls_cipher_dispose; - ctx->super.do_init = ptls_mbedtls_cipher_init; - ctx->super.do_transform = NULL; - - if (ret == 0) { - ctx->super.do_transform = ptls_mbedtls_cipher_transform; + ctx->op = psa_cipher_operation_init(); + if (is_enc) { + CALL_WITH_CHECK(psa_cipher_encrypt_setup, &ctx->op, key, alg); + } else { + CALL_WITH_CHECK(psa_cipher_decrypt_setup, &ctx->op, key, alg); } - return ret; + return 0; } -/* - * Implementation of AES128_ECB using the PSA API: - */ -static int ptls_mbedtls_cipher_setup_aes128_ecb(ptls_cipher_context_t *_ctx, int is_enc, const void *key_bytes) +static int setup_aes128ecb(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) { - return ptls_mbedtls_cipher_setup_crypto(_ctx, is_enc, key_bytes, PSA_ALG_ECB_NO_PADDING, 0, PSA_KEY_TYPE_AES, 128); + return setup_crypto(ctx, is_enc, key_bytes, PSA_ALG_ECB_NO_PADDING, 0, PSA_KEY_TYPE_AES, 128); } -ptls_cipher_algorithm_t ptls_mbedtls_aes128ecb = {"AES128-ECB", - PTLS_AES128_KEY_SIZE, - PTLS_AES_BLOCK_SIZE, - 0 /* iv size */, - sizeof(struct st_ptls_mbedtls_cipher_context_t), - ptls_mbedtls_cipher_setup_aes128_ecb}; +ptls_cipher_algorithm_t ptls_mbedtls_aes128ecb = { + "AES128-ECB", PTLS_AES128_KEY_SIZE, PTLS_AES_BLOCK_SIZE, 0 /* iv size */, sizeof(struct st_ptls_mbedtls_cipher_context_t), + setup_aes128ecb}; /* * Implementation of AES256_ECB using the PSA API: */ -static int ptls_mbedtls_cipher_setup_aes256_ecb(ptls_cipher_context_t *_ctx, int is_enc, const void *key_bytes) +static int setup_aes256ecb(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) { - return ptls_mbedtls_cipher_setup_crypto(_ctx, is_enc, key_bytes, PSA_ALG_ECB_NO_PADDING, 0, PSA_KEY_TYPE_AES, 256); + return setup_crypto(ctx, is_enc, key_bytes, PSA_ALG_ECB_NO_PADDING, 0, PSA_KEY_TYPE_AES, 256); } -ptls_cipher_algorithm_t ptls_mbedtls_aes256ecb = {"AES256-ECB", - PTLS_AES128_KEY_SIZE, - PTLS_AES_BLOCK_SIZE, - 0 /* iv size */, - sizeof(struct st_ptls_mbedtls_cipher_context_t), - ptls_mbedtls_cipher_setup_aes256_ecb}; +ptls_cipher_algorithm_t ptls_mbedtls_aes256ecb = { + "AES256-ECB", PTLS_AES128_KEY_SIZE, PTLS_AES_BLOCK_SIZE, 0 /* iv size */, sizeof(struct st_ptls_mbedtls_cipher_context_t), + setup_aes256ecb}; /* * Implementation of AES128_CTR using the PSA API: */ -static int ptls_mbedtls_cipher_setup_aes128_ctr(ptls_cipher_context_t *_ctx, int is_enc, const void *key_bytes) +static int setup_aes128ctr(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) { - return ptls_mbedtls_cipher_setup_crypto(_ctx, is_enc, key_bytes, PSA_ALG_CTR, 16, PSA_KEY_TYPE_AES, 128); + return setup_crypto(ctx, is_enc, key_bytes, PSA_ALG_CTR, 16, PSA_KEY_TYPE_AES, 128); } -ptls_cipher_algorithm_t ptls_mbedtls_aes128ctr = {"AES128-CTR", - PTLS_AES128_KEY_SIZE, - PTLS_AES_BLOCK_SIZE, - 16 /* iv size */, - sizeof(struct st_ptls_mbedtls_cipher_context_t), - ptls_mbedtls_cipher_setup_aes128_ctr}; +ptls_cipher_algorithm_t ptls_mbedtls_aes128ctr = { + "AES128-CTR", PTLS_AES128_KEY_SIZE, PTLS_AES_BLOCK_SIZE, 16 /* iv size */, sizeof(struct st_ptls_mbedtls_cipher_context_t), + setup_aes128ctr}; /* * Implementation of AES128_CTR using the PSA API: */ -static int ptls_mbedtls_cipher_setup_aes256_ctr(ptls_cipher_context_t *_ctx, int is_enc, const void *key_bytes) +static int setup_aes256ctr(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) { - return ptls_mbedtls_cipher_setup_crypto(_ctx, is_enc, key_bytes, PSA_ALG_CTR, 16, PSA_KEY_TYPE_AES, 256); + return setup_crypto(ctx, is_enc, key_bytes, PSA_ALG_CTR, 16, PSA_KEY_TYPE_AES, 256); } -ptls_cipher_algorithm_t ptls_mbedtls_aes256ctr = {"AES128-CTR", - PTLS_AES256_KEY_SIZE, - PTLS_AES_BLOCK_SIZE, - 16 /* iv size */, - sizeof(struct st_ptls_mbedtls_cipher_context_t), - ptls_mbedtls_cipher_setup_aes256_ctr}; +ptls_cipher_algorithm_t ptls_mbedtls_aes256ctr = { + "AES128-CTR", PTLS_AES256_KEY_SIZE, PTLS_AES_BLOCK_SIZE, 16 /* iv size */, sizeof(struct st_ptls_mbedtls_cipher_context_t), + setup_aes256ctr}; #if 0 /* @@ -235,15 +188,14 @@ ptls_cipher_algorithm_t ptls_mbedtls_aes256ctr = {"AES128-CTR", * This is disabled for now, as there seems to be an issue when * setting the 16 bytes long IV that we need. */ -static int ptls_mbedtls_cipher_setup_crypto_chacha20(ptls_cipher_context_t *_ctx, int is_enc, const void *key_bytes) +static int setup_crypto_chacha20(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) { - return ptls_mbedtls_cipher_setup_crypto(_ctx, is_enc, key_bytes, - PSA_ALG_STREAM_CIPHER, 16, PSA_KEY_TYPE_CHACHA20, 256); + return setup_crypto(ctx, is_enc, key_bytes, PSA_ALG_STREAM_CIPHER, 16, PSA_KEY_TYPE_CHACHA20, 256); } ptls_cipher_algorithm_t ptls_mbedtls_chacha20 = { "CHACHA20", PTLS_CHACHA20_KEY_SIZE, 1 /* block size */, PTLS_CHACHA20_IV_SIZE, sizeof(struct st_ptls_mbedtls_cipher_context_t), - ptls_mbedtls_cipher_setup_crypto_chacha20}; + setup_chacha20}; #else /* Implementation of ChaCha20 using the low level ChaCha20 API. * TODO: remove this and the reference to chacha20.h as soon as @@ -254,7 +206,7 @@ struct st_ptls_mbedtls_chacha20_context_t { mbedtls_chacha20_context mctx; }; -static void ptls_mbedtls_chacha20_init(ptls_cipher_context_t *_ctx, const void *v_iv) +static void chacha20_init(ptls_cipher_context_t *_ctx, const void *v_iv) { struct st_ptls_mbedtls_chacha20_context_t *ctx = (struct st_ptls_mbedtls_chacha20_context_t *)_ctx; const uint8_t *iv = (const uint8_t *)v_iv; @@ -263,38 +215,36 @@ static void ptls_mbedtls_chacha20_init(ptls_cipher_context_t *_ctx, const void * (void)mbedtls_chacha20_starts(&ctx->mctx, (const uint8_t *)(iv + 4), ctr); } -static void ptls_mbedtls_chacha20_transform(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t len) +static void chacha20_transform(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t len) { struct st_ptls_mbedtls_chacha20_context_t *ctx = (struct st_ptls_mbedtls_chacha20_context_t *)_ctx; if (mbedtls_chacha20_update(&ctx->mctx, len, (const uint8_t *)input, (uint8_t *)output) != 0) { - memset(output, 0, len); + fprintf(stderr, "mbedtls_chacha20_update failed\n"); + abort(); } } -static void ptls_mbedtls_chacha20_dispose(ptls_cipher_context_t *_ctx) +static void chacha20_dispose(ptls_cipher_context_t *_ctx) { struct st_ptls_mbedtls_chacha20_context_t *ctx = (struct st_ptls_mbedtls_chacha20_context_t *)_ctx; + mbedtls_chacha20_free(&ctx->mctx); } -static int ptls_mbedtls_cipher_setup_crypto_chacha20(ptls_cipher_context_t *_ctx, int is_enc, const void *key) +static int setup_chacha20(ptls_cipher_context_t *_ctx, int is_enc, const void *key) { struct st_ptls_mbedtls_chacha20_context_t *ctx = (struct st_ptls_mbedtls_chacha20_context_t *)_ctx; - int ret = 0; mbedtls_chacha20_init(&ctx->mctx); - ret = mbedtls_chacha20_setkey(&ctx->mctx, (const uint8_t *)key); + if (mbedtls_chacha20_setkey(&ctx->mctx, key) != 0) + return PTLS_ERROR_LIBRARY; - ctx->super.do_dispose = ptls_mbedtls_chacha20_dispose; - ctx->super.do_init = ptls_mbedtls_chacha20_init; - ctx->super.do_transform = NULL; + ctx->super.do_dispose = chacha20_dispose; + ctx->super.do_init = chacha20_init; + ctx->super.do_transform = chacha20_transform; - if (ret == 0) { - ctx->super.do_transform = ptls_mbedtls_chacha20_transform; - } - - return ret; + return 0; } ptls_cipher_algorithm_t ptls_mbedtls_chacha20 = {"CHACHA20", @@ -302,7 +252,7 @@ ptls_cipher_algorithm_t ptls_mbedtls_chacha20 = {"CHACHA20", 1 /* block size */, PTLS_CHACHA20_IV_SIZE, sizeof(struct st_ptls_mbedtls_chacha20_context_t), - ptls_mbedtls_cipher_setup_crypto_chacha20}; + setup_chacha20}; #endif /* Definitions of AEAD algorithms. From 89c9fa1bcfdea67b580f11dfa9930c7f6547acf7 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Sat, 4 Nov 2023 07:56:36 +0100 Subject: [PATCH 59/84] engines can be tested using `test_picotls` --- CMakeLists.txt | 2 +- include/picotls/mbedtls.h | 2 + lib/mbedtls.c | 5 + t/mbedtls.c | 425 +++++--------------------------------- 4 files changed, 56 insertions(+), 378 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e816e57f..f1f2f736f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -211,7 +211,7 @@ IF (WITH_MBEDTLS) ADD_LIBRARY(picotls-mbedtls lib/mbedtls.c) ADD_EXECUTABLE(test-mbedtls.t deps/picotest/picotest.c - lib/picotls.c + ${CORE_TEST_FILES} t/mbedtls.c) TARGET_LINK_LIBRARIES(test-mbedtls.t picotls-minicrypto picotls-mbedtls diff --git a/include/picotls/mbedtls.h b/include/picotls/mbedtls.h index 3e8904c7d..538a2508f 100644 --- a/include/picotls/mbedtls.h +++ b/include/picotls/mbedtls.h @@ -51,9 +51,11 @@ extern ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305; extern ptls_cipher_suite_t ptls_mbedtls_aes128gcmsha256; extern ptls_cipher_suite_t ptls_mbedtls_aes256gcmsha384; extern ptls_cipher_suite_t ptls_mbedtls_chacha20poly1305sha256; +extern ptls_cipher_suite_t *ptls_mbedtls_cipher_suites[]; extern ptls_key_exchange_algorithm_t ptls_mbedtls_secp256r1; extern ptls_key_exchange_algorithm_t ptls_mbedtls_x25519; +extern ptls_key_exchange_algorithm_t *ptls_mbedtls_key_exchanges[]; void ptls_mbedtls_random_bytes(void *buf, size_t len); diff --git a/lib/mbedtls.c b/lib/mbedtls.c index 629b6c013..f15467931 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -576,6 +576,9 @@ ptls_cipher_suite_t ptls_mbedtls_chacha20poly1305sha256 = {.id = PTLS_CIPHER_SUI .aead = &ptls_mbedtls_chacha20poly1305, .hash = &ptls_mbedtls_sha256}; +ptls_cipher_suite_t *ptls_mbedtls_cipher_suites[] = {&ptls_mbedtls_aes256gcmsha384, &ptls_mbedtls_aes128gcmsha256, + &ptls_mbedtls_chacha20poly1305sha256, NULL}; + /* Key exchange algorithms. * The Picotls framework defines these algorithms as ptls_key_exchange_algorithm_t, * a structure containing two function pointers: @@ -786,3 +789,5 @@ ptls_key_exchange_algorithm_t ptls_mbedtls_x25519 = {.id = PTLS_GROUP_X25519, .name = PTLS_GROUP_NAME_X25519, .create = ptls_mbedtls_x25519_create, .exchange = ptls_mbedtls_x25519_exchange}; + +ptls_key_exchange_algorithm_t *ptls_mbedtls_key_exchanges[] = {&ptls_mbedtls_secp256r1, NULL}; diff --git a/t/mbedtls.c b/t/mbedtls.c index faff669e2..1a86d9f48 100644 --- a/t/mbedtls.c +++ b/t/mbedtls.c @@ -36,6 +36,7 @@ #include "picotls/mbedtls.h" #include "picotls/minicrypto.h" #include "../deps/picotest/picotest.h" +#include "test.h" static int random_trial() { @@ -74,367 +75,6 @@ static void test_random(void) ok(!!"success"); } -static int hash_trial(ptls_hash_algorithm_t *algo, const uint8_t *input, size_t len1, size_t len2, uint8_t *final_hash) -{ - int ret = 0; - ptls_hash_context_t *hash_ctx = algo->create(); - - hash_ctx->update(hash_ctx, input, len1); - if (len2 > 0) { - hash_ctx->update(hash_ctx, input + len1, len2); - } - hash_ctx->final(hash_ctx, final_hash, PTLS_HASH_FINAL_MODE_FREE); - - return ret; -} - -static int hash_reset_trial(ptls_hash_algorithm_t *algo, const uint8_t *input, size_t len1, size_t len2, uint8_t *hash1, - uint8_t *hash2) -{ - int ret = 0; - ptls_hash_context_t *hash_ctx = algo->create(); - - hash_ctx->update(hash_ctx, input, len1); - hash_ctx->final(hash_ctx, hash1, PTLS_HASH_FINAL_MODE_RESET); - hash_ctx->update(hash_ctx, input + len1, len2); - hash_ctx->final(hash_ctx, hash2, PTLS_HASH_FINAL_MODE_FREE); - - return ret; -} - -static int test_hash(ptls_hash_algorithm_t *algo, ptls_hash_algorithm_t *ref) -{ - int ret = 0; - uint8_t input[1234]; - uint8_t final_hash[64]; - uint8_t final_ref[64]; - uint8_t hash1[64], hash2[64], href1[64], href2[64]; - - memset(input, 0xba, sizeof(input)); - - ret = hash_trial(algo, input, sizeof(input), 0, final_hash); - if (ret == 0) { - ret = hash_trial(ref, input, sizeof(input), 0, final_ref); - } - if (ret == 0) { - if (memcmp(final_hash, final_ref, ref->digest_size) != 0) { - ret = -1; - } - } - if (ret == 0) { - ret = hash_trial(algo, input, sizeof(input) - 17, 17, final_hash); - } - if (ret == 0) { - if (memcmp(final_hash, final_ref, ref->digest_size) != 0) { - ret = -1; - } - } - - if (ret == 0) { - ret = hash_reset_trial(algo, input, sizeof(input) - 126, 126, hash1, hash2); - } - if (ret == 0) { - ret = hash_reset_trial(ref, input, sizeof(input) - 126, 126, href1, href2); - } - if (ret == 0) { - if (memcmp(hash1, href1, ref->digest_size) != 0) { - ret = -1; - } else if (memcmp(hash2, href2, ref->digest_size) != 0) { - ret = -1; - } - } - - return ret; -} - -static int cipher_trial(ptls_cipher_algorithm_t *cipher, const uint8_t *key, const uint8_t *iv, int is_enc, const uint8_t *v_in, - uint8_t *v_out1, uint8_t *v_out2, size_t len) -{ - int ret = 0; - ptls_cipher_context_t *test_cipher = ptls_cipher_new(cipher, is_enc, key); - if (test_cipher == NULL) { - ret = -1; - } else { - if (test_cipher->do_init != NULL) { - ptls_cipher_init(test_cipher, iv); - } - ptls_cipher_encrypt(test_cipher, v_out1, v_in, len); - if (test_cipher->do_init != NULL) { - ptls_cipher_init(test_cipher, iv); - } - ptls_cipher_encrypt(test_cipher, v_out2, v_out1, len); - ptls_cipher_free(test_cipher); - } - - return ret; -} - -static int test_cipher(ptls_cipher_algorithm_t *cipher, ptls_cipher_algorithm_t *cipher_ref) -{ - uint8_t key[32]; - uint8_t iv[16]; - uint8_t v_in[16]; - uint8_t v_out_1a[16], v_out_2a[16], v_out_1b[16], v_out_2b[16], v_out_1d[16], v_out_2d[16]; - int ret = 0; - - /* Set initial values */ - memset(key, 0x55, sizeof(key)); - memset(iv, 0x33, sizeof(iv)); - memset(v_in, 0xaa, sizeof(v_in)); - - /* Encryption test */ - ret = cipher_trial(cipher, key, iv, 1, v_in, v_out_1a, v_out_2a, 16); - if (ret == 0) { - ret = cipher_trial(cipher_ref, key, iv, 1, v_in, v_out_1b, v_out_2b, 16); - } - if (ret == 0) { - if (memcmp(v_out_1a, v_out_1b, 16) != 0) { - ret = -1; - } else if (memcmp(v_out_2a, v_out_2b, 16) != 0) { - ret = -1; - } - } - /* decryption test */ - if (ret == 0) { - ret = cipher_trial(cipher, key, iv, 0, v_out_2a, v_out_1d, v_out_2d, 16); - } - if (ret == 0) { - if (memcmp(v_out_1a, v_out_1d, 16) != 0) { - ret = -1; - } else if (memcmp(v_out_2d, v_in, 16) != 0) { - ret = -1; - } - } - - return ret; -} - -static int label_test(ptls_hash_algorithm_t *hash, uint8_t *v_out, size_t o_len, const uint8_t *secret, char const *label, - char const *label_prefix) -{ - uint8_t h_val_v[32]; - ptls_iovec_t h_val = {0}; - ptls_iovec_t s_vec = {0}; - s_vec.base = (uint8_t *)secret; - s_vec.len = 32; - h_val.base = h_val_v; - h_val.len = 32; - memset(h_val_v, 0, sizeof(h_val_v)); - - ptls_hkdf_expand_label(hash, v_out, o_len, s_vec, label, h_val, label_prefix); - return 0; -} - -static int test_label(ptls_hash_algorithm_t *hash, ptls_hash_algorithm_t *ref) -{ - int ret = 0; - uint8_t v_out[16], v_ref[16]; - uint8_t secret[32]; - char const *label = "label"; - char const *label_prefix = "label_prefix"; - memset(secret, 0x5e, sizeof(secret)); - - ret = label_test(hash, v_out, 16, secret, label, label_prefix); - - if (ret == 0) { - ret = label_test(ref, v_ref, 16, secret, label, label_prefix); - } - - if (ret == 0 && memcmp(v_out, v_ref, 16) != 0) { - ret = -1; - } - - return ret; -} - -static int aead_trial(ptls_aead_algorithm_t *algo, ptls_hash_algorithm_t *hash, const uint8_t *secret, int is_enc, - const uint8_t *v_in, size_t len, uint8_t *aad, size_t aad_len, uint64_t seq, uint8_t *v_out, size_t *o_len) -{ - int ret = 0; - ptls_aead_context_t *aead = ptls_aead_new(algo, hash, is_enc, secret, "test_aead"); - - if (aead == NULL) { - ret = -1; - } else { - if (is_enc) { - *o_len = ptls_aead_encrypt(aead, v_out, v_in, len, seq, aad, aad_len); - if (*o_len != len + algo->tag_size) { - ret = -1; - } - } else { - *o_len = ptls_aead_decrypt(aead, v_out, v_in, len, seq, aad, aad_len); - if (*o_len != len - algo->tag_size) { - ret = -1; - } - } - ptls_aead_free(aead); - } - return ret; -} - -static int test_aead(ptls_aead_algorithm_t *algo, ptls_hash_algorithm_t *hash, ptls_aead_algorithm_t *ref, - ptls_hash_algorithm_t *hash_ref) -{ - uint8_t secret[64]; - uint8_t v_in[1234]; - uint8_t aad[17]; - uint8_t v_out_a[1250], v_out_b[1250], v_out_r[1250]; - size_t olen_a, olen_b, olen_r; - uint64_t seq = 12345; - int ret = 0; - - memset(secret, 0x58, sizeof(secret)); - memset(v_in, 0x12, sizeof(v_in)); - memset(aad, 0xaa, sizeof(aad)); - - ret = aead_trial(algo, hash, secret, 1, v_in, sizeof(v_in), aad, sizeof(aad), seq, v_out_a, &olen_a); - if (ret == 0) { - ret = aead_trial(ref, hash_ref, secret, 1, v_in, sizeof(v_in), aad, sizeof(aad), seq, v_out_b, &olen_b); - } - if (ret == 0 && (olen_a != olen_b || memcmp(v_out_a, v_out_b, olen_a) != 0)) { - ret = -1; - } - if (ret == 0) { - ret = aead_trial(ref, hash_ref, secret, 0, v_out_a, olen_a, aad, sizeof(aad), seq, v_out_r, &olen_r); - } - if (ret == 0 && (olen_r != sizeof(v_in) || memcmp(v_in, v_out_r, sizeof(v_in)) != 0)) { - ret = -1; - } - return ret; -} - -static void test_sha256(void) -{ - if (test_hash(&ptls_mbedtls_sha256, &ptls_minicrypto_sha256) != 0) { - ok(!"fail"); - return; - } - ok(!!"success"); -} - -#if defined(MBEDTLS_SHA384_C) -static void test_sha384(void) -{ - if (test_hash(&ptls_mbedtls_sha384, &ptls_minicrypto_sha384) != 0) { - ok(!"fail"); - return; - } - ok(!!"success"); -} -#endif - -static void test_label_sha256(void) -{ - if (test_label(&ptls_mbedtls_sha256, &ptls_minicrypto_sha256) != 0) { - ok(!"fail"); - return; - } - ok(!!"success"); -} - -static void test_aes128ecb(void) -{ - if (test_cipher(&ptls_mbedtls_aes128ecb, &ptls_minicrypto_aes128ecb) != 0) { - ok(!"fail"); - } - ok(!!"success"); -} - -static void test_aes128ctr(void) -{ - if (test_cipher(&ptls_mbedtls_aes128ctr, &ptls_minicrypto_aes128ctr) != 0) { - ok(!"fail"); - } - ok(!!"success"); -} - -static void test_aes256ecb(void) -{ - if (test_cipher(&ptls_mbedtls_aes256ecb, &ptls_minicrypto_aes256ecb) != 0) { - ok(!"fail"); - } - ok(!!"success"); -} - -static void test_aes256ctr(void) -{ - if (test_cipher(&ptls_mbedtls_aes256ctr, &ptls_minicrypto_aes256ctr) != 0) { - ok(!"fail"); - } - ok(!!"success"); -} - -static void test_chacha20(void) -{ - if (test_cipher(&ptls_mbedtls_chacha20, &ptls_minicrypto_chacha20) != 0) { - ok(!"fail"); - } - ok(!!"success"); -} - -static void test_aes128gcm_sha256(void) -{ - if (test_aead(&ptls_mbedtls_aes128gcm, &ptls_mbedtls_sha256, &ptls_minicrypto_aes128gcm, &ptls_minicrypto_sha256) != 0) { - ok(!"fail"); - } - ok(!!"success"); -} - -#if defined(MBEDTLS_SHA384_C) -static void test_aes256gcm_sha384(void) -{ - if (test_aead(&ptls_mbedtls_aes256gcm, &ptls_mbedtls_sha384, &ptls_minicrypto_aes256gcm, &ptls_minicrypto_sha384) != 0) { - ok(!"fail"); - } - ok(!!"success"); -} -#endif - -static void test_chacha20poly1305_sha256(void) -{ - if (test_aead(&ptls_mbedtls_chacha20poly1305, &ptls_mbedtls_sha256, &ptls_minicrypto_chacha20poly1305, - &ptls_minicrypto_sha256) != 0) { - ok(!"fail"); - } - ok(!!"success"); -} - -/* Test key exchange. This is a cut and paste of the "test_key_exchange" - * defined in test.h and openssl.c, because referring to that common code - * causes a link error. - */ -static void test_key_exchange(ptls_key_exchange_algorithm_t *client, ptls_key_exchange_algorithm_t *server) -{ - ptls_key_exchange_context_t *ctx; - ptls_iovec_t client_secret, server_pubkey, server_secret; - int ret; - - /* fail */ - ret = server->exchange(server, &server_pubkey, &server_secret, (ptls_iovec_t){NULL}); - ok(ret != 0); - - /* perform ecdh */ - ret = client->create(client, &ctx); - ok(ret == 0); - ret = server->exchange(server, &server_pubkey, &server_secret, ctx->pubkey); - ok(ret == 0); - ret = ctx->on_exchange(&ctx, 1, &client_secret, server_pubkey); - ok(ret == 0); - ok(client_secret.len == server_secret.len); - ok(memcmp(client_secret.base, server_secret.base, client_secret.len) == 0); - - free(client_secret.base); - free(server_pubkey.base); - free(server_secret.base); - - /* client abort */ - ret = client->create(client, &ctx); - ok(ret == 0); - ret = ctx->on_exchange(&ctx, 1, NULL, ptls_iovec_init(NULL, 0)); - ok(ret == 0); - ok(ctx == NULL); -} - static void test_secp256r1(void) { test_key_exchange(&ptls_mbedtls_secp256r1, &ptls_minicrypto_secp256r1); @@ -453,6 +93,9 @@ static void test_key_exchanges(void) subtest("x25519", test_x25519); } +DEFINE_FFX_AES128_ALGORITHMS(mbedtls); +DEFINE_FFX_CHACHA20_ALGORITHMS(mbedtls); + int main(int argc, char **argv) { /* Initialize the PSA crypto library. */ @@ -460,25 +103,53 @@ int main(int argc, char **argv) note("psa_crypto_init fails."); return done_testing(); } + /* Test of the port of the mbedtls random generator */ subtest("random", test_random); - /* Series of test to check consistency between wrapped mbedtls and minicrypto */ - subtest("sha256", test_sha256); -#if defined(MBEDTLS_SHA384_C) - subtest("sha384", test_sha384); -#endif - subtest("label_sha256", test_label_sha256); - subtest("aes128ecb", test_aes128ecb); - subtest("aes128ctr", test_aes128ctr); - subtest("aes256ecb", test_aes256ecb); - subtest("aes256ctr", test_aes256ctr); - subtest("chacha20", test_chacha20); - subtest("aes128gcm_sha256", test_aes128gcm_sha256); -#if defined(MBEDTLS_SHA384_C) - subtest("aes256gcm_sha384", test_aes256gcm_sha384); -#endif - subtest("chacha20poly1305_sha256", test_chacha20poly1305_sha256); subtest("key_exchanges", test_key_exchanges); + + ADD_FFX_AES128_ALGORITHMS(mbedtls); + ADD_FFX_CHACHA20_ALGORITHMS(mbedtls); + + /* minicrypto contexts used as peer for valiation */ + ptls_iovec_t secp256r1_certificate = ptls_iovec_init(SECP256R1_CERTIFICATE, sizeof(SECP256R1_CERTIFICATE) - 1); + ptls_minicrypto_secp256r1sha256_sign_certificate_t minicrypto_sign_certificate; + ptls_minicrypto_init_secp256r1sha256_sign_certificate( + &minicrypto_sign_certificate, ptls_iovec_init(SECP256R1_PRIVATE_KEY, sizeof(SECP256R1_PRIVATE_KEY) - 1)); + ptls_context_t minicrypto_ctx = {ptls_minicrypto_random_bytes, + &ptls_get_time, + ptls_minicrypto_key_exchanges, + ptls_minicrypto_cipher_suites, + {&secp256r1_certificate, 1}, + {{NULL}}, + NULL, + NULL, + &minicrypto_sign_certificate.super}; + + /* context using mbedtls as backend; minicrypto is used for signing certificate as the mbedtls backend does not (yet) have the + * capability */ + ptls_context_t mbedtls_ctx = {ptls_mbedtls_random_bytes, + &ptls_get_time, + ptls_mbedtls_key_exchanges, + ptls_mbedtls_cipher_suites, + {&minicrypto_certificate, 1}, + {{NULL}}, + NULL, + NULL, + &minicrypto_sign_certificate.super}; + + ctx = &mbedtls_ctx; + ctx_peer = &mbedtls_ctx; + subtest("selt-test", test_picotls); + + ctx = &mbedtls_ctx; + ctx_peer = &minicrypto_ctx; + subtest("vs. minicrypto", test_picotls); + + ctx = &minicrypto_ctx; + ctx_peer = &mbedtls_ctx; + subtest("minicrypto vs.", test_picotls); + /* Deinitialize the PSA crypto library. */ mbedtls_psa_crypto_free(); From bdec08f79bf56a144fd9bb54eef6722411c7d527 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Sat, 4 Nov 2023 10:28:39 +0100 Subject: [PATCH 60/84] report error in detail --- lib/mbedtls.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/mbedtls.c b/lib/mbedtls.c index f15467931..64b50c22d 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -34,8 +34,9 @@ #define CALL_WITH_CHECK(fn, ...) \ do { \ - if (fn(__VA_ARGS__) != PSA_SUCCESS) { \ - fprintf(stderr, PTLS_TO_STR(fn) " failed\n"); \ + psa_status_t ret; \ + if ((ret = fn(__VA_ARGS__)) != PSA_SUCCESS) { \ + fprintf(stderr, "in %s at line %d, " PTLS_TO_STR(fn) " failed (%d)\n", __FUNCTION__, __LINE__, (int)ret); \ abort(); \ } \ } while (0) From c4521e8e467410e2c56375aa005d84a0a1ccb4dd Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Sat, 4 Nov 2023 10:29:21 +0100 Subject: [PATCH 61/84] have ones own --- t/mbedtls.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/t/mbedtls.c b/t/mbedtls.c index 1a86d9f48..94cf55cd8 100644 --- a/t/mbedtls.c +++ b/t/mbedtls.c @@ -128,15 +128,18 @@ int main(int argc, char **argv) /* context using mbedtls as backend; minicrypto is used for signing certificate as the mbedtls backend does not (yet) have the * capability */ + ptls_minicrypto_secp256r1sha256_sign_certificate_t mbedtls_sign_certificate; + ptls_minicrypto_init_secp256r1sha256_sign_certificate( + &mbedtls_sign_certificate, ptls_iovec_init(SECP256R1_PRIVATE_KEY, sizeof(SECP256R1_PRIVATE_KEY) - 1)); ptls_context_t mbedtls_ctx = {ptls_mbedtls_random_bytes, &ptls_get_time, ptls_mbedtls_key_exchanges, ptls_mbedtls_cipher_suites, - {&minicrypto_certificate, 1}, + {&secp256r1_certificate, 1}, {{NULL}}, NULL, NULL, - &minicrypto_sign_certificate.super}; + &mbedtls_sign_certificate.super}; ctx = &mbedtls_ctx; ctx_peer = &mbedtls_ctx; From e6ac47f50d15ed66d61df8e1f0588d3850a07cc4 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Sat, 4 Nov 2023 10:44:27 +0100 Subject: [PATCH 62/84] amend 2106299 --- lib/mbedtls.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/lib/mbedtls.c b/lib/mbedtls.c index 64b50c22d..54ca9f5f4 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -79,7 +79,11 @@ DEFINE_HASH(sha384, SHA384, PSA_ALG_SHA_384); */ struct st_ptls_mbedtls_cipher_context_t { ptls_cipher_context_t super; + psa_algorithm_t alg; size_t iv_length; + unsigned is_enc : 1; + unsigned is_op_in_progress : 1; + mbedtls_svc_key_id_t key; psa_cipher_operation_t op; }; @@ -87,6 +91,18 @@ static void cipher_init(ptls_cipher_context_t *_ctx, const void *iv) { struct st_ptls_mbedtls_cipher_context_t *ctx = (struct st_ptls_mbedtls_cipher_context_t *)_ctx; + if (ctx->is_op_in_progress) { + psa_cipher_abort(&ctx->op); + ctx->is_op_in_progress = 0; + } + + ctx->op = psa_cipher_operation_init(); + if (ctx->is_enc) { + CALL_WITH_CHECK(psa_cipher_encrypt_setup, &ctx->op, ctx->key, ctx->alg); + } else { + CALL_WITH_CHECK(psa_cipher_decrypt_setup, &ctx->op, ctx->key, ctx->alg); + } + ctx->is_op_in_progress = 1; if (ctx->iv_length > 0) CALL_WITH_CHECK(psa_cipher_set_iv, &ctx->op, iv, ctx->iv_length); } @@ -103,14 +119,15 @@ static void cipher_dispose(ptls_cipher_context_t *_ctx) { struct st_ptls_mbedtls_cipher_context_t *ctx = (struct st_ptls_mbedtls_cipher_context_t *)_ctx; - psa_cipher_abort(&ctx->op); + if (ctx->is_op_in_progress) + psa_cipher_abort(&ctx->op); + psa_destroy_key(ctx->key); } static int setup_crypto(ptls_cipher_context_t *_ctx, int is_enc, const void *key_bytes, psa_algorithm_t alg, size_t iv_length, psa_key_type_t key_type, size_t key_bits) { struct st_ptls_mbedtls_cipher_context_t *ctx = (struct st_ptls_mbedtls_cipher_context_t *)_ctx; - mbedtls_svc_key_id_t key; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; /* import key or fail immediately */ @@ -118,20 +135,18 @@ static int setup_crypto(ptls_cipher_context_t *_ctx, int is_enc, const void *key psa_set_key_algorithm(&attributes, alg); psa_set_key_type(&attributes, key_type); psa_set_key_bits(&attributes, key_bits); - if (psa_import_key(&attributes, key_bytes, key_bits / 8, &key) != PSA_SUCCESS) + if (psa_import_key(&attributes, key_bytes, key_bits / 8, &ctx->key) != PSA_SUCCESS) return PTLS_ERROR_LIBRARY; - /* init context */ + /* init the rest that are guaranteed to succeed */ ctx->super.do_dispose = cipher_dispose; ctx->super.do_init = cipher_init; ctx->super.do_transform = cipher_transform; + ctx->alg = alg; ctx->iv_length = iv_length; + ctx->is_enc = is_enc; + ctx->is_op_in_progress = 0; ctx->op = psa_cipher_operation_init(); - if (is_enc) { - CALL_WITH_CHECK(psa_cipher_encrypt_setup, &ctx->op, key, alg); - } else { - CALL_WITH_CHECK(psa_cipher_decrypt_setup, &ctx->op, key, alg); - } return 0; } From 4d5827ddd46517ec24a31067fedb91e05ea60481 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Sat, 4 Nov 2023 10:54:02 +0100 Subject: [PATCH 63/84] `ptls_cipher_init` is not called in ECB mode --- lib/mbedtls.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/lib/mbedtls.c b/lib/mbedtls.c index 54ca9f5f4..f7dd20d56 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -124,7 +124,7 @@ static void cipher_dispose(ptls_cipher_context_t *_ctx) psa_destroy_key(ctx->key); } -static int setup_crypto(ptls_cipher_context_t *_ctx, int is_enc, const void *key_bytes, psa_algorithm_t alg, size_t iv_length, +static int cipher_setup(ptls_cipher_context_t *_ctx, int is_enc, const void *key_bytes, psa_algorithm_t alg, size_t iv_length, psa_key_type_t key_type, size_t key_bits) { struct st_ptls_mbedtls_cipher_context_t *ctx = (struct st_ptls_mbedtls_cipher_context_t *)_ctx; @@ -151,9 +151,27 @@ static int setup_crypto(ptls_cipher_context_t *_ctx, int is_enc, const void *key return 0; } +static int ecb_setup(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes, psa_key_type_t key_type, size_t key_bits) +{ + int ret; + + if ((ret = cipher_setup(ctx, is_enc, key_bytes, PSA_ALG_ECB_NO_PADDING, 0, key_type, key_bits)) != 0) + return ret; + /* ECB mode does not necessary call `ptls_cipher_init` */ + cipher_init(ctx, NULL); + + return 0; +} + +static int ctr_setup(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes, size_t iv_length, psa_key_type_t key_type, + size_t key_bits) +{ + return cipher_setup(ctx, is_enc, key_bytes, PSA_ALG_CTR, iv_length, key_type, key_bits); +} + static int setup_aes128ecb(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) { - return setup_crypto(ctx, is_enc, key_bytes, PSA_ALG_ECB_NO_PADDING, 0, PSA_KEY_TYPE_AES, 128); + return ecb_setup(ctx, is_enc, key_bytes, PSA_KEY_TYPE_AES, 128); } ptls_cipher_algorithm_t ptls_mbedtls_aes128ecb = { @@ -165,7 +183,7 @@ ptls_cipher_algorithm_t ptls_mbedtls_aes128ecb = { */ static int setup_aes256ecb(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) { - return setup_crypto(ctx, is_enc, key_bytes, PSA_ALG_ECB_NO_PADDING, 0, PSA_KEY_TYPE_AES, 256); + return ecb_setup(ctx, is_enc, key_bytes, PSA_KEY_TYPE_AES, 256); } ptls_cipher_algorithm_t ptls_mbedtls_aes256ecb = { @@ -178,7 +196,7 @@ ptls_cipher_algorithm_t ptls_mbedtls_aes256ecb = { static int setup_aes128ctr(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) { - return setup_crypto(ctx, is_enc, key_bytes, PSA_ALG_CTR, 16, PSA_KEY_TYPE_AES, 128); + return ctr_setup(ctx, is_enc, key_bytes, 16, PSA_KEY_TYPE_AES, 128); } ptls_cipher_algorithm_t ptls_mbedtls_aes128ctr = { @@ -191,7 +209,7 @@ ptls_cipher_algorithm_t ptls_mbedtls_aes128ctr = { static int setup_aes256ctr(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) { - return setup_crypto(ctx, is_enc, key_bytes, PSA_ALG_CTR, 16, PSA_KEY_TYPE_AES, 256); + return ctr_setup(ctx, is_enc, key_bytes, 16, PSA_KEY_TYPE_AES, 256); } ptls_cipher_algorithm_t ptls_mbedtls_aes256ctr = { @@ -206,7 +224,7 @@ ptls_cipher_algorithm_t ptls_mbedtls_aes256ctr = { */ static int setup_crypto_chacha20(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) { - return setup_crypto(ctx, is_enc, key_bytes, PSA_ALG_STREAM_CIPHER, 16, PSA_KEY_TYPE_CHACHA20, 256); + return cipher_setup(ctx, is_enc, key_bytes, PSA_ALG_STREAM_CIPHER, 16, PSA_KEY_TYPE_CHACHA20, 256); } ptls_cipher_algorithm_t ptls_mbedtls_chacha20 = { From 046b582a39ea3625cab90c71310a7897c8661e34 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Tue, 14 Nov 2023 09:51:33 +0900 Subject: [PATCH 64/84] limit scope of `psa_key_attributes_t` --- lib/mbedtls.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/mbedtls.c b/lib/mbedtls.c index f7dd20d56..80ed6ce45 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -128,15 +128,16 @@ static int cipher_setup(ptls_cipher_context_t *_ctx, int is_enc, const void *key psa_key_type_t key_type, size_t key_bits) { struct st_ptls_mbedtls_cipher_context_t *ctx = (struct st_ptls_mbedtls_cipher_context_t *)_ctx; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - /* import key or fail immediately */ - psa_set_key_usage_flags(&attributes, (is_enc) ? PSA_KEY_USAGE_ENCRYPT : PSA_KEY_USAGE_DECRYPT); - psa_set_key_algorithm(&attributes, alg); - psa_set_key_type(&attributes, key_type); - psa_set_key_bits(&attributes, key_bits); - if (psa_import_key(&attributes, key_bytes, key_bits / 8, &ctx->key) != PSA_SUCCESS) - return PTLS_ERROR_LIBRARY; + { /* import key or fail immediately */ + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, is_enc ? PSA_KEY_USAGE_ENCRYPT : PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, key_type); + psa_set_key_bits(&attributes, key_bits); + if (psa_import_key(&attributes, key_bytes, key_bits / 8, &ctx->key) != PSA_SUCCESS) + return PTLS_ERROR_LIBRARY; + } /* init the rest that are guaranteed to succeed */ ctx->super.do_dispose = cipher_dispose; From 47411024167a26df38b034f2e4e74deb4f88eaf4 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Tue, 14 Nov 2023 10:21:55 +0900 Subject: [PATCH 65/84] move useful comments to `.h`, as they are not specific to the mbedtls backend --- include/picotls.h | 70 +++++++++++++++++++++++++++++++++++++++++------ lib/mbedtls.c | 34 ----------------------- 2 files changed, 62 insertions(+), 42 deletions(-) diff --git a/include/picotls.h b/include/picotls.h index 374543054..49271f77a 100644 --- a/include/picotls.h +++ b/include/picotls.h @@ -398,31 +398,81 @@ typedef const struct st_ptls_cipher_algorithm_t { int (*setup_crypto)(ptls_cipher_context_t *ctx, int is_enc, const void *key); } ptls_cipher_algorithm_t; +/** + * This object specifies symmetric cipher to be calculated alongside the AEAD encryption. + * QUIC stacks can use this object to apply QUIC header protection and AEAD encryption in one shot. + */ typedef struct st_ptls_aead_supplementary_encryption_t { + /** + * Cipher context to be used. + */ ptls_cipher_context_t *ctx; + /** + * Input to the cipher. + * This field may point to the output of AEAD encryption, in which case the input will be read after AEAD encryption is + * complete. + */ const void *input; + /** + * Output. + */ uint8_t output[16]; } ptls_aead_supplementary_encryption_t; /** - * AEAD context. AEAD implementations are allowed to stuff data at the end of the struct. The size of the memory allocated for the - * struct is governed by ptls_aead_algorithm_t::context_size. - * Ciphers for TLS over TCP MUST implement `do_encrypt`, `do_encrypt_v`, `do_decrypt`. `do_encrypt_init`, `~update`, `~final` are - * obsolete, and therefore may not be available. + * AEAD context. + * AEAD implementations are allowed to stuff data at the end of the struct; see `ptls_aead_algorithm_t::setup_crypto`. + * Ciphers for TLS over TCP MUST implement `do_encrypt`, `do_encrypt_v`, `do_decrypt`. + * `do_encrypt_init`, `~update`, `~final` are obsolete, and therefore may not be available. */ typedef struct st_ptls_aead_context_t { + /** + * Points to the algorithm. This field is governed by picotls core; backends must not alter. + */ const struct st_ptls_aead_algorithm_t *algo; - /* field above this line must not be altered by the crypto binding */ + /** + * Mandatory callback that disposes of all the backend-specific data. + */ void (*dispose_crypto)(struct st_ptls_aead_context_t *ctx); + /** + * Mandatory callback that returns the static IV. The size of IV is available as `ptls_aead_algorithm_t::iv_size`. + */ void (*do_get_iv)(struct st_ptls_aead_context_t *ctx, void *iv); + /** + * Mandatory callback that sets the static IV. The size of IV is available as `ptls_aead_algorithm_t::iv_size`. + */ void (*do_set_iv)(struct st_ptls_aead_context_t *ctx, const void *iv); + /** + * Deprecated. + */ void (*do_encrypt_init)(struct st_ptls_aead_context_t *ctx, uint64_t seq, const void *aad, size_t aadlen); + /** + * Deprecated. + */ size_t (*do_encrypt_update)(struct st_ptls_aead_context_t *ctx, void *output, const void *input, size_t inlen); + /** + * Deprecated. + */ size_t (*do_encrypt_final)(struct st_ptls_aead_context_t *ctx, void *output); + /** + * Mandatory callback that does "one-shot" encryption of an AEAD block. + * When `supp` is set to non-NULL, the callback must also encrypt the supplementary block. + * Backends may set this field to `ptls_aead__do_encrypt` that calls `do_encrypt_v` and `ptls_cipher_*` functions for handling + * the supplimentary block. + */ void (*do_encrypt)(struct st_ptls_aead_context_t *ctx, void *output, const void *input, size_t inlen, uint64_t seq, const void *aad, size_t aadlen, ptls_aead_supplementary_encryption_t *supp); + /** + * Variant of `do_encrypt` that gathers input from multiple blocks. Support for this callback is also mandatory. + * Legacy backends may set this field to `ptls_aead__do_encrypt_v` that calls `do_encrypt_init`, `do_encrypt_update`, + * `do_encrypt_final`. + */ void (*do_encrypt_v)(struct st_ptls_aead_context_t *ctx, void *output, ptls_iovec_t *input, size_t incnt, uint64_t seq, const void *aad, size_t aadlen); + /** + * Mandatory callback for decrypting an AEAD block. + * If successful, returns the amount of cleartext bytes being written to output. Otherwise, returns SIZE_MAX. + */ size_t (*do_decrypt)(struct st_ptls_aead_context_t *ctx, void *output, const void *input, size_t inlen, uint64_t seq, const void *aad, size_t aadlen); } ptls_aead_context_t; @@ -479,12 +529,16 @@ typedef const struct st_ptls_aead_algorithm_t { */ uint8_t align_bits; /** - * size of memory allocated for ptls_aead_context_t. AEAD implementations can set this value to something greater than - * sizeof(ptls_aead_context_t) and stuff additional data at the bottom of the struct. + * size of memory allocated for `ptls_aead_context_t` */ size_t context_size; /** - * callback that sets up the crypto + * Backend callback called to setup `ptls_aead_context_t`. + * Backends are allowed to stuff arbitrary data at the end of `ptls_aead_context_t`; actual size of the memory chunk being + * allocated is that specified by `ptls_aead_algorithm_t::context_size`. When the `setup_crypto` callback is called, all the + * fields outside of `ptls_aead_context_t` will be in undefined state; it is the responsibility of the callback to initialize + * them, as well as the callbacks of `ptls_aead_context_t` that the backend supports. + * A non-zero return value indicates failure, in which case the error will propagate as `ptls_aead_new` returning NULL. */ int (*setup_crypto)(ptls_aead_context_t *ctx, int is_enc, const void *key, const void *iv); } ptls_aead_algorithm_t; diff --git a/lib/mbedtls.c b/lib/mbedtls.c index 80ed6ce45..7979802e0 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -290,40 +290,6 @@ ptls_cipher_algorithm_t ptls_mbedtls_chacha20 = {"CHACHA20", setup_chacha20}; #endif -/* Definitions of AEAD algorithms. - * - * For the picotls API, AEAD algorithms are created by calling: - * - * ptls_aead_context_t *ptls_aead_new(ptls_aead_algorithm_t *aead, - * ptls_hash_algorithm_t *hash, int is_enc, const void *secret, - * const char *label_prefix) - * That procedure will allocate memory and create keys, and then call - * a provider specific function: - * - * if (aead->setup_crypto(ctx, is_enc, key, iv) != 0) { - * free(ctx); - * return NULL; - * } - * - * The function will finish completing the aead structure, perform - * initialization, and then document the function pointers: - * - * ctx->super.dispose_crypto: release all resourc - * ctx->super.do_get_iv: return IV - * ctx->super.do_set_iv: set IV value - * ctx->super.do_decrypt: decrypt function - * ctx->super.do_encrypt_init: start encrypting one message - * ctx->super.do_encrypt_update: feed more ciphertext to descriptor - * ctx->super.do_encrypt_final: finalize encryption, including AEAD checksum - * ctx->super.do_encrypt: single shot variant of init/update/final - * ctx->super.do_encrypt_v: scatter gather version of do encrypt - * - * The aead context also documents the underlying "ECB" and "CTR" modes. - * In QUIC, these are used for PN encryption. - * - * TODO: declare other algorithms besides AES128_GCM - */ - struct ptls_mbedtls_aead_param_t { uint8_t static_iv[PTLS_MAX_IV_SIZE]; psa_algorithm_t alg; From 2e4ecad3deb0246327c2c97cea42282b64c13c1f Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Tue, 14 Nov 2023 11:04:59 +0900 Subject: [PATCH 66/84] simply AEAD code by only supporting the mandatory operation types --- lib/mbedtls.c | 246 ++++++++++++++------------------------------------ 1 file changed, 70 insertions(+), 176 deletions(-) diff --git a/lib/mbedtls.c b/lib/mbedtls.c index 7979802e0..d610b7abc 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -290,224 +290,118 @@ ptls_cipher_algorithm_t ptls_mbedtls_chacha20 = {"CHACHA20", setup_chacha20}; #endif -struct ptls_mbedtls_aead_param_t { +struct ptls_mbedtls_aead_context_t { + struct st_ptls_aead_context_t super; uint8_t static_iv[PTLS_MAX_IV_SIZE]; psa_algorithm_t alg; psa_key_id_t key; - psa_aead_operation_t op; - size_t extra_bytes; - int is_op_in_progress; -}; - -struct ptls_mbedtls_aead_context_t { - struct st_ptls_aead_context_t super; - struct ptls_mbedtls_aead_param_t mctx; }; -void ptls_mbedtls_aead_dispose_crypto(struct st_ptls_aead_context_t *_ctx) -{ - struct ptls_mbedtls_aead_context_t *ctx = (struct ptls_mbedtls_aead_context_t *)_ctx; - if (ctx->mctx.is_op_in_progress) { - psa_aead_abort(&ctx->mctx.op); - ctx->mctx.is_op_in_progress = 0; - } - psa_destroy_key(ctx->mctx.key); -} - -static void ptls_mbedtls_aead_get_iv(ptls_aead_context_t *_ctx, void *iv) +static void aead_dispose_crypto(struct st_ptls_aead_context_t *_ctx) { struct ptls_mbedtls_aead_context_t *ctx = (struct ptls_mbedtls_aead_context_t *)_ctx; - memcpy(iv, ctx->mctx.static_iv, ctx->super.algo->iv_size); + psa_destroy_key(ctx->key); } -static void ptls_mbedtls_aead_set_iv(ptls_aead_context_t *_ctx, const void *iv) +static void aead_get_iv(ptls_aead_context_t *_ctx, void *iv) { struct ptls_mbedtls_aead_context_t *ctx = (struct ptls_mbedtls_aead_context_t *)_ctx; - memcpy(ctx->mctx.static_iv, iv, ctx->super.algo->iv_size); + memcpy(iv, ctx->static_iv, ctx->super.algo->iv_size); } -void ptls_mbedtls_aead_do_encrypt_init(struct st_ptls_aead_context_t *_ctx, uint64_t seq, const void *aad, size_t aadlen) +static void aead_set_iv(ptls_aead_context_t *_ctx, const void *iv) { struct ptls_mbedtls_aead_context_t *ctx = (struct ptls_mbedtls_aead_context_t *)_ctx; - psa_status_t status; - - if (ctx->mctx.is_op_in_progress) { - psa_aead_abort(&ctx->mctx.op); /* required on errors, harmless on success */ - ctx->mctx.is_op_in_progress = 0; - } - - ctx->mctx.is_op_in_progress = 1; - memset(&ctx->mctx.op, 0, sizeof(ctx->mctx.op)); - - status = psa_aead_encrypt_setup(&ctx->mctx.op, ctx->mctx.key, ctx->mctx.alg); - if (status == PSA_SUCCESS) { - /* set the nonce. */ - uint8_t iv[PTLS_MAX_IV_SIZE]; - ptls_aead__build_iv(ctx->super.algo, iv, ctx->mctx.static_iv, seq); - status = psa_aead_set_nonce(&ctx->mctx.op, iv, ctx->super.algo->iv_size); - } - - if (status == PSA_SUCCESS) { - status = psa_aead_update_ad(&ctx->mctx.op, aad, aadlen); - } - - if (status != PSA_SUCCESS) { - psa_aead_abort(&ctx->mctx.op); /* required on errors, harmless on success */ - ctx->mctx.is_op_in_progress = 0; - } + memcpy(ctx->static_iv, iv, ctx->super.algo->iv_size); } -size_t ptls_mbedtls_aead_do_encrypt_update(struct st_ptls_aead_context_t *_ctx, void *output, const void *input, size_t inlen) +static void aead_encrypt_v(struct st_ptls_aead_context_t *_ctx, void *output, ptls_iovec_t *input, size_t incnt, uint64_t seq, + const void *aad, size_t aadlen) { - size_t olen = 0; struct ptls_mbedtls_aead_context_t *ctx = (struct ptls_mbedtls_aead_context_t *)_ctx; + psa_aead_operation_t op = psa_aead_operation_init(); + uint8_t *dst = output, iv[PTLS_MAX_IV_SIZE], tag[PSA_AEAD_TAG_MAX_SIZE]; + size_t outlen, taglen; - if (ctx->mctx.is_op_in_progress) { - size_t available = inlen + ctx->mctx.extra_bytes; - psa_status_t status = - psa_aead_update(&ctx->mctx.op, input, inlen, (uint8_t *)output, available + ctx->super.algo->tag_size, &olen); + /* setup op */ + CALL_WITH_CHECK(psa_aead_encrypt_setup, &op, ctx->key, ctx->alg); + ptls_aead__build_iv(ctx->super.algo, iv, ctx->static_iv, seq); + CALL_WITH_CHECK(psa_aead_set_nonce, &op, iv, ctx->super.algo->iv_size); + CALL_WITH_CHECK(psa_aead_update_ad, &op, aad, aadlen); - if (status == PSA_SUCCESS) { - if (olen < available) { - ctx->mctx.extra_bytes = available - olen; - } else { - ctx->mctx.extra_bytes = 0; - } - } else { - psa_aead_abort(&ctx->mctx.op); /* required on errors */ - ctx->mctx.is_op_in_progress = 0; - } + /* encrypt */ + for (size_t i = 0; i < incnt; i++) { + CALL_WITH_CHECK(psa_aead_update, &op, input[i].base, input[i].len, dst, SIZE_MAX, &outlen); + dst += outlen; } + CALL_WITH_CHECK(psa_aead_finish, &op, dst, SIZE_MAX, &outlen, tag, sizeof(tag), &taglen); + dst += outlen; + memcpy(dst, tag, taglen); - return olen; + /* destroy op */ + psa_aead_abort(&op); } -size_t ptls_mbedtls_aead_do_encrypt_final(struct st_ptls_aead_context_t *_ctx, void *output) +size_t aead_decrypt(struct st_ptls_aead_context_t *_ctx, void *output, const void *input, size_t inlen, uint64_t seq, + const void *aad, size_t aadlen) { - size_t olen = 0; struct ptls_mbedtls_aead_context_t *ctx = (struct ptls_mbedtls_aead_context_t *)_ctx; + uint8_t iv[PTLS_MAX_IV_SIZE]; + size_t outlen; - if (ctx->mctx.is_op_in_progress) { - unsigned char tag[PSA_AEAD_TAG_MAX_SIZE]; - size_t olen_tag = 0; - size_t available = ctx->mctx.extra_bytes; - uint8_t *p = (uint8_t *)output; - psa_status_t status = - psa_aead_finish(&ctx->mctx.op, p, available + ctx->super.algo->tag_size, &olen, tag, sizeof(tag), &olen_tag); - - if (status == PSA_SUCCESS) { - p += olen; - memcpy(p, tag, ctx->super.algo->tag_size); - olen += ctx->super.algo->tag_size; - } else { - psa_aead_abort(&ctx->mctx.op); /* required on errors */ - } - ctx->mctx.is_op_in_progress = 0; - } - - return (olen); -} - -void ptls_mbedtls_aead_do_encrypt_v(struct st_ptls_aead_context_t *_ctx, void *output, ptls_iovec_t *input, size_t incnt, - uint64_t seq, const void *aad, size_t aadlen) -{ - unsigned char *p = (uint8_t *)output; - - ptls_mbedtls_aead_do_encrypt_init(_ctx, seq, aad, aadlen); + ptls_aead__build_iv(ctx->super.algo, iv, ctx->static_iv, seq); - for (size_t i = 0; i < incnt; i++) { - p += ptls_mbedtls_aead_do_encrypt_update(_ctx, p, input[i].base, input[i].len); + switch (psa_aead_decrypt(ctx->key, ctx->alg, iv, ctx->super.algo->iv_size, aad, aadlen, input, inlen, output, inlen, &outlen)) { + case PSA_SUCCESS: + break; + case PSA_ERROR_INVALID_SIGNATURE: + outlen = SIZE_MAX; + break; + default: + abort(); + break; } - (void)ptls_mbedtls_aead_do_encrypt_final(_ctx, p); -} - -void ptls_mbedtls_aead_do_encrypt(struct st_ptls_aead_context_t *_ctx, void *output, const void *input, size_t inlen, uint64_t seq, - const void *aad, size_t aadlen, ptls_aead_supplementary_encryption_t *supp) -{ - ptls_iovec_t in_v; - in_v.base = (uint8_t *)input; - in_v.len = inlen; - - ptls_mbedtls_aead_do_encrypt_v(_ctx, output, &in_v, 1, seq, aad, aadlen); -} - -size_t ptls_mbedtls_aead_do_decrypt(struct st_ptls_aead_context_t *_ctx, void *output, const void *input, size_t inlen, - uint64_t seq, const void *aad, size_t aadlen) -{ - size_t o_len = 0; - uint8_t iv[PTLS_MAX_IV_SIZE]; - struct ptls_mbedtls_aead_context_t *ctx = (struct ptls_mbedtls_aead_context_t *)_ctx; - psa_status_t status; - /* set the nonce. */ - ptls_aead__build_iv(ctx->super.algo, iv, ctx->mctx.static_iv, seq); - - status = psa_aead_decrypt(ctx->mctx.key, ctx->mctx.alg, iv, ctx->super.algo->iv_size, (uint8_t *)aad, aadlen, (uint8_t *)input, - inlen, (uint8_t *)output, inlen, &o_len); - if (status != PSA_SUCCESS) { - o_len = inlen + 1; - } - return o_len; + return outlen; } -static int ptls_mbedtls_aead_setup_crypto(ptls_aead_context_t *_ctx, int is_enc, const void *key_bytes, const void *iv, - psa_algorithm_t psa_alg, size_t key_bits, psa_key_type_t key_type) +static int aead_setup(ptls_aead_context_t *_ctx, int is_enc, const void *key_bytes, const void *iv, psa_algorithm_t psa_alg, + size_t key_bits, psa_key_type_t key_type) { - int ret = 0; struct ptls_mbedtls_aead_context_t *ctx = (struct ptls_mbedtls_aead_context_t *)_ctx; - /* set mbed specific context to NULL, just to be sure */ - memset(&ctx->mctx, 0, sizeof(struct ptls_mbedtls_aead_param_t)); - ctx->mctx.alg = psa_alg; - - /* Initialize the key attributes */ - if (ret == 0) { + { /* setup key */ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_set_key_usage_flags(&attributes, (is_enc) ? PSA_KEY_USAGE_ENCRYPT : PSA_KEY_USAGE_DECRYPT); - psa_set_key_algorithm(&attributes, ctx->mctx.alg); + psa_set_key_usage_flags(&attributes, is_enc ? PSA_KEY_USAGE_ENCRYPT : PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, psa_alg); psa_set_key_type(&attributes, key_type); psa_set_key_bits(&attributes, key_bits); - /* Import key */ - if (psa_import_key(&attributes, key_bytes, key_bits / 8, &ctx->mctx.key) != PSA_SUCCESS) { - ret = PTLS_ERROR_LIBRARY; - } - } - - if (ret == 0) { - /* Store the static IV */ - if (ctx->super.algo->iv_size > PTLS_MAX_IV_SIZE) { - ret = PTLS_ERROR_LIBRARY; - } else { - memcpy(ctx->mctx.static_iv, iv, ctx->super.algo->iv_size); - ctx->mctx.is_op_in_progress = 0; - } + if (psa_import_key(&attributes, key_bytes, key_bits / 8, &ctx->key) != PSA_SUCCESS) + return PTLS_ERROR_LIBRARY; } - /* set the pointers to the individual functions */ - if (ret == 0) { - if (is_enc) { - ctx->super.do_encrypt_init = ptls_mbedtls_aead_do_encrypt_init; - ctx->super.do_encrypt_update = ptls_mbedtls_aead_do_encrypt_update; - ctx->super.do_encrypt_final = ptls_mbedtls_aead_do_encrypt_final; - ctx->super.do_encrypt = ptls_mbedtls_aead_do_encrypt; - ctx->super.do_encrypt_v = ptls_mbedtls_aead_do_encrypt_v; - } else { - ctx->super.do_decrypt = ptls_mbedtls_aead_do_decrypt; - } - ctx->super.dispose_crypto = ptls_mbedtls_aead_dispose_crypto; - ctx->super.do_get_iv = ptls_mbedtls_aead_get_iv; - ctx->super.do_set_iv = ptls_mbedtls_aead_set_iv; + /* setup the rest */ + ctx->super.dispose_crypto = aead_dispose_crypto; + ctx->super.do_get_iv = aead_get_iv; + ctx->super.do_set_iv = aead_set_iv; + if (is_enc) { + ctx->super.do_encrypt = ptls_aead__do_encrypt; + ctx->super.do_encrypt_v = aead_encrypt_v; + } else { + ctx->super.do_decrypt = aead_decrypt; } + memcpy(ctx->static_iv, iv, ctx->super.algo->iv_size); + ctx->alg = psa_alg; - return ret; + return 0; } -static int ptls_mbedtls_aead_setup_aes128gcm(ptls_aead_context_t *_ctx, int is_enc, const void *key_bytes, const void *iv) +static int aead_setup_aes128gcm(ptls_aead_context_t *_ctx, int is_enc, const void *key_bytes, const void *iv) { - return ptls_mbedtls_aead_setup_crypto(_ctx, is_enc, key_bytes, iv, PSA_ALG_GCM, 128, PSA_KEY_TYPE_AES); + return aead_setup(_ctx, is_enc, key_bytes, iv, PSA_ALG_GCM, 128, PSA_KEY_TYPE_AES); } ptls_aead_algorithm_t ptls_mbedtls_aes128gcm = {"AES128-GCM", @@ -522,16 +416,16 @@ ptls_aead_algorithm_t ptls_mbedtls_aes128gcm = {"AES128-GCM", 0, 0, sizeof(struct ptls_mbedtls_aead_context_t), - ptls_mbedtls_aead_setup_aes128gcm}; + aead_setup_aes128gcm}; ptls_cipher_suite_t ptls_mbedtls_aes128gcmsha256 = {.id = PTLS_CIPHER_SUITE_AES_128_GCM_SHA256, .name = PTLS_CIPHER_SUITE_NAME_AES_128_GCM_SHA256, .aead = &ptls_mbedtls_aes128gcm, .hash = &ptls_mbedtls_sha256}; -static int ptls_mbedtls_aead_setup_aes256gcm(ptls_aead_context_t *_ctx, int is_enc, const void *key_bytes, const void *iv) +static int aead_setup_aes256gcm(ptls_aead_context_t *_ctx, int is_enc, const void *key_bytes, const void *iv) { - return ptls_mbedtls_aead_setup_crypto(_ctx, is_enc, key_bytes, iv, PSA_ALG_GCM, 256, PSA_KEY_TYPE_AES); + return aead_setup(_ctx, is_enc, key_bytes, iv, PSA_ALG_GCM, 256, PSA_KEY_TYPE_AES); } ptls_aead_algorithm_t ptls_mbedtls_aes256gcm = {"AES256-GCM", @@ -546,16 +440,16 @@ ptls_aead_algorithm_t ptls_mbedtls_aes256gcm = {"AES256-GCM", 0, 0, sizeof(struct ptls_mbedtls_aead_context_t), - ptls_mbedtls_aead_setup_aes256gcm}; + aead_setup_aes256gcm}; ptls_cipher_suite_t ptls_mbedtls_aes256gcmsha384 = {.id = PTLS_CIPHER_SUITE_AES_256_GCM_SHA384, .name = PTLS_CIPHER_SUITE_NAME_AES_256_GCM_SHA384, .aead = &ptls_mbedtls_aes256gcm, .hash = &ptls_mbedtls_sha384}; -static int ptls_mbedtls_aead_setup_chacha20poly1305(ptls_aead_context_t *_ctx, int is_enc, const void *key_bytes, const void *iv) +static int aead_setup_chacha20poly1305(ptls_aead_context_t *_ctx, int is_enc, const void *key_bytes, const void *iv) { - return ptls_mbedtls_aead_setup_crypto(_ctx, is_enc, key_bytes, iv, PSA_ALG_CHACHA20_POLY1305, 256, PSA_KEY_TYPE_CHACHA20); + return aead_setup(_ctx, is_enc, key_bytes, iv, PSA_ALG_CHACHA20_POLY1305, 256, PSA_KEY_TYPE_CHACHA20); } ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305 = {"CHACHA20-POLY1305", @@ -570,7 +464,7 @@ ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305 = {"CHACHA20-POLY1305", 0, 0, sizeof(struct ptls_mbedtls_aead_context_t), - ptls_mbedtls_aead_setup_chacha20poly1305}; + aead_setup_chacha20poly1305}; ptls_cipher_suite_t ptls_mbedtls_chacha20poly1305sha256 = {.id = PTLS_CIPHER_SUITE_CHACHA20_POLY1305_SHA256, .name = PTLS_CIPHER_SUITE_NAME_CHACHA20_POLY1305_SHA256, From 7550f87de350b8a82f288e8768ee23103cf3dc86 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Tue, 14 Nov 2023 11:16:29 +0900 Subject: [PATCH 67/84] update test code to not rely on init-update-final cycle that is now optional (see doc-comment of ptls_aead_context_t) --- t/picotls.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/t/picotls.c b/t/picotls.c index ecca51d3c..b61dfce16 100644 --- a/t/picotls.c +++ b/t/picotls.c @@ -225,12 +225,8 @@ static void test_ciphersuite(ptls_cipher_suite_t *cs1, ptls_cipher_suite_t *cs2) /* encrypt */ c = ptls_aead_new(cs1->aead, cs1->hash, 1, traffic_secret, NULL); assert(c != NULL); - ptls_aead_encrypt_init(c, 0, NULL, 0); - enc1len = ptls_aead_encrypt_update(c, enc1, src1, strlen(src1)); - enc1len += ptls_aead_encrypt_final(c, enc1 + enc1len); - ptls_aead_encrypt_init(c, 1, NULL, 0); - enc2len = ptls_aead_encrypt_update(c, enc2, src2, strlen(src2)); - enc2len += ptls_aead_encrypt_final(c, enc2 + enc2len); + enc1len = ptls_aead_encrypt(c, enc1, src1, strlen(src1), 0, NULL, 0); + enc2len = ptls_aead_encrypt(c, enc2, src2, strlen(src2), 1, NULL, 0); ptls_aead_free(c); c = ptls_aead_new(cs2->aead, cs2->hash, 0, traffic_secret, NULL); @@ -275,6 +271,10 @@ static void test_ciphersuite_stream(ptls_cipher_suite_t *cs1, ptls_cipher_suite_ /* encrypt */ c = ptls_aead_new(cs1->aead, cs1->hash, 1, traffic_secret, NULL); assert(c != NULL); + if (c->do_encrypt_init == NULL) { + note("new ciphers may omit support for init-update-final"); + return; + } ptls_aead_encrypt_init(c, 0, NULL, 0); enclen = 0; for (size_t i = 0; text[i] != NULL; ++i) @@ -311,9 +311,7 @@ static void test_aad_ciphersuite(ptls_cipher_suite_t *cs1, ptls_cipher_suite_t * /* encrypt */ c = ptls_aead_new(cs1->aead, cs1->hash, 1, traffic_secret, NULL); assert(c != NULL); - ptls_aead_encrypt_init(c, 123, aad, strlen(aad)); - enclen = ptls_aead_encrypt_update(c, enc, src, strlen(src)); - enclen += ptls_aead_encrypt_final(c, enc + enclen); + enclen = ptls_aead_encrypt(c, enc, src, strlen(src), 123, aad, strlen(aad)); ptls_aead_free(c); /* decrypt */ @@ -340,9 +338,7 @@ static void test_aad96_ciphersuite(ptls_cipher_suite_t *cs1, ptls_cipher_suite_t c = ptls_aead_new(cs1->aead, cs1->hash, 1, traffic_secret, NULL); assert(c != NULL); ptls_aead_xor_iv(c, seq32, sizeof(seq32)); - ptls_aead_encrypt_init(c, 123, aad, strlen(aad)); - enclen = ptls_aead_encrypt_update(c, enc, src, strlen(src)); - enclen += ptls_aead_encrypt_final(c, enc + enclen); + enclen = ptls_aead_encrypt(c, enc, src, strlen(src), 123, aad, strlen(aad)); ptls_aead_free(c); /* decrypt */ From fc2bae6018990116caa1f167f7461165ff7e728e Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Tue, 14 Nov 2023 11:26:20 +0900 Subject: [PATCH 68/84] fail the same way --- lib/mbedtls.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/lib/mbedtls.c b/lib/mbedtls.c index d610b7abc..cf5ca055b 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -32,13 +32,17 @@ #include #include "picotls.h" +#define PSA_FUNC_FAILED(fn, ret) \ + do { \ + fprintf(stderr, "in %s at line %d, " PTLS_TO_STR(fn) " failed (%d)\n", __FUNCTION__, __LINE__, (int)ret); \ + abort(); \ + } while (0) + #define CALL_WITH_CHECK(fn, ...) \ do { \ psa_status_t ret; \ - if ((ret = fn(__VA_ARGS__)) != PSA_SUCCESS) { \ - fprintf(stderr, "in %s at line %d, " PTLS_TO_STR(fn) " failed (%d)\n", __FUNCTION__, __LINE__, (int)ret); \ - abort(); \ - } \ + if ((ret = fn(__VA_ARGS__)) != PSA_SUCCESS) \ + PSA_FUNC_FAILED(fn, ret); \ } while (0) void ptls_mbedtls_random_bytes(void *buf, size_t len) @@ -247,17 +251,18 @@ static void chacha20_init(ptls_cipher_context_t *_ctx, const void *v_iv) const uint8_t *iv = (const uint8_t *)v_iv; uint32_t ctr = iv[0] | ((uint32_t)iv[1] << 8) | ((uint32_t)iv[2] << 16) | ((uint32_t)iv[3] << 24); - (void)mbedtls_chacha20_starts(&ctx->mctx, (const uint8_t *)(iv + 4), ctr); + int ret = mbedtls_chacha20_starts(&ctx->mctx, (const uint8_t *)(iv + 4), ctr); + if (ret != 0) + PSA_FUNC_FAILED(mbedtls_chacha20_starts, ret); } static void chacha20_transform(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t len) { struct st_ptls_mbedtls_chacha20_context_t *ctx = (struct st_ptls_mbedtls_chacha20_context_t *)_ctx; - if (mbedtls_chacha20_update(&ctx->mctx, len, (const uint8_t *)input, (uint8_t *)output) != 0) { - fprintf(stderr, "mbedtls_chacha20_update failed\n"); - abort(); - } + int ret = mbedtls_chacha20_update(&ctx->mctx, len, (const uint8_t *)input, (uint8_t *)output); + if (ret != 0) + PSA_FUNC_FAILED(mbedtls_chacha20_update, ret); } static void chacha20_dispose(ptls_cipher_context_t *_ctx) @@ -354,14 +359,16 @@ size_t aead_decrypt(struct st_ptls_aead_context_t *_ctx, void *output, const voi ptls_aead__build_iv(ctx->super.algo, iv, ctx->static_iv, seq); - switch (psa_aead_decrypt(ctx->key, ctx->alg, iv, ctx->super.algo->iv_size, aad, aadlen, input, inlen, output, inlen, &outlen)) { + psa_status_t ret = + psa_aead_decrypt(ctx->key, ctx->alg, iv, ctx->super.algo->iv_size, aad, aadlen, input, inlen, output, inlen, &outlen); + switch (ret) { case PSA_SUCCESS: break; case PSA_ERROR_INVALID_SIGNATURE: outlen = SIZE_MAX; break; default: - abort(); + PSA_FUNC_FAILED(psa_aead_decrypt, ret); break; } From 0635d6e2ef08304cbde7a8978fc2d9b8ab984b0d Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Tue, 14 Nov 2023 11:51:36 +0900 Subject: [PATCH 69/84] expand doc-comment in picotls.h instead --- include/picotls.h | 13 +++++++++---- lib/mbedtls.c | 22 ---------------------- 2 files changed, 9 insertions(+), 26 deletions(-) diff --git a/include/picotls.h b/include/picotls.h index 49271f77a..3b7a96dec 100644 --- a/include/picotls.h +++ b/include/picotls.h @@ -338,11 +338,14 @@ typedef struct st_ptls_key_exchange_context_t { */ const struct st_ptls_key_exchange_algorithm_t *algo; /** - * the public key + * public key of this context */ ptls_iovec_t pubkey; /** - * If `release` is set, the callee frees resources allocated to the context and set *keyex to NULL + * This function can be used for deriving a shared secret or for destroying the context. + * When `secret` is non-NULL, this callback derives the shared secret using the public key of the context and the peer key being + * given, and sets the value in `secret`. The memory pointed to by `secret->base` must be freed by the caller by calling `free`. + * When `release` is set, the callee frees resources allocated to the context and set *keyex to NULL. */ int (*on_exchange)(struct st_ptls_key_exchange_context_t **keyex, int release, ptls_iovec_t *secret, ptls_iovec_t peerkey); } ptls_key_exchange_context_t; @@ -356,12 +359,14 @@ typedef const struct st_ptls_key_exchange_algorithm_t { */ uint16_t id; /** - * creates a context for asynchronous key exchange. The function is called when ClientHello is generated. The on_exchange + * Creates a context for asynchronous key exchange. The function is called when ClientHello is generated. The on_exchange * callback of the created context is called when the client receives ServerHello. */ int (*create)(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **ctx); /** - * implements synchronous key exchange. Called when receiving a ServerHello. + * Implements synchronous key exchange. Called when receiving a ServerHello. + * Given a public key provided by the peer (`peerkey`), this callback returns a empheral public key (`pubkey`) and a secret + * (`secret) `derived from the two public keys. */ int (*exchange)(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_iovec_t *pubkey, ptls_iovec_t *secret, ptls_iovec_t peerkey); diff --git a/lib/mbedtls.c b/lib/mbedtls.c index cf5ca055b..ffe4d96ab 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -481,28 +481,6 @@ ptls_cipher_suite_t ptls_mbedtls_chacha20poly1305sha256 = {.id = PTLS_CIPHER_SUI ptls_cipher_suite_t *ptls_mbedtls_cipher_suites[] = {&ptls_mbedtls_aes256gcmsha384, &ptls_mbedtls_aes128gcmsha256, &ptls_mbedtls_chacha20poly1305sha256, NULL}; -/* Key exchange algorithms. - * The Picotls framework defines these algorithms as ptls_key_exchange_algorithm_t, - * a structure containing two function pointers: - * - * int (*create)(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **ctx); - * int (*exchange)(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_iovec_t *pubkey, ptls_iovec_t *secret, - * ptls_iovec_t peerkey); - * The "create" call is used on the client. It documents the ptls_key_exchange_context_t, which contains - * the public key prepared by the client, as an iovec, and a function pointer: - * - * int (*on_exchange)(struct st_ptls_key_exchange_context_t **keyex, int release, ptls_iovec_t *secret, ptls_iovec_t peerkey); - * - * The public key of the client is passed to the server an ends up as "peerkey" argument to the (exchange) function. - * That function documents the server's public key, and the secret computed by combining server and client key. - * - * When the client receives the server hello, the stack calls the "on_exchange" callback, passing the context - * previously created by the client and the public key of the peer, so the client can compute its own - * version of the secret. - * - * The following code uses the MbedTLS PSA API to create the "create", "exchange" and "on_exchange" functions. - */ - #define PTLS_MBEDTLS_ECDH_PUBKEY_MAX 129 struct ptls_mbedtls_key_exchange_context_t { From bf9e1d735df6321089ab3e368d45684a237ece85 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Tue, 14 Nov 2023 12:22:04 +0900 Subject: [PATCH 70/84] reduce state, release memory regardless of errors --- lib/mbedtls.c | 187 ++++++++++++++++++++++++-------------------------- 1 file changed, 88 insertions(+), 99 deletions(-) diff --git a/lib/mbedtls.c b/lib/mbedtls.c index ffe4d96ab..6a5a59fe7 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -486,18 +486,15 @@ ptls_cipher_suite_t *ptls_mbedtls_cipher_suites[] = {&ptls_mbedtls_aes256gcmsha3 struct ptls_mbedtls_key_exchange_context_t { ptls_key_exchange_context_t super; psa_algorithm_t psa_alg; - psa_ecc_family_t curve; - size_t curve_bits; size_t secret_size; psa_key_id_t private_key; - uint8_t pub[PTLS_MBEDTLS_ECDH_PUBKEY_MAX]; + uint8_t pubkeybuf[PTLS_MBEDTLS_ECDH_PUBKEY_MAX]; }; -/* Set a private key for key exchange. For now, we only support ECC +/** + * Generates a private key. For now, we only support ECC. */ - -static int ptls_mbedtls_key_exchange_set_private_key(psa_key_id_t *private_key, psa_algorithm_t psa_alg, psa_ecc_family_t curve, - size_t curve_bits) +static int generate_private_key(psa_key_id_t *private_key, psa_algorithm_t psa_alg, psa_ecc_family_t curve, size_t curve_bits) { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; int ret = 0; @@ -512,123 +509,115 @@ static int ptls_mbedtls_key_exchange_set_private_key(psa_key_id_t *private_key, return ret; } -/* -* The key agreement is done by calling psa_raw_key_agreement -psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, -psa_key_id_t private_key, -const uint8_t * peer_key, -size_t peer_key_length, -uint8_t * output, -size_t output_size, -size_t * output_length); -*/ - -int ptls_mbedtls_key_exchange_on_exchange(struct st_ptls_key_exchange_context_t **_pctx, int release, ptls_iovec_t *secret, - ptls_iovec_t peerkey) +int key_exchange_on_exchange(struct st_ptls_key_exchange_context_t **_keyex, int release, ptls_iovec_t *secret, + ptls_iovec_t peerkey) { + struct ptls_mbedtls_key_exchange_context_t *keyex = (struct ptls_mbedtls_key_exchange_context_t *)*_keyex; int ret = 0; - struct ptls_mbedtls_key_exchange_context_t *keyex = (struct ptls_mbedtls_key_exchange_context_t *)*_pctx; - - if (secret != NULL) { - uint8_t *secbytes = (uint8_t *)malloc(keyex->secret_size); - - if (secbytes == NULL) { - ret = PTLS_ERROR_NO_MEMORY; - } else { - size_t olen; - if (psa_raw_key_agreement(keyex->psa_alg, keyex->private_key, (const uint8_t *)peerkey.base, peerkey.len, secbytes, - keyex->secret_size, &olen) == 0) { - *secret = ptls_iovec_init(secbytes, keyex->secret_size); - } else { - free(secbytes); - ret = PTLS_ERROR_LIBRARY; - } - } + + if (secret == NULL) + goto Exit; + + /* derive shared secret */ + if ((secret->base = malloc(keyex->secret_size)) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + if (psa_raw_key_agreement(keyex->psa_alg, keyex->private_key, peerkey.base, peerkey.len, secret->base, keyex->secret_size, + &secret->len) != 0) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; + } + assert(keyex->secret_size == secret->len); + ret = 0; + +Exit: + if (ret != 0 && secret != NULL) { + free(secret->base); + *secret = ptls_iovec_init(NULL, 0); } if (release) { - /* Clear the private key */ psa_destroy_key(keyex->private_key); - /* Set context to NULL */ - *_pctx = NULL; - /* TODO: check whether allocated memory should be freed */ + free(keyex); + *_keyex = NULL; } - return ret; } -int ptls_mbedtls_key_exchange_create(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **ctx, - psa_algorithm_t psa_alg, psa_ecc_family_t curve, size_t curve_bits, size_t secret_size) +static int key_exchange_create(ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **ctx, psa_algorithm_t psa_alg, + psa_ecc_family_t curve, size_t curve_bits, size_t secret_size) { struct ptls_mbedtls_key_exchange_context_t *keyex; - size_t olen = 0; - if ((keyex = (struct ptls_mbedtls_key_exchange_context_t *)malloc(sizeof(struct ptls_mbedtls_key_exchange_context_t))) == NULL) + *ctx = NULL; + + /* setup context */ + if ((keyex = malloc(sizeof(*keyex))) == NULL) return PTLS_ERROR_NO_MEMORY; - /* Initialize the exchange context based on the algorithm definition */ - keyex->psa_alg = psa_alg; - keyex->curve = curve; - keyex->curve_bits = curve_bits; - keyex->secret_size = secret_size; - /* Initialize the private key and format the public key */ - if (ptls_mbedtls_key_exchange_set_private_key(&keyex->private_key, psa_alg, curve, curve_bits) != 0) { + *keyex = (struct ptls_mbedtls_key_exchange_context_t){ + .super.algo = algo, + .super.pubkey.base = keyex->pubkeybuf, + .super.on_exchange = key_exchange_on_exchange, + .psa_alg = psa_alg, + .secret_size = secret_size, + }; + + /* generate private key */ + if (generate_private_key(&keyex->private_key, psa_alg, curve, curve_bits) != 0) { free(keyex); - *ctx = NULL; return PTLS_ERROR_LIBRARY; } - /* According to the doc, format of public key is same as picotls */ - if (psa_export_public_key(keyex->private_key, keyex->pub, sizeof(keyex->pub), &olen) != 0) { - psa_destroy_key(keyex->private_key); - free(keyex); - *ctx = NULL; - return PTLS_ERROR_LIBRARY; + { /* export public key */ + psa_status_t ret = + psa_export_public_key(keyex->private_key, keyex->pubkeybuf, sizeof(keyex->pubkeybuf), &keyex->super.pubkey.len); + if (ret != 0) + PSA_FUNC_FAILED(psa_export_public_key, ret); } - keyex->super.pubkey = ptls_iovec_init(keyex->pub, olen); - /* Initialize the ptls exchange context */ - keyex->super.algo = algo; - keyex->super.on_exchange = ptls_mbedtls_key_exchange_on_exchange; - *ctx = (ptls_key_exchange_context_t *)keyex; + + *ctx = &keyex->super; return 0; } -static int ptls_mbedtls_key_exchange_exchange(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_iovec_t *pubkey, - ptls_iovec_t *secret, ptls_iovec_t peerkey, psa_algorithm_t psa_alg, - psa_ecc_family_t curve, size_t curve_bits, size_t secret_size) +static int key_exchange_exchange(ptls_key_exchange_algorithm_t *algo, ptls_iovec_t *pubkey, ptls_iovec_t *secret, + ptls_iovec_t peerkey, psa_algorithm_t psa_alg, psa_ecc_family_t curve, size_t curve_bits, + size_t secret_size) { - /* generate a local private key for the selected algorithm */ psa_key_id_t private_key; - size_t pubkey_len; - uint8_t *pubkey_bytes = NULL; - size_t secret_len; - uint8_t *secret_bytes = (uint8_t *)malloc(secret_size); - int ret = 0; + int ret; - if (secret_bytes == NULL) { - return PTLS_ERROR_NO_MEMORY; - } - pubkey_bytes = (uint8_t *)malloc(PTLS_MBEDTLS_ECDH_PUBKEY_MAX); - if (pubkey_bytes == NULL) { - free(secret_bytes); - return PTLS_ERROR_NO_MEMORY; - } + *pubkey = ptls_iovec_init(NULL, 0); + *secret = ptls_iovec_init(NULL, 0); - if (ptls_mbedtls_key_exchange_set_private_key(&private_key, psa_alg, curve, curve_bits) != 0) { - free(secret_bytes); - free(pubkey_bytes); + /* generate private key (and return immediately upon failure) */ + if (generate_private_key(&private_key, psa_alg, curve, curve_bits) != 0) return PTLS_ERROR_LIBRARY; + + /* allocate buffers */ + if ((secret->base = malloc(secret_size)) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; + } + if ((pubkey->base = malloc(PTLS_MBEDTLS_ECDH_PUBKEY_MAX)) == NULL) { + ret = PTLS_ERROR_NO_MEMORY; + goto Exit; } - /* Export public key and call key agrement function */ - if (psa_export_public_key(private_key, pubkey_bytes, PTLS_MBEDTLS_ECDH_PUBKEY_MAX, &pubkey_len) == 0 && - psa_raw_key_agreement(psa_alg, private_key, (const uint8_t *)peerkey.base, peerkey.len, secret_bytes, secret_size, - &secret_len) == 0) { - *secret = ptls_iovec_init(secret_bytes, secret_len); - *pubkey = ptls_iovec_init(pubkey_bytes, pubkey_len); - } else { - free(secret_bytes); - free(pubkey_bytes); - return PTLS_ERROR_LIBRARY; + /* export public key and call key agrement function */ + if (psa_export_public_key(private_key, pubkey->base, PTLS_MBEDTLS_ECDH_PUBKEY_MAX, &pubkey->len) != 0 || + psa_raw_key_agreement(psa_alg, private_key, peerkey.base, peerkey.len, secret->base, secret_size, &secret->len) != 0) { + ret = PTLS_ERROR_LIBRARY; + goto Exit; } + ret = 0; + +Exit: + if (ret != 0) { + free(pubkey->base); + *pubkey = ptls_iovec_init(NULL, 0); + free(secret->base); + *secret = ptls_iovec_init(NULL, 0); + } psa_destroy_key(private_key); return ret; @@ -638,13 +627,13 @@ static int ptls_mbedtls_key_exchange_exchange(const struct st_ptls_key_exchange_ */ static int ptls_mbedtls_secp256r1_create(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **ctx) { - return ptls_mbedtls_key_exchange_create(algo, ctx, PSA_ALG_ECDH, PSA_ECC_FAMILY_SECP_R1, 256, 32); + return key_exchange_create(algo, ctx, PSA_ALG_ECDH, PSA_ECC_FAMILY_SECP_R1, 256, 32); } static int ptls_mbedtls_secp256r1_exchange(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_iovec_t *pubkey, ptls_iovec_t *secret, ptls_iovec_t peerkey) { - return ptls_mbedtls_key_exchange_exchange(algo, pubkey, secret, peerkey, PSA_ALG_ECDH, PSA_ECC_FAMILY_SECP_R1, 256, 32); + return key_exchange_exchange(algo, pubkey, secret, peerkey, PSA_ALG_ECDH, PSA_ECC_FAMILY_SECP_R1, 256, 32); } ptls_key_exchange_algorithm_t ptls_mbedtls_secp256r1 = {.id = PTLS_GROUP_SECP256R1, @@ -656,13 +645,13 @@ ptls_key_exchange_algorithm_t ptls_mbedtls_secp256r1 = {.id = PTLS_GROUP_SECP256 */ static int ptls_mbedtls_x25519_create(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **ctx) { - return ptls_mbedtls_key_exchange_create(algo, ctx, PSA_ALG_ECDH, PSA_ECC_FAMILY_MONTGOMERY, 255, 32); + return key_exchange_create(algo, ctx, PSA_ALG_ECDH, PSA_ECC_FAMILY_MONTGOMERY, 255, 32); } static int ptls_mbedtls_x25519_exchange(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_iovec_t *pubkey, ptls_iovec_t *secret, ptls_iovec_t peerkey) { - return ptls_mbedtls_key_exchange_exchange(algo, pubkey, secret, peerkey, PSA_ALG_ECDH, PSA_ECC_FAMILY_MONTGOMERY, 255, 32); + return key_exchange_exchange(algo, pubkey, secret, peerkey, PSA_ALG_ECDH, PSA_ECC_FAMILY_MONTGOMERY, 255, 32); } ptls_key_exchange_algorithm_t ptls_mbedtls_x25519 = {.id = PTLS_GROUP_X25519, From 60f4749cb8b4473439e23433cd6156ee9d547ff7 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Tue, 14 Nov 2023 14:56:38 +0900 Subject: [PATCH 71/84] add missing `static` --- lib/mbedtls.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/mbedtls.c b/lib/mbedtls.c index 6a5a59fe7..4e74c4fe6 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -350,8 +350,8 @@ static void aead_encrypt_v(struct st_ptls_aead_context_t *_ctx, void *output, pt psa_aead_abort(&op); } -size_t aead_decrypt(struct st_ptls_aead_context_t *_ctx, void *output, const void *input, size_t inlen, uint64_t seq, - const void *aad, size_t aadlen) +static size_t aead_decrypt(struct st_ptls_aead_context_t *_ctx, void *output, const void *input, size_t inlen, uint64_t seq, + const void *aad, size_t aadlen) { struct ptls_mbedtls_aead_context_t *ctx = (struct ptls_mbedtls_aead_context_t *)_ctx; uint8_t iv[PTLS_MAX_IV_SIZE]; @@ -509,8 +509,8 @@ static int generate_private_key(psa_key_id_t *private_key, psa_algorithm_t psa_a return ret; } -int key_exchange_on_exchange(struct st_ptls_key_exchange_context_t **_keyex, int release, ptls_iovec_t *secret, - ptls_iovec_t peerkey) +static int key_exchange_on_exchange(struct st_ptls_key_exchange_context_t **_keyex, int release, ptls_iovec_t *secret, + ptls_iovec_t peerkey) { struct ptls_mbedtls_key_exchange_context_t *keyex = (struct ptls_mbedtls_key_exchange_context_t *)*_keyex; int ret = 0; From 8a694b6fb64f896b7f8ee24c0c3682eb06ae51b6 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Tue, 14 Nov 2023 14:57:34 +0900 Subject: [PATCH 72/84] no need to have prefix for static functions --- lib/mbedtls.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/lib/mbedtls.c b/lib/mbedtls.c index 4e74c4fe6..610e9fa94 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -625,38 +625,34 @@ static int key_exchange_exchange(ptls_key_exchange_algorithm_t *algo, ptls_iovec /* Instantiation of the generic key exchange API with secp256r1 */ -static int ptls_mbedtls_secp256r1_create(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **ctx) +static int secp256r1_create(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **ctx) { return key_exchange_create(algo, ctx, PSA_ALG_ECDH, PSA_ECC_FAMILY_SECP_R1, 256, 32); } -static int ptls_mbedtls_secp256r1_exchange(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_iovec_t *pubkey, - ptls_iovec_t *secret, ptls_iovec_t peerkey) +static int secp256r1_exchange(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_iovec_t *pubkey, ptls_iovec_t *secret, + ptls_iovec_t peerkey) { return key_exchange_exchange(algo, pubkey, secret, peerkey, PSA_ALG_ECDH, PSA_ECC_FAMILY_SECP_R1, 256, 32); } -ptls_key_exchange_algorithm_t ptls_mbedtls_secp256r1 = {.id = PTLS_GROUP_SECP256R1, - .name = PTLS_GROUP_NAME_SECP256R1, - .create = ptls_mbedtls_secp256r1_create, - .exchange = ptls_mbedtls_secp256r1_exchange}; +ptls_key_exchange_algorithm_t ptls_mbedtls_secp256r1 = { + .id = PTLS_GROUP_SECP256R1, .name = PTLS_GROUP_NAME_SECP256R1, .create = secp256r1_create, .exchange = secp256r1_exchange}; /* Instantiation of the generic key exchange API with x25519 */ -static int ptls_mbedtls_x25519_create(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **ctx) +static int x25519_create(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **ctx) { return key_exchange_create(algo, ctx, PSA_ALG_ECDH, PSA_ECC_FAMILY_MONTGOMERY, 255, 32); } -static int ptls_mbedtls_x25519_exchange(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_iovec_t *pubkey, - ptls_iovec_t *secret, ptls_iovec_t peerkey) +static int x25519_exchange(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_iovec_t *pubkey, ptls_iovec_t *secret, + ptls_iovec_t peerkey) { return key_exchange_exchange(algo, pubkey, secret, peerkey, PSA_ALG_ECDH, PSA_ECC_FAMILY_MONTGOMERY, 255, 32); } -ptls_key_exchange_algorithm_t ptls_mbedtls_x25519 = {.id = PTLS_GROUP_X25519, - .name = PTLS_GROUP_NAME_X25519, - .create = ptls_mbedtls_x25519_create, - .exchange = ptls_mbedtls_x25519_exchange}; +ptls_key_exchange_algorithm_t ptls_mbedtls_x25519 = { + .id = PTLS_GROUP_X25519, .name = PTLS_GROUP_NAME_X25519, .create = x25519_create, .exchange = x25519_exchange}; ptls_key_exchange_algorithm_t *ptls_mbedtls_key_exchanges[] = {&ptls_mbedtls_secp256r1, NULL}; From 25e0ab8bde0dd54136b2f0ae8b2e22f9bb418164 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Tue, 14 Nov 2023 15:08:48 +0900 Subject: [PATCH 73/84] consolidate duplicated constants into `const struct` --- lib/mbedtls.c | 54 ++++++++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/lib/mbedtls.c b/lib/mbedtls.c index 610e9fa94..256dfca53 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -483,10 +483,17 @@ ptls_cipher_suite_t *ptls_mbedtls_cipher_suites[] = {&ptls_mbedtls_aes256gcmsha3 #define PTLS_MBEDTLS_ECDH_PUBKEY_MAX 129 +static const struct ptls_mbedtls_key_exchange_params_t { + psa_algorithm_t alg; + psa_ecc_family_t curve; + size_t curve_bits; + size_t secret_size; +} secp256r1_params = {PSA_ALG_ECDH, PSA_ECC_FAMILY_SECP_R1, 256, 32}, + x25519_params = {PSA_ALG_ECDH, PSA_ECC_FAMILY_MONTGOMERY, 255, 32}; + struct ptls_mbedtls_key_exchange_context_t { ptls_key_exchange_context_t super; - psa_algorithm_t psa_alg; - size_t secret_size; + const struct ptls_mbedtls_key_exchange_params_t *params; psa_key_id_t private_key; uint8_t pubkeybuf[PTLS_MBEDTLS_ECDH_PUBKEY_MAX]; }; @@ -494,15 +501,15 @@ struct ptls_mbedtls_key_exchange_context_t { /** * Generates a private key. For now, we only support ECC. */ -static int generate_private_key(psa_key_id_t *private_key, psa_algorithm_t psa_alg, psa_ecc_family_t curve, size_t curve_bits) +static int generate_private_key(psa_key_id_t *private_key, const struct ptls_mbedtls_key_exchange_params_t *params) { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; int ret = 0; psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE); - psa_set_key_algorithm(&attributes, psa_alg); - psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve)); - psa_set_key_bits(&attributes, curve_bits); + psa_set_key_algorithm(&attributes, params->alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(params->curve)); + psa_set_key_bits(&attributes, params->curve_bits); if (psa_generate_key(&attributes, private_key) != 0) { ret = -1; } @@ -519,16 +526,16 @@ static int key_exchange_on_exchange(struct st_ptls_key_exchange_context_t **_key goto Exit; /* derive shared secret */ - if ((secret->base = malloc(keyex->secret_size)) == NULL) { + if ((secret->base = malloc(keyex->params->secret_size)) == NULL) { ret = PTLS_ERROR_NO_MEMORY; goto Exit; } - if (psa_raw_key_agreement(keyex->psa_alg, keyex->private_key, peerkey.base, peerkey.len, secret->base, keyex->secret_size, - &secret->len) != 0) { + if (psa_raw_key_agreement(keyex->params->alg, keyex->private_key, peerkey.base, peerkey.len, secret->base, + keyex->params->secret_size, &secret->len) != 0) { ret = PTLS_ERROR_LIBRARY; goto Exit; } - assert(keyex->secret_size == secret->len); + assert(keyex->params->secret_size == secret->len); ret = 0; Exit: @@ -544,8 +551,8 @@ static int key_exchange_on_exchange(struct st_ptls_key_exchange_context_t **_key return ret; } -static int key_exchange_create(ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **ctx, psa_algorithm_t psa_alg, - psa_ecc_family_t curve, size_t curve_bits, size_t secret_size) +static int key_exchange_create(ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **ctx, + const struct ptls_mbedtls_key_exchange_params_t *params) { struct ptls_mbedtls_key_exchange_context_t *keyex; @@ -558,12 +565,11 @@ static int key_exchange_create(ptls_key_exchange_algorithm_t *algo, ptls_key_exc .super.algo = algo, .super.pubkey.base = keyex->pubkeybuf, .super.on_exchange = key_exchange_on_exchange, - .psa_alg = psa_alg, - .secret_size = secret_size, + .params = params, }; /* generate private key */ - if (generate_private_key(&keyex->private_key, psa_alg, curve, curve_bits) != 0) { + if (generate_private_key(&keyex->private_key, keyex->params) != 0) { free(keyex); return PTLS_ERROR_LIBRARY; } @@ -579,8 +585,7 @@ static int key_exchange_create(ptls_key_exchange_algorithm_t *algo, ptls_key_exc } static int key_exchange_exchange(ptls_key_exchange_algorithm_t *algo, ptls_iovec_t *pubkey, ptls_iovec_t *secret, - ptls_iovec_t peerkey, psa_algorithm_t psa_alg, psa_ecc_family_t curve, size_t curve_bits, - size_t secret_size) + ptls_iovec_t peerkey, const struct ptls_mbedtls_key_exchange_params_t *params) { psa_key_id_t private_key; int ret; @@ -589,11 +594,11 @@ static int key_exchange_exchange(ptls_key_exchange_algorithm_t *algo, ptls_iovec *secret = ptls_iovec_init(NULL, 0); /* generate private key (and return immediately upon failure) */ - if (generate_private_key(&private_key, psa_alg, curve, curve_bits) != 0) + if (generate_private_key(&private_key, params) != 0) return PTLS_ERROR_LIBRARY; /* allocate buffers */ - if ((secret->base = malloc(secret_size)) == NULL) { + if ((secret->base = malloc(params->secret_size)) == NULL) { ret = PTLS_ERROR_NO_MEMORY; goto Exit; } @@ -604,7 +609,8 @@ static int key_exchange_exchange(ptls_key_exchange_algorithm_t *algo, ptls_iovec /* export public key and call key agrement function */ if (psa_export_public_key(private_key, pubkey->base, PTLS_MBEDTLS_ECDH_PUBKEY_MAX, &pubkey->len) != 0 || - psa_raw_key_agreement(psa_alg, private_key, peerkey.base, peerkey.len, secret->base, secret_size, &secret->len) != 0) { + psa_raw_key_agreement(params->alg, private_key, peerkey.base, peerkey.len, secret->base, params->secret_size, + &secret->len) != 0) { ret = PTLS_ERROR_LIBRARY; goto Exit; } @@ -627,13 +633,13 @@ static int key_exchange_exchange(ptls_key_exchange_algorithm_t *algo, ptls_iovec */ static int secp256r1_create(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **ctx) { - return key_exchange_create(algo, ctx, PSA_ALG_ECDH, PSA_ECC_FAMILY_SECP_R1, 256, 32); + return key_exchange_create(algo, ctx, &secp256r1_params); } static int secp256r1_exchange(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_iovec_t *pubkey, ptls_iovec_t *secret, ptls_iovec_t peerkey) { - return key_exchange_exchange(algo, pubkey, secret, peerkey, PSA_ALG_ECDH, PSA_ECC_FAMILY_SECP_R1, 256, 32); + return key_exchange_exchange(algo, pubkey, secret, peerkey, &secp256r1_params); } ptls_key_exchange_algorithm_t ptls_mbedtls_secp256r1 = { @@ -643,13 +649,13 @@ ptls_key_exchange_algorithm_t ptls_mbedtls_secp256r1 = { */ static int x25519_create(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **ctx) { - return key_exchange_create(algo, ctx, PSA_ALG_ECDH, PSA_ECC_FAMILY_MONTGOMERY, 255, 32); + return key_exchange_create(algo, ctx, &x25519_params); } static int x25519_exchange(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_iovec_t *pubkey, ptls_iovec_t *secret, ptls_iovec_t peerkey) { - return key_exchange_exchange(algo, pubkey, secret, peerkey, PSA_ALG_ECDH, PSA_ECC_FAMILY_MONTGOMERY, 255, 32); + return key_exchange_exchange(algo, pubkey, secret, peerkey, &x25519_params); } ptls_key_exchange_algorithm_t ptls_mbedtls_x25519 = { From 0069e3c2fdf6855c57532d48ee16ed18b1b6936f Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Tue, 14 Nov 2023 15:13:58 +0900 Subject: [PATCH 74/84] reduce state --- lib/mbedtls.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/lib/mbedtls.c b/lib/mbedtls.c index 256dfca53..a2136e3cf 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -84,7 +84,6 @@ DEFINE_HASH(sha384, SHA384, PSA_ALG_SHA_384); struct st_ptls_mbedtls_cipher_context_t { ptls_cipher_context_t super; psa_algorithm_t alg; - size_t iv_length; unsigned is_enc : 1; unsigned is_op_in_progress : 1; mbedtls_svc_key_id_t key; @@ -107,8 +106,8 @@ static void cipher_init(ptls_cipher_context_t *_ctx, const void *iv) CALL_WITH_CHECK(psa_cipher_decrypt_setup, &ctx->op, ctx->key, ctx->alg); } ctx->is_op_in_progress = 1; - if (ctx->iv_length > 0) - CALL_WITH_CHECK(psa_cipher_set_iv, &ctx->op, iv, ctx->iv_length); + if (ctx->super.algo->iv_size > 0) + CALL_WITH_CHECK(psa_cipher_set_iv, &ctx->op, iv, ctx->super.algo->iv_size); } static void cipher_transform(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t len) @@ -128,8 +127,8 @@ static void cipher_dispose(ptls_cipher_context_t *_ctx) psa_destroy_key(ctx->key); } -static int cipher_setup(ptls_cipher_context_t *_ctx, int is_enc, const void *key_bytes, psa_algorithm_t alg, size_t iv_length, - psa_key_type_t key_type, size_t key_bits) +static int cipher_setup(ptls_cipher_context_t *_ctx, int is_enc, const void *key_bytes, psa_algorithm_t alg, + psa_key_type_t key_type) { struct st_ptls_mbedtls_cipher_context_t *ctx = (struct st_ptls_mbedtls_cipher_context_t *)_ctx; @@ -138,8 +137,8 @@ static int cipher_setup(ptls_cipher_context_t *_ctx, int is_enc, const void *key psa_set_key_usage_flags(&attributes, is_enc ? PSA_KEY_USAGE_ENCRYPT : PSA_KEY_USAGE_DECRYPT); psa_set_key_algorithm(&attributes, alg); psa_set_key_type(&attributes, key_type); - psa_set_key_bits(&attributes, key_bits); - if (psa_import_key(&attributes, key_bytes, key_bits / 8, &ctx->key) != PSA_SUCCESS) + psa_set_key_bits(&attributes, ctx->super.algo->key_size * 8); + if (psa_import_key(&attributes, key_bytes, ctx->super.algo->key_size, &ctx->key) != PSA_SUCCESS) return PTLS_ERROR_LIBRARY; } @@ -148,7 +147,6 @@ static int cipher_setup(ptls_cipher_context_t *_ctx, int is_enc, const void *key ctx->super.do_init = cipher_init; ctx->super.do_transform = cipher_transform; ctx->alg = alg; - ctx->iv_length = iv_length; ctx->is_enc = is_enc; ctx->is_op_in_progress = 0; ctx->op = psa_cipher_operation_init(); @@ -156,11 +154,11 @@ static int cipher_setup(ptls_cipher_context_t *_ctx, int is_enc, const void *key return 0; } -static int ecb_setup(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes, psa_key_type_t key_type, size_t key_bits) +static int ecb_setup(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes, psa_key_type_t key_type) { int ret; - if ((ret = cipher_setup(ctx, is_enc, key_bytes, PSA_ALG_ECB_NO_PADDING, 0, key_type, key_bits)) != 0) + if ((ret = cipher_setup(ctx, is_enc, key_bytes, PSA_ALG_ECB_NO_PADDING, key_type)) != 0) return ret; /* ECB mode does not necessary call `ptls_cipher_init` */ cipher_init(ctx, NULL); @@ -168,15 +166,14 @@ static int ecb_setup(ptls_cipher_context_t *ctx, int is_enc, const void *key_byt return 0; } -static int ctr_setup(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes, size_t iv_length, psa_key_type_t key_type, - size_t key_bits) +static int ctr_setup(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes, psa_key_type_t key_type) { - return cipher_setup(ctx, is_enc, key_bytes, PSA_ALG_CTR, iv_length, key_type, key_bits); + return cipher_setup(ctx, is_enc, key_bytes, PSA_ALG_CTR, key_type); } static int setup_aes128ecb(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) { - return ecb_setup(ctx, is_enc, key_bytes, PSA_KEY_TYPE_AES, 128); + return ecb_setup(ctx, is_enc, key_bytes, PSA_KEY_TYPE_AES); } ptls_cipher_algorithm_t ptls_mbedtls_aes128ecb = { @@ -188,7 +185,7 @@ ptls_cipher_algorithm_t ptls_mbedtls_aes128ecb = { */ static int setup_aes256ecb(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) { - return ecb_setup(ctx, is_enc, key_bytes, PSA_KEY_TYPE_AES, 256); + return ecb_setup(ctx, is_enc, key_bytes, PSA_KEY_TYPE_AES); } ptls_cipher_algorithm_t ptls_mbedtls_aes256ecb = { @@ -201,7 +198,7 @@ ptls_cipher_algorithm_t ptls_mbedtls_aes256ecb = { static int setup_aes128ctr(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) { - return ctr_setup(ctx, is_enc, key_bytes, 16, PSA_KEY_TYPE_AES, 128); + return ctr_setup(ctx, is_enc, key_bytes, PSA_KEY_TYPE_AES); } ptls_cipher_algorithm_t ptls_mbedtls_aes128ctr = { @@ -214,7 +211,7 @@ ptls_cipher_algorithm_t ptls_mbedtls_aes128ctr = { static int setup_aes256ctr(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) { - return ctr_setup(ctx, is_enc, key_bytes, 16, PSA_KEY_TYPE_AES, 256); + return ctr_setup(ctx, is_enc, key_bytes, PSA_KEY_TYPE_AES); } ptls_cipher_algorithm_t ptls_mbedtls_aes256ctr = { @@ -229,7 +226,7 @@ ptls_cipher_algorithm_t ptls_mbedtls_aes256ctr = { */ static int setup_crypto_chacha20(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) { - return cipher_setup(ctx, is_enc, key_bytes, PSA_ALG_STREAM_CIPHER, 16, PSA_KEY_TYPE_CHACHA20, 256); + return cipher_setup(ctx, is_enc, key_bytes, PSA_ALG_STREAM_CIPHER, 16, PSA_KEY_TYPE_CHACHA20); } ptls_cipher_algorithm_t ptls_mbedtls_chacha20 = { From 177c1564e46fd3195729a8007d4873f00d51c29f Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Tue, 14 Nov 2023 15:17:03 +0900 Subject: [PATCH 75/84] ... and we find a bug --- lib/mbedtls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mbedtls.c b/lib/mbedtls.c index a2136e3cf..ed9374d5a 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -189,7 +189,7 @@ static int setup_aes256ecb(ptls_cipher_context_t *ctx, int is_enc, const void *k } ptls_cipher_algorithm_t ptls_mbedtls_aes256ecb = { - "AES256-ECB", PTLS_AES128_KEY_SIZE, PTLS_AES_BLOCK_SIZE, 0 /* iv size */, sizeof(struct st_ptls_mbedtls_cipher_context_t), + "AES256-ECB", PTLS_AES256_KEY_SIZE, PTLS_AES_BLOCK_SIZE, 0 /* iv size */, sizeof(struct st_ptls_mbedtls_cipher_context_t), setup_aes256ecb}; /* From e6a01a86e6569485a151a2ab72ffd205955bb8f2 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Tue, 14 Nov 2023 15:19:26 +0900 Subject: [PATCH 76/84] update the hidden chacha20 backend --- lib/mbedtls.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/mbedtls.c b/lib/mbedtls.c index ed9374d5a..7344d8f16 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -224,9 +224,9 @@ ptls_cipher_algorithm_t ptls_mbedtls_aes256ctr = { * This is disabled for now, as there seems to be an issue when * setting the 16 bytes long IV that we need. */ -static int setup_crypto_chacha20(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) +static int setup_chacha20(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) { - return cipher_setup(ctx, is_enc, key_bytes, PSA_ALG_STREAM_CIPHER, 16, PSA_KEY_TYPE_CHACHA20); + return cipher_setup(ctx, is_enc, key_bytes, PSA_ALG_CTR, PSA_KEY_TYPE_CHACHA20); } ptls_cipher_algorithm_t ptls_mbedtls_chacha20 = { From 7ccec73a90881ae8974140726fee53bdcc47cc5b Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Tue, 14 Nov 2023 15:22:11 +0900 Subject: [PATCH 77/84] no need to have a wrapper for CTR mode --- lib/mbedtls.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/lib/mbedtls.c b/lib/mbedtls.c index 7344d8f16..f9fe42f70 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -166,11 +166,6 @@ static int ecb_setup(ptls_cipher_context_t *ctx, int is_enc, const void *key_byt return 0; } -static int ctr_setup(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes, psa_key_type_t key_type) -{ - return cipher_setup(ctx, is_enc, key_bytes, PSA_ALG_CTR, key_type); -} - static int setup_aes128ecb(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) { return ecb_setup(ctx, is_enc, key_bytes, PSA_KEY_TYPE_AES); @@ -198,7 +193,7 @@ ptls_cipher_algorithm_t ptls_mbedtls_aes256ecb = { static int setup_aes128ctr(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) { - return ctr_setup(ctx, is_enc, key_bytes, PSA_KEY_TYPE_AES); + return cipher_setup(ctx, is_enc, key_bytes, PSA_ALG_CTR, PSA_KEY_TYPE_AES); } ptls_cipher_algorithm_t ptls_mbedtls_aes128ctr = { @@ -211,7 +206,7 @@ ptls_cipher_algorithm_t ptls_mbedtls_aes128ctr = { static int setup_aes256ctr(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) { - return ctr_setup(ctx, is_enc, key_bytes, PSA_KEY_TYPE_AES); + return cipher_setup(ctx, is_enc, key_bytes, PSA_ALG_CTR, PSA_KEY_TYPE_AES); } ptls_cipher_algorithm_t ptls_mbedtls_aes256ctr = { From f481e291dca5bc8e6eef2db5f016aee628184229 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Tue, 14 Nov 2023 15:26:09 +0900 Subject: [PATCH 78/84] remove verbose doc comments --- lib/mbedtls.c | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/lib/mbedtls.c b/lib/mbedtls.c index f9fe42f70..2186d17c5 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -78,7 +78,7 @@ DEFINE_HASH(sha512, SHA512, PSA_ALG_SHA_512); DEFINE_HASH(sha384, SHA384, PSA_ALG_SHA_384); #endif -/* +/** * Generic implementation of a cipher using the PSA API */ struct st_ptls_mbedtls_cipher_context_t { @@ -175,9 +175,6 @@ ptls_cipher_algorithm_t ptls_mbedtls_aes128ecb = { "AES128-ECB", PTLS_AES128_KEY_SIZE, PTLS_AES_BLOCK_SIZE, 0 /* iv size */, sizeof(struct st_ptls_mbedtls_cipher_context_t), setup_aes128ecb}; -/* - * Implementation of AES256_ECB using the PSA API: - */ static int setup_aes256ecb(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) { return ecb_setup(ctx, is_enc, key_bytes, PSA_KEY_TYPE_AES); @@ -187,10 +184,6 @@ ptls_cipher_algorithm_t ptls_mbedtls_aes256ecb = { "AES256-ECB", PTLS_AES256_KEY_SIZE, PTLS_AES_BLOCK_SIZE, 0 /* iv size */, sizeof(struct st_ptls_mbedtls_cipher_context_t), setup_aes256ecb}; -/* - * Implementation of AES128_CTR using the PSA API: - */ - static int setup_aes128ctr(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) { return cipher_setup(ctx, is_enc, key_bytes, PSA_ALG_CTR, PSA_KEY_TYPE_AES); @@ -200,10 +193,6 @@ ptls_cipher_algorithm_t ptls_mbedtls_aes128ctr = { "AES128-CTR", PTLS_AES128_KEY_SIZE, PTLS_AES_BLOCK_SIZE, 16 /* iv size */, sizeof(struct st_ptls_mbedtls_cipher_context_t), setup_aes128ctr}; -/* - * Implementation of AES128_CTR using the PSA API: - */ - static int setup_aes256ctr(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) { return cipher_setup(ctx, is_enc, key_bytes, PSA_ALG_CTR, PSA_KEY_TYPE_AES); @@ -214,11 +203,8 @@ ptls_cipher_algorithm_t ptls_mbedtls_aes256ctr = { setup_aes256ctr}; #if 0 -/* -* Implementation of CHACHA20 using the PSA API. -* This is disabled for now, as there seems to be an issue when -* setting the 16 bytes long IV that we need. -*/ +/* CHACHA20 backend using PSA API is disabled for now, as there seems to be an issue when setting the 16 bytes long IV that we + * need. */ static int setup_chacha20(ptls_cipher_context_t *ctx, int is_enc, const void *key_bytes) { return cipher_setup(ctx, is_enc, key_bytes, PSA_ALG_CTR, PSA_KEY_TYPE_CHACHA20); @@ -229,9 +215,7 @@ ptls_cipher_algorithm_t ptls_mbedtls_chacha20 = { setup_chacha20}; #else /* Implementation of ChaCha20 using the low level ChaCha20 API. - * TODO: remove this and the reference to chacha20.h as soon as - * the IV bug in the generic implementation is fixed. - */ + * TODO: remove this and the reference to chacha20.h as soon as the IV bug in the generic implementation is fixed. */ struct st_ptls_mbedtls_chacha20_context_t { ptls_cipher_context_t super; mbedtls_chacha20_context mctx; @@ -621,8 +605,6 @@ static int key_exchange_exchange(ptls_key_exchange_algorithm_t *algo, ptls_iovec return ret; } -/* Instantiation of the generic key exchange API with secp256r1 - */ static int secp256r1_create(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **ctx) { return key_exchange_create(algo, ctx, &secp256r1_params); @@ -637,8 +619,6 @@ static int secp256r1_exchange(const struct st_ptls_key_exchange_algorithm_t *alg ptls_key_exchange_algorithm_t ptls_mbedtls_secp256r1 = { .id = PTLS_GROUP_SECP256R1, .name = PTLS_GROUP_NAME_SECP256R1, .create = secp256r1_create, .exchange = secp256r1_exchange}; -/* Instantiation of the generic key exchange API with x25519 - */ static int x25519_create(const struct st_ptls_key_exchange_algorithm_t *algo, ptls_key_exchange_context_t **ctx) { return key_exchange_create(algo, ctx, &x25519_params); From 72da59db136370a7c73bbf0543c34ae7dbbfe4ef Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Tue, 14 Nov 2023 16:04:29 +0900 Subject: [PATCH 79/84] [xcode] add files --- picotls.xcodeproj/project.pbxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/picotls.xcodeproj/project.pbxproj b/picotls.xcodeproj/project.pbxproj index 67ddebfdd..0174a7b1c 100644 --- a/picotls.xcodeproj/project.pbxproj +++ b/picotls.xcodeproj/project.pbxproj @@ -205,6 +205,7 @@ 081F00CC291A358800534A86 /* asn1.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = asn1.h; sourceTree = ""; }; 081F00CD291A358800534A86 /* pembase64.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pembase64.h; sourceTree = ""; }; 081F00CE291A358800534A86 /* ptlsbcrypt.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ptlsbcrypt.h; sourceTree = ""; }; + 087F1A732B034AEB00E81AC1 /* FindMbedTLS.cmake */ = {isa = PBXFileReference; lastKnownFileType = text; path = FindMbedTLS.cmake; sourceTree = ""; }; 0883D32A2AF601A700B711CC /* mbedtls.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mbedtls.c; sourceTree = ""; }; 0883D32B2AF601B900B711CC /* mbedtls.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mbedtls.c; sourceTree = ""; }; 0883D32C2AF601CB00B711CC /* mbedtls.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mbedtls.h; sourceTree = ""; }; @@ -532,6 +533,7 @@ E95EBCC9227E9FF30022C32D /* cmake */ = { isa = PBXGroup; children = ( + 087F1A732B034AEB00E81AC1 /* FindMbedTLS.cmake */, 08A835EB2996971300D872CE /* boringssl-adjust.cmake */, E95EBCCA227EA0180022C32D /* dtrace-utils.cmake */, ); From 7e7d39ba516ec081e6386391faada730a9776b17 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Tue, 14 Nov 2023 16:06:02 +0900 Subject: [PATCH 80/84] use standard names (e.g., _ROOT_DIR), and UNIX-style search paths (/usr/local, lib) --- CMakeLists.txt | 29 +++++++++---------- cmake/FindMbedTLS.cmake | 64 +++++++++++++++++++++++++---------------- 2 files changed, 54 insertions(+), 39 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f1f2f736f..86331a851 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ ENDIF () FIND_PACKAGE(PkgConfig REQUIRED) INCLUDE(cmake/dtrace-utils.cmake) INCLUDE(cmake/boringssl-adjust.cmake) -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/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 @@ -204,23 +204,22 @@ ENDIF () IF (WITH_MBEDTLS) FIND_PACKAGE(MbedTLS) - # IF (MbedTLS_FOUND) - message(STATUS "mbedtls/include: ${MBEDTLS_INCLUDE_DIRS}") - message(STATUS "mbedtls libraries: ${MBEDTLS_LIBRARIES}") - INCLUDE_DIRECTORIES(${MBEDTLS_INCLUDE_DIRS}) - ADD_LIBRARY(picotls-mbedtls lib/mbedtls.c) - ADD_EXECUTABLE(test-mbedtls.t + IF (NOT MbedTLS_FOUND) + MESSAGE(FATAL_ERROR "-DWITH_MBEDTLS set but mbedtls not found") + ENDIF () + message(STATUS "mbedtls/include: ${MBEDTLS_INCLUDE_DIRS}") + message(STATUS "mbedtls libraries: ${MBEDTLS_LIBRARIES}") + INCLUDE_DIRECTORIES(${MBEDTLS_INCLUDE_DIRS}) + ADD_LIBRARY(picotls-mbedtls lib/mbedtls.c) + ADD_EXECUTABLE(test-mbedtls.t deps/picotest/picotest.c ${CORE_TEST_FILES} t/mbedtls.c) - TARGET_LINK_LIBRARIES(test-mbedtls.t - picotls-minicrypto picotls-mbedtls - ${MBEDTLS_LIBRARIES}) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPTLS_HAVE_MBEDTLS=1") - LIST(APPEND PTLSBENCH_LIBS picotls-mbedtls ${MBEDTLS_LIBRARIES}) - #ELSE () - # MESSAGE (FATAL_ERROR "MbedTLS not found") - #ENDIF() + TARGET_LINK_LIBRARIES(test-mbedtls.t + picotls-minicrypto picotls-mbedtls + ${MBEDTLS_LIBRARIES}) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPTLS_HAVE_MBEDTLS=1") + LIST(APPEND PTLSBENCH_LIBS picotls-mbedtls ${MBEDTLS_LIBRARIES}) ENDIF () ADD_EXECUTABLE(ptlsbench t/ptlsbench.c) diff --git a/cmake/FindMbedTLS.cmake b/cmake/FindMbedTLS.cmake index e71403ea0..48185f12a 100644 --- a/cmake/FindMbedTLS.cmake +++ b/cmake/FindMbedTLS.cmake @@ -1,32 +1,48 @@ -# - Try to find MbedTLS -# set(MBEDTLS_LIBRARY mbedtls) -# set(MBEDTLS_INCLUDE_DIRS ${MBEDTLS_SOURCE_DIR}/include) -find_path(MBEDTLS_INCLUDE_DIRS - NAMES mbedtls/build_info.h psa/crypto.h - HINTS ${MBEDTLS_PREFIX}/include/ - ${CMAKE_SOURCE_DIR}/../mbedtls/include/ - ${CMAKE_BINARY_DIR}/../mbedtls/include/ - ../mbedtls/include/ ) +# Try to find MbedTLS; recognized hints are: +# * MBEDTLS_ROOT_DIR +# * MBEDTLS_LIBDIR +# Upon return, +# * MBEDTLS_INCLUDE_DIRS +# * MBEDTLS_LIBRARIES +# will be set. +# Users may supply MBEDTLS_INCLUDE_DIRS or MBEDTLS_LIBRARIES directly. +INCLUDE(FindPackageHandleStandardArgs) +# setup default vars for the hints +IF (NOT DEFINED MBEDTLS_ROOT_DIR) + SET(MBEDTLS_ROOT_DIR "/usr/local" "/usr") +ENDIF () +IF (NOT DEFINED MBEDTLS_LIBDIR) + SET(MBEDTLS_LIBDIR) + FOREACH (item IN LISTS MBEDTLS_ROOT_DIR) + LIST(APPEND MBEDTLS_LIBDIR "${item}/lib" "${item}/build/library") + ENDFOREACH () +ENDIF () -set(MBEDTLS_HINTS ${MBEDTLS_PREFIX}/build/library - ${CMAKE_BINARY_DIR}/../mbedtls/build/library - ../mbedtls/build/library ../mbedtls/library) +# find include directory +IF (NOT DEFINED MBEDTLS_INCLUDE_DIRS) + SET(HINTS) + FOREACH (item IN LISTS MBEDTLS_ROOT_DIR) + LIST(APPEND HINTS "${item}/include") + ENDFOREACH () + FIND_PATH(MBEDTLS_INCLUDE_DIRS + NAMES mbedtls/build_info.h psa/crypto.h + HINTS $HINTS) +ENDIF () -find_library(MBEDTLS_LIBRARY mbedtls HINTS ${MBEDTLS_HINTS}) -find_library(MBEDTLS_CRYPTO mbedcrypto HINTS ${MBEDTLS_HINTS}) -find_library(MBEDTLS_X509 mbedx509 HINTS ${MBEDTLS_HINTS}) -include(FindPackageHandleStandardArgs) -# handle the QUIETLY and REQUIRED arguments and set PTLS_FOUND to TRUE -# if all listed variables are TRUE -find_package_handle_standard_args(MbedTLS REQUIRED_VARS +# find libraries +FIND_LIBRARY(MBEDTLS_LIBRARY mbedtls HINTS $MBEDTLS_LIBDIR) +FIND_LIBRARY(MBEDTLS_CRYPTO mbedcrypto HINTS $MBEDTLS_LIBDIR) +FIND_LIBRARY(MBEDTLS_X509 mbedx509 HINTS $MBEDTLS_LIBDIR) + +# setup +FIND_PACKAGE_HANDLE_STANDARD_ARGS(MbedTLS REQUIRED_VARS MBEDTLS_LIBRARY MBEDTLS_CRYPTO MBEDTLS_X509 MBEDTLS_INCLUDE_DIRS) - -if (MbedTLS_FOUND) - set(MBEDTLS_LIBRARIES ${MBEDTLS_LIBRARY} ${MBEDTLS_CRYPTO} ${MBEDTLS_X509}) - mark_as_advanced(MBEDTLS_LIBRARIES MBEDTLS_INCLUDE_DIRS) -endif () \ No newline at end of file +IF (MbedTLS_FOUND) + SET(MBEDTLS_LIBRARIES ${MBEDTLS_LIBRARY} ${MBEDTLS_CRYPTO} ${MBEDTLS_X509}) + MARK_AS_ADVANCED(MBEDTLS_LIBRARIES MBEDTLS_INCLUDE_DIRS) +ENDIF () From cdc446219ab9fbe98c9b613bede1028d9a1f7366 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Tue, 14 Nov 2023 16:13:49 +0900 Subject: [PATCH 81/84] sha384 might not be available --- include/picotls/mbedtls.h | 2 ++ lib/mbedtls.c | 9 +++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/include/picotls/mbedtls.h b/include/picotls/mbedtls.h index 538a2508f..feef4951e 100644 --- a/include/picotls/mbedtls.h +++ b/include/picotls/mbedtls.h @@ -49,7 +49,9 @@ extern ptls_aead_algorithm_t ptls_mbedtls_aes256gcm; extern ptls_aead_algorithm_t ptls_mbedtls_chacha20poly1305; extern ptls_cipher_suite_t ptls_mbedtls_aes128gcmsha256; +#if defined(MBEDTLS_SHA384_C) extern ptls_cipher_suite_t ptls_mbedtls_aes256gcmsha384; +#endif extern ptls_cipher_suite_t ptls_mbedtls_chacha20poly1305sha256; extern ptls_cipher_suite_t *ptls_mbedtls_cipher_suites[]; diff --git a/lib/mbedtls.c b/lib/mbedtls.c index 2186d17c5..86fa7b017 100644 --- a/lib/mbedtls.c +++ b/lib/mbedtls.c @@ -425,10 +425,12 @@ ptls_aead_algorithm_t ptls_mbedtls_aes256gcm = {"AES256-GCM", sizeof(struct ptls_mbedtls_aead_context_t), aead_setup_aes256gcm}; +#if defined(MBEDTLS_SHA384_C) ptls_cipher_suite_t ptls_mbedtls_aes256gcmsha384 = {.id = PTLS_CIPHER_SUITE_AES_256_GCM_SHA384, .name = PTLS_CIPHER_SUITE_NAME_AES_256_GCM_SHA384, .aead = &ptls_mbedtls_aes256gcm, .hash = &ptls_mbedtls_sha384}; +#endif static int aead_setup_chacha20poly1305(ptls_aead_context_t *_ctx, int is_enc, const void *key_bytes, const void *iv) { @@ -454,8 +456,11 @@ ptls_cipher_suite_t ptls_mbedtls_chacha20poly1305sha256 = {.id = PTLS_CIPHER_SUI .aead = &ptls_mbedtls_chacha20poly1305, .hash = &ptls_mbedtls_sha256}; -ptls_cipher_suite_t *ptls_mbedtls_cipher_suites[] = {&ptls_mbedtls_aes256gcmsha384, &ptls_mbedtls_aes128gcmsha256, - &ptls_mbedtls_chacha20poly1305sha256, NULL}; +ptls_cipher_suite_t *ptls_mbedtls_cipher_suites[] = { +#if defined(MBEDTLS_SHA384_C) + &ptls_mbedtls_aes256gcmsha384, +#endif + &ptls_mbedtls_aes128gcmsha256, &ptls_mbedtls_chacha20poly1305sha256, NULL}; #define PTLS_MBEDTLS_ECDH_PUBKEY_MAX 129 From 62236db4d4a7457b1ada377220f45d8d56015a21 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Tue, 14 Nov 2023 16:31:12 +0900 Subject: [PATCH 82/84] mbedtls of ubuntu2204 does not have these files, we can remove them and still refer to `MBEDTLS_SHA384_C` at least on homebrew --- include/picotls/mbedtls.h | 3 +-- t/mbedtls.c | 4 ---- t/ptlsbench.c | 2 -- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/include/picotls/mbedtls.h b/include/picotls/mbedtls.h index feef4951e..b64924694 100644 --- a/include/picotls/mbedtls.h +++ b/include/picotls/mbedtls.h @@ -26,8 +26,7 @@ extern "C" { #endif -#include -#include +#include #include "picotls.h" /* before using any of these objects, psa_crypto_init() must be called */ diff --git a/t/mbedtls.c b/t/mbedtls.c index 94cf55cd8..d3651de14 100644 --- a/t/mbedtls.c +++ b/t/mbedtls.c @@ -29,10 +29,6 @@ #include #include #include -#include "mbedtls/mbedtls_config.h" -#include "mbedtls/build_info.h" -#include "psa/crypto.h" -#include "psa/crypto_struct.h" #include "picotls/mbedtls.h" #include "picotls/minicrypto.h" #include "../deps/picotest/picotest.h" diff --git a/t/ptlsbench.c b/t/ptlsbench.c index 9d9b89d8d..b0f525b8f 100644 --- a/t/ptlsbench.c +++ b/t/ptlsbench.c @@ -60,8 +60,6 @@ #endif #ifdef PTLS_HAVE_MBEDTLS -#include "mbedtls/build_info.h" -#include "psa/crypto.h" #include "picotls/mbedtls.h" #endif From cce8446b0b1c39689eedc9c165c7cbe45e3a7513 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Wed, 15 Nov 2023 14:46:59 +0900 Subject: [PATCH 83/84] run mbedtls test as part of the main CI (builds on top of https://github.com/h2o/h2o/pull/3311) --- .github/workflows/ci.yml | 4 ++-- .github/workflows/mbedtls.yml | 44 ----------------------------------- 2 files changed, 2 insertions(+), 46 deletions(-) delete mode 100644 .github/workflows/mbedtls.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 80b5401a4..12938762e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,8 +19,8 @@ jobs: 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 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 3.0 + mbedtls" + command: make -f misc/docker-ci.mk CONTAINER_NAME=h2oserver/h2o-ci:ubuntu2204 CMAKE_ARGS='-DWITH_MBEDTLS=1' - name: "Linux / OpenSSL 1.1.1 + ASan & UBSan" command: make -f misc/docker-ci.mk CMAKE_ARGS='-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_FLAGS=-fsanitize=address,undefined -DCMAKE_CXX_FLAGS=-fsanitize=address,undefined' CHECK_ENVS='ASAN_OPTIONS=detect_leaks=0 UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1' - name: "Linux / boringssl" diff --git a/.github/workflows/mbedtls.yml b/.github/workflows/mbedtls.yml deleted file mode 100644 index 93d14de85..000000000 --- a/.github/workflows/mbedtls.yml +++ /dev/null @@ -1,44 +0,0 @@ ---- -name: "MbedTLS-test" - -on: [push, pull_request] - -jobs: - mbedtls: - name: MbedTLS-test - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - with: - # We must fetch at least the immediate parents so that if this is - # a pull request then we can checkout the head. - fetch-depth: 2 - submodules: 'recursive' - - - name: Installing MbedTLS - run: | - cd .. - git clone https://github.com/Mbed-TLS/mbedtls - cd mbedtls - echo "cloned mbedtls" - mkdir build - cd build - cmake -S .. . - echo "cmake done" - make - echo "compiled MbedTLS" - pwd - cd ../../picotls - - - name: Compile picotls - run: | - echo "building picotls with MbedTLS" - pwd - cmake "-DWITH_MBEDTLS=ON" . - make - - - name: Run test - run: | - ./test-mbedtls.t \ No newline at end of file From 3c2af6de8c976958ff40e09dc578f37b46451c7f Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Thu, 16 Nov 2023 11:55:00 +0900 Subject: [PATCH 84/84] remove non-standard directory --- cmake/FindMbedTLS.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/FindMbedTLS.cmake b/cmake/FindMbedTLS.cmake index 48185f12a..048a1e9b4 100644 --- a/cmake/FindMbedTLS.cmake +++ b/cmake/FindMbedTLS.cmake @@ -16,7 +16,7 @@ ENDIF () IF (NOT DEFINED MBEDTLS_LIBDIR) SET(MBEDTLS_LIBDIR) FOREACH (item IN LISTS MBEDTLS_ROOT_DIR) - LIST(APPEND MBEDTLS_LIBDIR "${item}/lib" "${item}/build/library") + LIST(APPEND MBEDTLS_LIBDIR "${item}/lib") ENDFOREACH () ENDIF ()