From cc88d4231ca7b52b04a251df3db8b642d45ead58 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Mon, 8 Apr 2024 12:06:41 +0900 Subject: [PATCH] clang-format --- include/picotls/mbedtls.h | 4 +- lib/mbedtls_sign.c | 440 ++++++++++++++++---------------------- t/mbedtls.c | 63 +++--- 3 files changed, 211 insertions(+), 296 deletions(-) diff --git a/include/picotls/mbedtls.h b/include/picotls/mbedtls.h index 581c41655..62fd382d3 100644 --- a/include/picotls/mbedtls.h +++ b/include/picotls/mbedtls.h @@ -60,8 +60,8 @@ extern ptls_key_exchange_algorithm_t *ptls_mbedtls_key_exchanges[]; void ptls_mbedtls_random_bytes(void *buf, size_t len); -int ptls_mbedtls_load_private_key(ptls_context_t* ctx, char const* pem_fname); -void ptls_mbedtls_dispose_sign_certificate(ptls_sign_certificate_t* _self); +int ptls_mbedtls_load_private_key(ptls_context_t *ctx, char const *pem_fname); +void ptls_mbedtls_dispose_sign_certificate(ptls_sign_certificate_t *_self); #ifdef __cplusplus } diff --git a/lib/mbedtls_sign.c b/lib/mbedtls_sign.c index 8eed140a5..de06175f3 100644 --- a/lib/mbedtls_sign.c +++ b/lib/mbedtls_sign.c @@ -1,25 +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,7 +38,6 @@ #include /* #include "ptls_mbedtls.h" */ - typedef struct st_ptls_mbedtls_signature_scheme_t { uint16_t scheme_id; psa_algorithm_t hash_algo; @@ -49,18 +47,17 @@ typedef struct st_ptls_mbedtls_sign_certificate_t { ptls_sign_certificate_t super; mbedtls_svc_key_id_t key_id; psa_key_attributes_t attributes; - const ptls_mbedtls_signature_scheme_t * schemes; + const ptls_mbedtls_signature_scheme_t *schemes; } ptls_mbedtls_sign_certificate_t; -static const unsigned char ptls_mbedtls_oid_ec_key[] = { 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01 }; -static const unsigned char ptls_mbedtls_oid_rsa_key[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 }; -static const unsigned char ptls_mbedtls_oid_ed25519[] = { 0x2b, 0x65, 0x70 }; +static const unsigned char ptls_mbedtls_oid_ec_key[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01}; +static const unsigned char ptls_mbedtls_oid_rsa_key[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01}; +static const unsigned char ptls_mbedtls_oid_ed25519[] = {0x2b, 0x65, 0x70}; -static const ptls_mbedtls_signature_scheme_t rsa_signature_schemes[] = { - {PTLS_SIGNATURE_RSA_PSS_RSAE_SHA256, PSA_ALG_SHA_256}, - {PTLS_SIGNATURE_RSA_PSS_RSAE_SHA384, PSA_ALG_SHA_384}, - {PTLS_SIGNATURE_RSA_PSS_RSAE_SHA512, PSA_ALG_SHA_512}, - {UINT16_MAX, PSA_ALG_NONE}}; +static const ptls_mbedtls_signature_scheme_t rsa_signature_schemes[] = {{PTLS_SIGNATURE_RSA_PSS_RSAE_SHA256, PSA_ALG_SHA_256}, + {PTLS_SIGNATURE_RSA_PSS_RSAE_SHA384, PSA_ALG_SHA_384}, + {PTLS_SIGNATURE_RSA_PSS_RSAE_SHA512, PSA_ALG_SHA_512}, + {UINT16_MAX, PSA_ALG_NONE}}; static const ptls_mbedtls_signature_scheme_t secp256r1_signature_schemes[] = { {PTLS_SIGNATURE_ECDSA_SECP256R1_SHA256, PSA_ALG_SHA_256}, {UINT16_MAX, PSA_ALG_NONE}}; @@ -68,14 +65,14 @@ static const ptls_mbedtls_signature_scheme_t secp384r1_signature_schemes[] = { {PTLS_SIGNATURE_ECDSA_SECP384R1_SHA384, PSA_ALG_SHA_384}, {UINT16_MAX, PSA_ALG_NONE}}; static const ptls_mbedtls_signature_scheme_t secp521r1_signature_schemes[] = { {PTLS_SIGNATURE_ECDSA_SECP521R1_SHA512, PSA_ALG_SHA_512}, {UINT16_MAX, PSA_ALG_NONE}}; -static const ptls_mbedtls_signature_scheme_t ed25519_signature_schemes[] = { - {PTLS_SIGNATURE_ED25519, PSA_ALG_NONE}, {UINT16_MAX, PSA_ALG_NONE}}; +static const ptls_mbedtls_signature_scheme_t ed25519_signature_schemes[] = {{PTLS_SIGNATURE_ED25519, PSA_ALG_NONE}, + {UINT16_MAX, PSA_ALG_NONE}}; #if defined(MBEDTLS_PEM_PARSE_C) /* Mapping of MBEDTLS APIs to Picotls */ -static int ptls_mbedtls_parse_der_length(const unsigned char* pem_buf, size_t pem_len, size_t* px, size_t *pl) +static int ptls_mbedtls_parse_der_length(const unsigned char *pem_buf, size_t pem_len, size_t *px, size_t *pl) { int ret = 0; size_t x = *px; @@ -97,18 +94,15 @@ static int ptls_mbedtls_parse_der_length(const unsigned char* pem_buf, size_t pe return ret; } -static int ptls_mbedtls_parse_ecdsa_field(const unsigned char* pem_buf, size_t pem_len, size_t* key_index, size_t* key_length) +static int ptls_mbedtls_parse_ecdsa_field(const unsigned char *pem_buf, size_t pem_len, size_t *key_index, size_t *key_length) { int ret = 0; size_t x = 0; // const unsigned char head = { 0x30, l-2, 0x02, 0x01, 0x01, 0x04 } - if (pem_len < 16 || - pem_buf[x++] != 0x30 /* type = sequence */) - { + if (pem_len < 16 || pem_buf[x++] != 0x30 /* type = sequence */) { ret = -1; - } - else { + } else { size_t l = 0; ret = ptls_mbedtls_parse_der_length(pem_buf, pem_len, &x, &l); @@ -116,15 +110,11 @@ static int ptls_mbedtls_parse_ecdsa_field(const unsigned char* pem_buf, size_t p ret = -1; } } - if (ret == 0){ - if (pem_buf[x++] != 0x02 /* type = int */ || - pem_buf[x++] != 0x01 /* length of int = 1 */ || - pem_buf[x++] != 0x01 /* version = 1 */ || - pem_buf[x++] != 0x04 /*octet string */ || - pem_buf[x] + x >= pem_len) { + if (ret == 0) { + if (pem_buf[x++] != 0x02 /* type = int */ || pem_buf[x++] != 0x01 /* length of int = 1 */ || + pem_buf[x++] != 0x01 /* version = 1 */ || pem_buf[x++] != 0x04 /*octet string */ || pem_buf[x] + x >= pem_len) { ret = -1; - } - else { + } else { *key_index = x + 1; *key_length = pem_buf[x]; x += 1 + pem_buf[x]; @@ -135,19 +125,16 @@ static int ptls_mbedtls_parse_ecdsa_field(const unsigned char* pem_buf, size_t p if (x + pem_buf[x] >= pem_len) { /* EC parameters extend beyond buffer */ ret = -1; - } - else { + } else { x += pem_buf[x] + 1; } } if (ret == 0 && x < pem_len) { /* skip the public key parameter */ - if (pem_buf[x++] != 0xa1 || - x >= pem_len) { + if (pem_buf[x++] != 0xa1 || x >= pem_len) { ret = -1; - } - else { + } else { size_t l = 0; ret = ptls_mbedtls_parse_der_length(pem_buf, pem_len, &x, &l); x += l; @@ -163,12 +150,11 @@ static int ptls_mbedtls_parse_ecdsa_field(const unsigned char* pem_buf, size_t p } /* On input, key_index points at the "key information" in a -* "private key" message. For EDDSA, this contains an -* octet string carrying the key itself. On return, key index -* and key length are updated to point at the key field. -*/ -static int ptls_mbedtls_parse_eddsa_key(const unsigned char* pem_buf, size_t pem_len, - size_t* key_index, size_t* key_length) + * "private key" message. For EDDSA, this contains an + * octet string carrying the key itself. On return, key index + * and key length are updated to point at the key field. + */ +static int ptls_mbedtls_parse_eddsa_key(const unsigned char *pem_buf, size_t pem_len, size_t *key_index, size_t *key_length) { int ret = 0; size_t x = *key_index; @@ -180,8 +166,7 @@ static int ptls_mbedtls_parse_eddsa_key(const unsigned char* pem_buf, size_t pem ret = ptls_mbedtls_parse_der_length(pem_buf, pem_len, &x, &l_key); if (x + l_key != *key_index + *key_length) { ret = -1; - } - else { + } else { *key_index = x; *key_length = l_key; @@ -191,12 +176,11 @@ static int ptls_mbedtls_parse_eddsa_key(const unsigned char* pem_buf, size_t pem } /* If using PKCS8 encoding, the "private key" field contains the -* same "ecdsa field" found in PEM "EC PRIVATE KEY" files. We -* use the same parser, but we need to reset indices so they -* reflect the unwrapped key. -*/ -int ptls_mbedtls_parse_ec_private_key(const unsigned char* pem_buf, size_t pem_len, - size_t* key_index, size_t* key_length) + * same "ecdsa field" found in PEM "EC PRIVATE KEY" files. We + * use the same parser, but we need to reset indices so they + * reflect the unwrapped key. + */ +int ptls_mbedtls_parse_ec_private_key(const unsigned char *pem_buf, size_t pem_len, size_t *key_index, size_t *key_length) { size_t x_offset = 0; size_t x_len = 0; @@ -209,9 +193,8 @@ int ptls_mbedtls_parse_ec_private_key(const unsigned char* pem_buf, size_t pem_l return ret; } -int test_parse_private_key_field(const unsigned char* pem_buf, size_t pem_len, - size_t* oid_index, size_t *oid_length, - size_t* key_index, size_t* key_length) +int test_parse_private_key_field(const unsigned char *pem_buf, size_t pem_len, size_t *oid_index, size_t *oid_length, + size_t *key_index, size_t *key_length) { int ret = 0; size_t l_oid = 0; @@ -221,12 +204,9 @@ int test_parse_private_key_field(const unsigned char* pem_buf, size_t pem_len, size_t x = 0; /* const unsigned char head = {0x30, l - 2, 0x02, 0x01, 0x00} */ - if (pem_len < 16 || - pem_buf[x++] != 0x30 /* type = sequence */) - { + if (pem_len < 16 || pem_buf[x++] != 0x30 /* type = sequence */) { ret = -1; - } - else { + } else { size_t l = 0; ret = ptls_mbedtls_parse_der_length(pem_buf, pem_len, &x, &l); @@ -235,31 +215,25 @@ int test_parse_private_key_field(const unsigned char* pem_buf, size_t pem_len, } } if (ret == 0) { - if (pem_buf[x++] != 0x02 /* type = int */ || - pem_buf[x++] != 0x01 /* length of int = 1 */ || - pem_buf[x++] != 0x00 /* version = 0 */ || - pem_buf[x++] != 0x30 /* sequence */){ + if (pem_buf[x++] != 0x02 /* type = int */ || pem_buf[x++] != 0x01 /* length of int = 1 */ || + pem_buf[x++] != 0x00 /* version = 0 */ || pem_buf[x++] != 0x30 /* sequence */) { ret = -1; - } - else { + } else { /* the sequence contains the OID and optional key attributes, - * which we ignore for now. - */ + * which we ignore for now. + */ size_t l_seq = 0; size_t x_seq; ret = ptls_mbedtls_parse_der_length(pem_buf, pem_len, &x, &l_seq); x_seq = x; - if (x + l_seq >= pem_len || - pem_buf[x++] != 0x06) { + if (x + l_seq >= pem_len || pem_buf[x++] != 0x06) { ret = -1; - } - else { + } else { l_oid = pem_buf[x++]; x_oid = x; if (x + l_oid > x_seq + l_seq) { ret = -1; - } - else { + } else { x = x_seq + l_seq; } } @@ -267,13 +241,11 @@ int test_parse_private_key_field(const unsigned char* pem_buf, size_t pem_len, } if (ret == 0) { /* At that point the oid has been identified. - * The next parameter is an octet string containing the key info. - */ - if (x + 2 > pem_len || - pem_buf[x++] != 0x04){ + * The next parameter is an octet string containing the key info. + */ + if (x + 2 > pem_len || pem_buf[x++] != 0x04) { ret = -1; - } - else { + } else { ret = ptls_mbedtls_parse_der_length(pem_buf, pem_len, &x, &l_key); x_key = x; x += l_key; @@ -290,11 +262,8 @@ int test_parse_private_key_field(const unsigned char* pem_buf, size_t pem_len, return ret; } -int ptls_mbedtls_get_der_key(mbedtls_pem_context* pem, - mbedtls_pk_type_t * pk_type, - const unsigned char* key, size_t keylen, - const unsigned char* pwd, size_t pwdlen, - int (*f_rng)(void*, unsigned char*, size_t), void* p_rng) +int ptls_mbedtls_get_der_key(mbedtls_pem_context *pem, mbedtls_pk_type_t *pk_type, const unsigned char *key, size_t keylen, + const unsigned char *pwd, size_t pwdlen, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; #if defined(MBEDTLS_PEM_PARSE_C) @@ -311,25 +280,19 @@ int ptls_mbedtls_get_der_key(mbedtls_pem_context* pem, /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ if (key[keylen - 1] != '\0') { ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - } - else { - ret = mbedtls_pem_read_buffer(pem, - "-----BEGIN RSA PRIVATE KEY-----", - "-----END RSA PRIVATE KEY-----", - key, pwd, pwdlen, &len); + } else { + ret = mbedtls_pem_read_buffer(pem, "-----BEGIN RSA PRIVATE KEY-----", "-----END RSA PRIVATE KEY-----", key, pwd, pwdlen, + &len); } if (ret == 0) { - * pk_type = MBEDTLS_PK_RSA; + *pk_type = MBEDTLS_PK_RSA; return ret; - } - else if (ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH) { + } else if (ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH) { return MBEDTLS_ERR_PK_PASSWORD_MISMATCH; - } - else if (ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED) { + } else if (ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED) { return MBEDTLS_ERR_PK_PASSWORD_REQUIRED; - } - else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { + } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { return ret; } @@ -339,24 +302,18 @@ int ptls_mbedtls_get_der_key(mbedtls_pem_context* pem, /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ if (key[keylen - 1] != '\0') { ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - } - else { - ret = mbedtls_pem_read_buffer(pem, - "-----BEGIN EC PRIVATE KEY-----", - "-----END EC PRIVATE KEY-----", - key, pwd, pwdlen, &len); + } else { + ret = + mbedtls_pem_read_buffer(pem, "-----BEGIN EC PRIVATE KEY-----", "-----END EC PRIVATE KEY-----", key, pwd, pwdlen, &len); } if (ret == 0) { - * pk_type = MBEDTLS_PK_ECKEY; + *pk_type = MBEDTLS_PK_ECKEY; return ret; - } - else if (ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH) { + } else if (ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH) { return MBEDTLS_ERR_PK_PASSWORD_MISMATCH; - } - else if (ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED) { + } else if (ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED) { return MBEDTLS_ERR_PK_PASSWORD_REQUIRED; - } - else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { + } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { return ret; } #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ @@ -364,17 +321,12 @@ int ptls_mbedtls_get_der_key(mbedtls_pem_context* pem, /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ if (key[keylen - 1] != '\0') { ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - } - else { - ret = mbedtls_pem_read_buffer(pem, - "-----BEGIN PRIVATE KEY-----", - "-----END PRIVATE KEY-----", - key, NULL, 0, &len); + } else { + ret = mbedtls_pem_read_buffer(pem, "-----BEGIN PRIVATE KEY-----", "-----END PRIVATE KEY-----", key, NULL, 0, &len); if (ret == 0) { /* info is unknown */ return ret; - } - else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { + } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { return ret; } } @@ -383,18 +335,14 @@ int ptls_mbedtls_get_der_key(mbedtls_pem_context* pem, /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ if (key[keylen - 1] != '\0') { ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - } - else { - ret = mbedtls_pem_read_buffer(pem, - "-----BEGIN ENCRYPTED PRIVATE KEY-----", - "-----END ENCRYPTED PRIVATE KEY-----", - key, NULL, 0, &len); + } else { + ret = mbedtls_pem_read_buffer(pem, "-----BEGIN ENCRYPTED PRIVATE KEY-----", "-----END ENCRYPTED PRIVATE KEY-----", key, + NULL, 0, &len); } if (ret == 0) { /* infor is unknown */ return ret; - } - else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { + } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { return ret; } #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ @@ -402,11 +350,10 @@ int ptls_mbedtls_get_der_key(mbedtls_pem_context* pem, } #endif -const ptls_mbedtls_signature_scheme_t* ptls_mbedtls_select_signature_scheme( - const ptls_mbedtls_signature_scheme_t *available, - const uint16_t *algorithms, size_t num_algorithms) +const ptls_mbedtls_signature_scheme_t *ptls_mbedtls_select_signature_scheme(const ptls_mbedtls_signature_scheme_t *available, + const uint16_t *algorithms, size_t num_algorithms) { - const ptls_mbedtls_signature_scheme_t* scheme; + const ptls_mbedtls_signature_scheme_t *scheme; /* select the algorithm, driven by server-isde preference of `available` */ for (scheme = available; scheme->scheme_id != UINT16_MAX; ++scheme) { @@ -419,8 +366,7 @@ const ptls_mbedtls_signature_scheme_t* ptls_mbedtls_select_signature_scheme( return NULL; } -int ptls_mbedtls_set_available_schemes( - ptls_mbedtls_sign_certificate_t* signer) +int ptls_mbedtls_set_available_schemes(ptls_mbedtls_sign_certificate_t *signer) { int ret = 0; psa_algorithm_t algo = psa_get_key_algorithm(&signer->attributes); @@ -468,55 +414,52 @@ int ptls_mbedtls_set_available_schemes( } /* -* Sign a certificate -* - step1, selected a signature algorithm compatible with the public key algorithm -* and with the list specified by the application. -* - step2, compute the hash with the specified algorithm. -* - step3, compute the signature of the hash using psa_sign_hash. -* -* In the case of RSA, we use the algorithm PSA_ALG_RSA_PKCS1V15_SIGN_RAW, which -* pads the hash according to PKCS1V15 before doing the private key operation. -* The implementation of RSA/PKCS1V15 also includes a verification step to protect -* against key attacks through partial faults. -* -* MBEDTLS has a "psa_sign_message" that combines step2 and step3. However, it -* requires specifying an algorithm type that exactly specifies the signature -* algorithm, such as "RSA with SHA384". This is not compatible with the -* "RSA sign raw" algorithm. Instead, we decompose the operation in two steps. -* There is no performance penalty doing so, as "psa_sign_message" is only -* a convenience API. -*/ - -int ptls_mbedtls_sign_certificate(ptls_sign_certificate_t* _self, ptls_t* tls, - ptls_async_job_t** async, uint16_t* selected_algorithm, - ptls_buffer_t* outbuf, ptls_iovec_t input, const uint16_t* algorithms, size_t num_algorithms) + * Sign a certificate + * - step1, selected a signature algorithm compatible with the public key algorithm + * and with the list specified by the application. + * - step2, compute the hash with the specified algorithm. + * - step3, compute the signature of the hash using psa_sign_hash. + * + * In the case of RSA, we use the algorithm PSA_ALG_RSA_PKCS1V15_SIGN_RAW, which + * pads the hash according to PKCS1V15 before doing the private key operation. + * The implementation of RSA/PKCS1V15 also includes a verification step to protect + * against key attacks through partial faults. + * + * MBEDTLS has a "psa_sign_message" that combines step2 and step3. However, it + * requires specifying an algorithm type that exactly specifies the signature + * algorithm, such as "RSA with SHA384". This is not compatible with the + * "RSA sign raw" algorithm. Instead, we decompose the operation in two steps. + * There is no performance penalty doing so, as "psa_sign_message" is only + * a convenience API. + */ + +int ptls_mbedtls_sign_certificate(ptls_sign_certificate_t *_self, ptls_t *tls, ptls_async_job_t **async, + uint16_t *selected_algorithm, ptls_buffer_t *outbuf, ptls_iovec_t input, + const uint16_t *algorithms, size_t num_algorithms) { int ret = 0; - ptls_mbedtls_sign_certificate_t* self = (ptls_mbedtls_sign_certificate_t*) - (((unsigned char*)_self) - offsetof(struct st_ptls_mbedtls_sign_certificate_t, super)); + ptls_mbedtls_sign_certificate_t *self = + (ptls_mbedtls_sign_certificate_t *)(((unsigned char *)_self) - offsetof(struct st_ptls_mbedtls_sign_certificate_t, super)); /* First, find the set of compatible algorithms */ - const ptls_mbedtls_signature_scheme_t* scheme = - ptls_mbedtls_select_signature_scheme(self->schemes, algorithms, num_algorithms); + const ptls_mbedtls_signature_scheme_t *scheme = ptls_mbedtls_select_signature_scheme(self->schemes, algorithms, num_algorithms); if (scheme == NULL) { ret = PTLS_ERROR_INCOMPATIBLE_KEY; - } - else { + } else { /* First prepare the hash */ unsigned char hash_buffer[PTLS_MAX_DIGEST_SIZE]; - unsigned char* hash_value = NULL; + unsigned char *hash_value = NULL; size_t hash_length = 0; if (scheme->hash_algo == PSA_ALG_NONE) { hash_value = input.base; hash_length = input.len; - } - else { - if (psa_hash_compute(scheme->hash_algo, input.base, input.len, hash_buffer, PTLS_MAX_DIGEST_SIZE, &hash_length) != PSA_SUCCESS) { + } else { + if (psa_hash_compute(scheme->hash_algo, input.base, input.len, hash_buffer, PTLS_MAX_DIGEST_SIZE, &hash_length) != + PSA_SUCCESS) { ret = PTLS_ERROR_NOT_AVAILABLE; - } - else { + } else { hash_value = hash_buffer; } } @@ -528,8 +471,7 @@ int ptls_mbedtls_sign_certificate(ptls_sign_certificate_t* _self, ptls_t* tls, if (sign_algo == PSA_ALG_RSA_PKCS1V15_SIGN_RAW) { /* assume at most 4096 bit key */ nb_bytes = 512; - } - else { + } else { /* Max size assumed, secp521r1 */ nb_bytes = 124; } @@ -538,11 +480,10 @@ int ptls_mbedtls_sign_certificate(ptls_sign_certificate_t* _self, ptls_t* tls, } if ((ret = ptls_buffer_reserve(outbuf, nb_bytes)) == 0) { size_t signature_length = 0; - if (psa_sign_hash(self->key_id, sign_algo, hash_value, hash_length, - outbuf->base + outbuf->off, nb_bytes, &signature_length) != 0) { + if (psa_sign_hash(self->key_id, sign_algo, hash_value, hash_length, outbuf->base + outbuf->off, nb_bytes, + &signature_length) != 0) { ret = PTLS_ERROR_INCOMPATIBLE_KEY; - } - else { + } else { outbuf->off += signature_length; } } @@ -554,8 +495,9 @@ int ptls_mbedtls_sign_certificate(ptls_sign_certificate_t* _self, ptls_t* tls, void ptls_mbedtls_dispose_sign_certificate(ptls_sign_certificate_t *_self) { if (_self != NULL) { - ptls_mbedtls_sign_certificate_t* self = (ptls_mbedtls_sign_certificate_t*) - (((unsigned char*)_self) - offsetof(struct st_ptls_mbedtls_sign_certificate_t, super)); + ptls_mbedtls_sign_certificate_t *self = + (ptls_mbedtls_sign_certificate_t *)(((unsigned char *)_self) - + offsetof(struct st_ptls_mbedtls_sign_certificate_t, super)); /* Destroy the key */ psa_destroy_key(self->key_id); psa_reset_key_attributes(&self->attributes); @@ -564,24 +506,24 @@ void ptls_mbedtls_dispose_sign_certificate(ptls_sign_certificate_t *_self) } } /* -* An RSa key is encoded in DER as: -* RSAPrivateKey ::= SEQUENCE { -* version INTEGER, -- must be 0 -* modulus INTEGER, -- n -* publicExponent INTEGER, -- e -* privateExponent INTEGER, -- d -* prime1 INTEGER, -- p -* prime2 INTEGER, -- q -* exponent1 INTEGER, -- d mod (p-1) -* exponent2 INTEGER, -- d mod (q-1) -* coefficient INTEGER, -- (inverse of q) mod p -* } -* -* The number of key bits is the size in bits of the integer N. -* We must decode the length in octets of the integer representation, -* then subtract the number of zeros at the beginning of the data. -*/ -int ptls_mbedtls_rsa_get_key_bits(const unsigned char* key_value, size_t key_length, size_t * p_nb_bits) + * An RSa key is encoded in DER as: + * RSAPrivateKey ::= SEQUENCE { + * version INTEGER, -- must be 0 + * modulus INTEGER, -- n + * publicExponent INTEGER, -- e + * privateExponent INTEGER, -- d + * prime1 INTEGER, -- p + * prime2 INTEGER, -- q + * exponent1 INTEGER, -- d mod (p-1) + * exponent2 INTEGER, -- d mod (q-1) + * coefficient INTEGER, -- (inverse of q) mod p + * } + * + * The number of key bits is the size in bits of the integer N. + * We must decode the length in octets of the integer representation, + * then subtract the number of zeros at the beginning of the data. + */ +int ptls_mbedtls_rsa_get_key_bits(const unsigned char *key_value, size_t key_length, size_t *p_nb_bits) { int ret = 0; size_t nb_bytes = 0; @@ -598,15 +540,10 @@ int ptls_mbedtls_rsa_get_key_bits(const unsigned char* key_value, size_t key_len } } - if (ret == 0 && - key_value[x] == 0x02 && - key_value[x + 1] == 0x01 && - key_value[x + 2] == 0x00 && - key_value[x + 3] == 0x02) { + if (ret == 0 && key_value[x] == 0x02 && key_value[x + 1] == 0x01 && key_value[x + 2] == 0x00 && key_value[x + 3] == 0x02) { x += 4; ret = ptls_mbedtls_parse_der_length(key_value, key_length, &x, &nb_bytes); - } - else { + } else { ret = -1; } @@ -616,8 +553,7 @@ int ptls_mbedtls_rsa_get_key_bits(const unsigned char* key_value, size_t key_len if (v == 0) { nb_bits -= 8; - } - else { + } else { while ((v & 0x80) == 0) { nb_bits--; v <<= 1; @@ -628,8 +564,7 @@ int ptls_mbedtls_rsa_get_key_bits(const unsigned char* key_value, size_t key_len return ret; } -void ptls_mbedtls_set_rsa_key_attributes(ptls_mbedtls_sign_certificate_t* signer, - const unsigned char * key_value, size_t key_length) +void ptls_mbedtls_set_rsa_key_attributes(ptls_mbedtls_sign_certificate_t *signer, const unsigned char *key_value, size_t key_length) { size_t nb_bits = 0; psa_set_key_usage_flags(&signer->attributes, PSA_KEY_USAGE_SIGN_HASH); @@ -640,7 +575,7 @@ void ptls_mbedtls_set_rsa_key_attributes(ptls_mbedtls_sign_certificate_t* signer } } -int ptls_mbedtls_set_ec_key_attributes(ptls_mbedtls_sign_certificate_t* signer, size_t key_length) +int ptls_mbedtls_set_ec_key_attributes(ptls_mbedtls_sign_certificate_t *signer, size_t key_length) { int ret = 0; @@ -648,51 +583,44 @@ int ptls_mbedtls_set_ec_key_attributes(ptls_mbedtls_sign_certificate_t* signer, psa_set_key_algorithm(&signer->attributes, PSA_ALG_ECDSA_BASE); psa_set_key_type(&signer->attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); if (key_length == 32) { - psa_set_key_algorithm(&signer->attributes, - PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)); + psa_set_key_algorithm(&signer->attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)); psa_set_key_bits(&signer->attributes, 256); - } - else if (key_length == 48) { - psa_set_key_algorithm(&signer->attributes, - PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_384)); + } else if (key_length == 48) { + psa_set_key_algorithm(&signer->attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_384)); psa_set_key_bits(&signer->attributes, 384); - } - else if (key_length == 66) { - psa_set_key_algorithm(&signer->attributes, - PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_512)); + } else if (key_length == 66) { + psa_set_key_algorithm(&signer->attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_512)); psa_set_key_bits(&signer->attributes, 521); - } - else { + } else { ret = -1; } return ret; } -int ptls_mbedtls_load_private_key(ptls_context_t* ctx, char const* pem_fname) +int ptls_mbedtls_load_private_key(ptls_context_t *ctx, char const *pem_fname) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t n; - unsigned char* buf; - mbedtls_pem_context pem = { 0 }; + unsigned char *buf; + mbedtls_pem_context pem = {0}; mbedtls_pk_type_t pk_type = 0; /* mbedtls_svc_key_id_t key_id = 0; */ size_t key_length = 0; size_t key_index = 0; - ptls_mbedtls_sign_certificate_t* signer = (ptls_mbedtls_sign_certificate_t*)malloc(sizeof(ptls_mbedtls_sign_certificate_t)); + ptls_mbedtls_sign_certificate_t *signer = (ptls_mbedtls_sign_certificate_t *)malloc(sizeof(ptls_mbedtls_sign_certificate_t)); if (signer == NULL) { - return(PTLS_ERROR_NO_MEMORY); + return (PTLS_ERROR_NO_MEMORY); } memset(signer, 0, sizeof(ptls_mbedtls_sign_certificate_t)); signer->attributes = psa_key_attributes_init(); if ((ret = mbedtls_pk_load_file(pem_fname, &buf, &n)) != 0) { if (ret == MBEDTLS_ERR_PK_ALLOC_FAILED) { - return(PTLS_ERROR_NO_MEMORY); - } - else { - return(PTLS_ERROR_NOT_AVAILABLE); + return (PTLS_ERROR_NO_MEMORY); + } else { + return (PTLS_ERROR_NOT_AVAILABLE); } } ret = ptls_mbedtls_get_der_key(&pem, &pk_type, buf, n, NULL, 0, NULL, NULL); @@ -708,21 +636,20 @@ int ptls_mbedtls_load_private_key(ptls_context_t* ctx, char const* pem_fname) if (pk_type == MBEDTLS_PK_RSA) { key_length = pem.private_buflen; ptls_mbedtls_set_rsa_key_attributes(signer, pem.private_buf, key_length); - } - else if (pk_type == MBEDTLS_PK_ECKEY) { + } else if (pk_type == MBEDTLS_PK_ECKEY) { ret = ptls_mbedtls_parse_ecdsa_field(pem.private_buf, pem.private_buflen, &key_index, &key_length); if (ret == 0) { ret = ptls_mbedtls_set_ec_key_attributes(signer, key_length); } - } - else if (pk_type == MBEDTLS_PK_NONE) { + } else if (pk_type == MBEDTLS_PK_NONE) { /* TODO: not clear whether MBDED TLS supports ED25519 yet. Probably not. */ /* Should have option to encode RSA or ECDSA using PKCS8 */ size_t oid_index = 0; size_t oid_length = 0; psa_set_key_usage_flags(&signer->attributes, PSA_KEY_USAGE_SIGN_HASH); - ret = test_parse_private_key_field(pem.private_buf, pem.private_buflen, &oid_index, &oid_length, &key_index, &key_length); + ret = + test_parse_private_key_field(pem.private_buf, pem.private_buflen, &oid_index, &oid_length, &key_index, &key_length); if (ret == 0) { /* need to parse the OID in order to set the parameters */ @@ -732,27 +659,23 @@ int ptls_mbedtls_load_private_key(ptls_context_t* ctx, char const* pem_fname) if (ret == 0) { ret = ptls_mbedtls_set_ec_key_attributes(signer, key_length); } - } - else if (oid_length == sizeof(ptls_mbedtls_oid_ed25519) && - memcmp(pem.private_buf + oid_index, ptls_mbedtls_oid_ed25519, sizeof(ptls_mbedtls_oid_ed25519)) == 0) { + } else if (oid_length == sizeof(ptls_mbedtls_oid_ed25519) && + memcmp(pem.private_buf + oid_index, ptls_mbedtls_oid_ed25519, sizeof(ptls_mbedtls_oid_ed25519)) == 0) { /* We recognized ED25519 -- PSA_ECC_FAMILY_TWISTED_EDWARDS -- PSA_ALG_ED25519PH */ psa_set_key_algorithm(&signer->attributes, PSA_ALG_PURE_EDDSA); psa_set_key_type(&signer->attributes, PSA_ECC_FAMILY_TWISTED_EDWARDS); ret = ptls_mbedtls_parse_eddsa_key(pem.private_buf, pem.private_buflen, &key_index, &key_length); psa_set_key_bits(&signer->attributes, 256); - } - else if (oid_length == sizeof(ptls_mbedtls_oid_rsa_key) && - memcmp(pem.private_buf + oid_index, ptls_mbedtls_oid_rsa_key, sizeof(ptls_mbedtls_oid_rsa_key)) == 0) { + } else if (oid_length == sizeof(ptls_mbedtls_oid_rsa_key) && + memcmp(pem.private_buf + oid_index, ptls_mbedtls_oid_rsa_key, sizeof(ptls_mbedtls_oid_rsa_key)) == 0) { /* We recognized RSA */ key_length = pem.private_buflen; ptls_mbedtls_set_rsa_key_attributes(signer, pem.private_buf, key_length); - } - else { + } else { ret = PTLS_ERROR_NOT_AVAILABLE; } } - } - else { + } else { ret = -1; } @@ -762,8 +685,7 @@ int ptls_mbedtls_load_private_key(ptls_context_t* ctx, char const* pem_fname) if (status != PSA_SUCCESS) { ret = -1; - } - else { + } else { ret = ptls_mbedtls_set_available_schemes(signer); } } diff --git a/t/mbedtls.c b/t/mbedtls.c index 8cbe0a979..1ea3416bf 100644 --- a/t/mbedtls.c +++ b/t/mbedtls.c @@ -43,12 +43,12 @@ typedef struct st_ptls_mbedtls_sign_certificate_t { ptls_sign_certificate_t super; mbedtls_svc_key_id_t key_id; psa_key_attributes_t attributes; - const ptls_mbedtls_signature_scheme_t * schemes; + const ptls_mbedtls_signature_scheme_t *schemes; } ptls_mbedtls_sign_certificate_t; -int ptls_mbedtls_sign_certificate(ptls_sign_certificate_t* _self, ptls_t* tls, - ptls_async_job_t** async, uint16_t* selected_algorithm, - ptls_buffer_t* outbuf, ptls_iovec_t input, const uint16_t* algorithms, size_t num_algorithms); +int ptls_mbedtls_sign_certificate(ptls_sign_certificate_t *_self, ptls_t *tls, ptls_async_job_t **async, + uint16_t *selected_algorithm, ptls_buffer_t *outbuf, ptls_iovec_t input, + const uint16_t *algorithms, size_t num_algorithms); static int random_trial() { @@ -134,36 +134,31 @@ Output buffer is already partially filled. #define ASSET_SECP521R1_KEY "t/assets/secp521r1/key.pem" #define ASSET_SECP256R1_PKCS8_KEY "t/assets/secp256r1-pkcs8/key.pem" -int test_load_one_der_key(char const* path) +int test_load_one_der_key(char const *path) { int ret = -1; unsigned char hash[32]; - const unsigned char h0[32] = { - 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32 - }; - ptls_context_t ctx = { 0 }; + const unsigned char h0[32] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}; + ptls_context_t ctx = {0}; ret = ptls_mbedtls_load_private_key(&ctx, path); if (ret != 0) { printf("Cannot create sign_certificate from: %s\n", path); ret = -1; - } - else if (ctx.sign_certificate == NULL) { + } else if (ctx.sign_certificate == NULL) { printf("Sign_certificate not set in ptls context for: %s\n", path); ret = -1; - } - else { + } else { /* Try to sign something */ int ret; - ptls_mbedtls_sign_certificate_t* signer = (ptls_mbedtls_sign_certificate_t*) - (((unsigned char*)ctx.sign_certificate) - offsetof(struct st_ptls_mbedtls_sign_certificate_t, super)); + ptls_mbedtls_sign_certificate_t *signer = + (ptls_mbedtls_sign_certificate_t *)(((unsigned char *)ctx.sign_certificate) - + offsetof(struct st_ptls_mbedtls_sign_certificate_t, super)); /* get the key algorithm */ ptls_buffer_t outbuf; uint8_t outbuf_smallbuf[256]; - ptls_iovec_t input = { hash, sizeof(hash) }; + ptls_iovec_t input = {hash, sizeof(hash)}; uint16_t selected_algorithm = 0; int num_algorithms = 0; uint16_t algorithms[16]; @@ -175,12 +170,11 @@ int test_load_one_der_key(char const* path) ptls_buffer_init(&outbuf, outbuf_smallbuf, sizeof(outbuf_smallbuf)); - ret = ptls_mbedtls_sign_certificate(ctx.sign_certificate, NULL, NULL, &selected_algorithm, - &outbuf, input, algorithms, num_algorithms); + ret = ptls_mbedtls_sign_certificate(ctx.sign_certificate, NULL, NULL, &selected_algorithm, &outbuf, input, algorithms, + num_algorithms); if (ret == 0) { printf("Signed a message, key: %s, scheme: %x, signature size: %zu\n", path, selected_algorithm, outbuf.off); - } - else { + } else { printf("Sign failed, key: %s, scheme: %x, signature size: %zu\n", path, selected_algorithm, outbuf.off); } ptls_buffer_dispose(&outbuf); @@ -189,10 +183,10 @@ int test_load_one_der_key(char const* path) return ret; } -static void test_load_rsa_key() +static void test_load_rsa_key() { int ret = test_load_one_der_key(ASSET_RSA_KEY); - + if (ret != 0) { ok(!"fail"); return; @@ -209,9 +203,9 @@ static void test_load_secp256r1_key() } ok(!!"success"); } - + static void test_load_secp384r1_key() -{ +{ int ret = test_load_one_der_key(ASSET_SECP384R1_KEY); if (ret != 0) { ok(!"fail"); @@ -220,11 +214,10 @@ static void test_load_secp384r1_key() ok(!!"success"); } - static void test_load_secp521r1_key() -{ +{ int ret = test_load_one_der_key(ASSET_SECP521R1_KEY); - if (ret != 0) { + if (ret != 0) { ok(!"fail"); return; } @@ -234,12 +227,12 @@ static void test_load_secp521r1_key() static void test_load_secp256r1_pkcs8_key() { int ret = test_load_one_der_key(ASSET_SECP256R1_PKCS8_KEY); - if (ret != 0) { + if (ret != 0) { ok(!"fail"); return; } ok(!!"success"); -} +} static void test_load_rsa_pkcs8_key() { @@ -252,7 +245,7 @@ static void test_load_rsa_pkcs8_key() } void test_sign_certificate(void) -{ +{ subtest("load rsa key", test_load_rsa_key); subtest("load secp256r1 key", test_load_secp256r1_key); subtest("load secp384r1 key", test_load_secp384r1_key); @@ -294,7 +287,7 @@ int main(int argc, char **argv) .sign_certificate = &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 */ + * 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)); @@ -319,7 +312,7 @@ int main(int argc, char **argv) /* test the sign certificate */ subtest("sign certificate", test_sign_certificate); - + /* Deinitialize the PSA crypto library. */ mbedtls_psa_crypto_free();