/* * Embedded Linux library * * Copyright (C) 2018 Intel Corporation. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include #endif #define _GNU_SOURCE #include #include #include #include #include "util.h" #include "tls.h" #include "cipher.h" #include "checksum.h" #include "cert.h" #include "tls-private.h" #include "key.h" #include "random.h" #include "ecc.h" #include "ecdh.h" #include "missing.h" static bool tls_rsa_validate_cert_key(struct l_cert *cert) { return l_cert_get_pubkey_type(cert) == L_CERT_KEY_RSA; } static ssize_t tls_rsa_sign(struct l_tls *tls, uint8_t *out, size_t out_len, tls_get_hash_t get_hash, const uint8_t *data, size_t data_len) { ssize_t result = -EMSGSIZE; enum l_checksum_type sign_checksum_type; uint8_t sign_input[HANDSHAKE_HASH_MAX_SIZE + 36]; size_t sign_input_len; uint8_t *ptr = out; if (!tls->priv_key || !tls->priv_key_size) { TLS_DISCONNECT(TLS_ALERT_INTERNAL_ERROR, TLS_ALERT_BAD_CERT, "No private key loaded"); return -ENOKEY; } if (tls->negotiated_version >= L_TLS_V12) { const struct tls_hash_algorithm *hash_type = &tls_handshake_hash_data[tls->signature_hash]; /* Build the DigitallySigned struct */ if (out_len < 2) /* Is there space for the algorithm IDs */ goto error; get_hash(tls, tls->signature_hash, data, data_len, sign_input, &sign_input_len); sign_checksum_type = hash_type->l_id; *ptr++ = hash_type->tls_id; *ptr++ = 1; /* RSA_sign */ out_len -= 2; } else { get_hash(tls, HANDSHAKE_HASH_MD5, data, data_len, sign_input + 0, NULL); get_hash(tls, HANDSHAKE_HASH_SHA1, data, data_len, sign_input + 16, NULL); sign_checksum_type = L_CHECKSUM_NONE; sign_input_len = 36; } if (out_len < tls->priv_key_size + 2) goto error; l_put_be16(tls->priv_key_size, ptr); result = l_key_sign(tls->priv_key, L_KEY_RSA_PKCS1_V1_5, sign_checksum_type, sign_input, ptr + 2, sign_input_len, tls->priv_key_size); ptr += tls->priv_key_size + 2; if (result == (ssize_t) tls->priv_key_size) return ptr - out; /* Success */ error: TLS_DISCONNECT(TLS_ALERT_INTERNAL_ERROR, 0, "Signing the hash failed: %s", strerror(-result)); return result; } static bool tls_rsa_verify(struct l_tls *tls, const uint8_t *in, size_t in_len, tls_get_hash_t get_hash, const uint8_t *data, size_t data_len) { enum l_checksum_type sign_checksum_type; uint8_t expected[HANDSHAKE_HASH_MAX_SIZE + 36]; size_t expected_len; unsigned int offset; bool success; /* 2 bytes for SignatureAndHashAlgorithm if version >= 1.2 */ offset = 2; if (tls->negotiated_version < L_TLS_V12) offset = 0; if (in_len < offset + 2 || (size_t) l_get_be16(in + offset) + offset + 2 != in_len) { TLS_DISCONNECT(TLS_ALERT_DECODE_ERROR, 0, "Signature msg too " "short (%zi) or signature length doesn't match", in_len); return false; } /* Only the default hash type supported */ if (in_len != offset + 2 + tls->peer_pubkey_size) { TLS_DISCONNECT(TLS_ALERT_DECODE_ERROR, 0, "Signature length %zi not equal %zi", in_len, offset + 2 + tls->peer_pubkey_size); return false; } if (tls->negotiated_version >= L_TLS_V12) { enum handshake_hash_type hash; /* Only RSA supported */ if (in[1] != 1 /* RSA_sign */) { TLS_DISCONNECT(TLS_ALERT_DECRYPT_ERROR, 0, "Unknown signature algorithm %i", in[1]); return false; } for (hash = 0; hash < __HANDSHAKE_HASH_COUNT; hash++) if (tls_handshake_hash_data[hash].tls_id == in[0]) break; if (hash == __HANDSHAKE_HASH_COUNT) { TLS_DISCONNECT(TLS_ALERT_DECRYPT_ERROR, 0, "Unknown hash type %i", in[0]); return false; } get_hash(tls, hash, data, data_len, expected, &expected_len); sign_checksum_type = tls_handshake_hash_data[hash].l_id; /* * Note: Next we let the l_key_verify's underlying kernel * operation prepend the OID to the hash to build the * DigestInfo struct. However according to 4.7 we need to * support at least two forms of the signed content in the * verification: * - DigestInfo with NULL AlgorithmIdentifier.parameters, * - DigestInfo with empty AlgorithmIdentifier.parameters, * * while the kernel only understands the former encoding. * Note PKCS#1 versions 2.0 and later section A.2.4 do * mandate NULL AlgorithmIdentifier.parameters. * * Additionally PKCS#1 v1.5 said BER is used in place of DER * for DigestInfo encoding which adds more ambiguity in the * encoding. */ } else { get_hash(tls, HANDSHAKE_HASH_MD5, data, data_len, expected + 0, NULL); get_hash(tls, HANDSHAKE_HASH_SHA1, data, data_len, expected + 16, NULL); expected_len = 36; sign_checksum_type = L_CHECKSUM_NONE; /* * Note: Within the RSA padding for signatures PKCS#1 1.5 * allows the block format to be either 0 or 1, while PKCS#1 * v2.0+ mandates block type 1 making the signatures * unambiguous. TLS 1.0 doesn't additionally specify which * block type is to be used (TLS 1.2 does) meaning that both * PKCS#1 v1.5 types are allowed. The l_key_verify's * underlying kernel implementation only accepts block type * 1. If this ever becomes an issue we'd need to go back to * using L_KEY_RSA_RAW and our own PKCS#1 v1.5 verify logic. */ } success = l_key_verify(tls->peer_pubkey, L_KEY_RSA_PKCS1_V1_5, sign_checksum_type, expected, in + offset + 2, expected_len, tls->peer_pubkey_size); if (!success) TLS_DISCONNECT(TLS_ALERT_DECRYPT_ERROR, 0, "Peer signature verification failed"); else TLS_DEBUG("Peer signature verified"); return success; } static struct tls_signature_algorithm tls_rsa_signature = { .id = 1, /* SignatureAlgorithm.rsa */ .validate_cert_key_type = tls_rsa_validate_cert_key, .sign = tls_rsa_sign, .verify = tls_rsa_verify, }; static bool tls_send_rsa_client_key_xchg(struct l_tls *tls) { uint8_t buf[1024 + 32]; uint8_t *ptr = buf + TLS_HANDSHAKE_HEADER_SIZE; uint8_t pre_master_secret[48]; ssize_t bytes_encrypted; if (!tls->peer_pubkey) { TLS_DISCONNECT(TLS_ALERT_INTERNAL_ERROR, 0, "Peer public key not received"); return false; } /* Must match the version in tls_send_client_hello */ pre_master_secret[0] = (uint8_t) (tls->max_version >> 8); pre_master_secret[1] = (uint8_t) (tls->max_version >> 0); l_getrandom(pre_master_secret + 2, 46); if (tls->peer_pubkey_size + 32 > (int) sizeof(buf)) { TLS_DISCONNECT(TLS_ALERT_INTERNAL_ERROR, 0, "Peer public key too big: %zi", tls->peer_pubkey_size); return false; } l_put_be16(tls->peer_pubkey_size, ptr); bytes_encrypted = l_key_encrypt(tls->peer_pubkey, L_KEY_RSA_PKCS1_V1_5, L_CHECKSUM_NONE, pre_master_secret, ptr + 2, 48, tls->peer_pubkey_size); ptr += tls->peer_pubkey_size + 2; if (bytes_encrypted != (ssize_t) tls->peer_pubkey_size) { TLS_DISCONNECT(TLS_ALERT_INTERNAL_ERROR, 0, "Encrypting PreMasterSecret failed: %s", strerror(-bytes_encrypted)); return false; } tls_tx_handshake(tls, TLS_CLIENT_KEY_EXCHANGE, buf, ptr - buf); tls_generate_master_secret(tls, pre_master_secret, 48); explicit_bzero(pre_master_secret, 48); return true; } static void tls_handle_rsa_client_key_xchg(struct l_tls *tls, const uint8_t *buf, size_t len) { uint8_t pre_master_secret[48], random_secret[46]; ssize_t bytes_decrypted; if (!tls->priv_key || !tls->priv_key_size) { TLS_DISCONNECT(TLS_ALERT_INTERNAL_ERROR, TLS_ALERT_BAD_CERT, "No private key"); return; } if (len != tls->priv_key_size + 2) { TLS_DISCONNECT(TLS_ALERT_DECODE_ERROR, 0, "ClientKeyExchange len %zi not %zi", len, tls->priv_key_size + 2); return; } len = l_get_be16(buf); if (len != tls->priv_key_size) { TLS_DISCONNECT(TLS_ALERT_DECODE_ERROR, 0, "EncryptedPreMasterSecret len %zi not %zi", len, tls->priv_key_size); return; } bytes_decrypted = l_key_decrypt(tls->priv_key, L_KEY_RSA_PKCS1_V1_5, L_CHECKSUM_NONE, buf + 2, pre_master_secret, tls->priv_key_size, 48); /* * Assume correct premaster secret client version which according * to the TLS1.2 spec is unlikely in client implementations SSLv3 * and prior. Spec suggests either not supporting them or adding * a configurable override for <= SSLv3 clients. For now we have * no need to support them. * * On any decode error randomise the Pre Master Secret as per the * countermeasures in 7.4.7.1 and don't generate any alerts. */ l_getrandom(random_secret, 46); pre_master_secret[0] = tls->client_version >> 8; pre_master_secret[1] = tls->client_version >> 0; if (bytes_decrypted != 48) { memcpy(pre_master_secret + 2, random_secret, 46); TLS_DEBUG("Error decrypting PreMasterSecret: %s", strerror(-bytes_decrypted)); } tls_generate_master_secret(tls, pre_master_secret, 48); explicit_bzero(pre_master_secret, 48); explicit_bzero(random_secret, 46); } static struct tls_key_exchange_algorithm tls_rsa_key_xchg = { .send_client_key_exchange = tls_send_rsa_client_key_xchg, .handle_client_key_exchange = tls_handle_rsa_client_key_xchg, }; /* Used by both DHE and ECDHE */ static bool tls_get_dh_params_hash(struct l_tls *tls, enum handshake_hash_type type, const uint8_t *data, size_t data_len, uint8_t *out, size_t *out_len) { struct l_checksum *checksum; ssize_t ret; /* * The ServerKeyExchange signature hash input format for RSA_sign is * not really specified in either RFC 8422 or RFC 5246 explicitly * but we use this format by analogy to DHE_RSA which uses RSA_sign * as well. Also matches ecdsa, ed25519 and ed448 formats. */ struct iovec iov[] = { { .iov_base = tls->pending.client_random, .iov_len = 32 }, { .iov_base = tls->pending.server_random, .iov_len = 32 }, { .iov_base = (void *) data, .iov_len = data_len }, }; checksum = l_checksum_new(tls_handshake_hash_data[type].l_id); if (!checksum) return false; l_checksum_updatev(checksum, iov, L_ARRAY_SIZE(iov)); ret = l_checksum_get_digest(checksum, out, HANDSHAKE_HASH_MAX_SIZE); l_checksum_free(checksum); if (ret < 0) return false; if (out_len) *out_len = ret; return true; } struct tls_ecdhe_params { const struct l_ecc_curve *curve; struct l_ecc_scalar *private; struct l_ecc_point *public; }; static void tls_free_ecdhe_params(struct l_tls *tls) { struct tls_ecdhe_params *params = tls->pending.key_xchg_params; if (!params) return; tls->pending.key_xchg_params = NULL; l_ecc_scalar_free(params->private); l_ecc_point_free(params->public); l_free(params); } static size_t tls_write_ecpoint(uint8_t *buf, size_t len, const struct tls_named_group *curve, const struct l_ecc_point *point) { size_t point_bytes; /* RFC 8422, Section 5.4.1 */ point_bytes = l_ecc_point_get_data(point, buf + 2, len - 2); buf[0] = 1 + point_bytes; /* length */ buf[1] = 4; /* form: uncompressed */ return 2 + point_bytes; } static size_t tls_write_server_ecdh_params(struct l_tls *tls, uint8_t *buf, size_t len) { struct tls_ecdhe_params *params = tls->pending.key_xchg_params; /* RFC 8422, Section 5.4 */ buf[0] = 3; /* curve_type: named_curve */ l_put_be16(tls->negotiated_curve->id, buf + 1); return 3 + tls_write_ecpoint(buf + 3, len - 3, tls->negotiated_curve, params->public); } static bool tls_send_ecdhe_server_key_xchg(struct l_tls *tls) { uint8_t buf[1024]; uint8_t *ptr = buf + TLS_HANDSHAKE_HEADER_SIZE; struct tls_ecdhe_params *params; ssize_t sign_len; const uint8_t *server_ecdh_params_ptr; /* * RFC 8422, Section 5.4 * * If we're getting here we can assume that tls->pending.key_xchg_params * is NULL, tls->priv_key is our signing key and tls->negotiated_curve * is non-NULL. */ params = l_new(struct tls_ecdhe_params, 1); params->curve = l_ecc_curve_get_tls_group(tls->negotiated_curve->id); tls->pending.key_xchg_params = params; if (!l_ecdh_generate_key_pair(params->curve, ¶ms->private, ¶ms->public)) { TLS_DISCONNECT(TLS_ALERT_INTERNAL_ERROR, 0, "Generating ECDH key pair failed"); return false; } server_ecdh_params_ptr = ptr; ptr += tls_write_server_ecdh_params(tls, ptr, buf + sizeof(buf) - ptr); if (tls->pending.cipher_suite->signature) { sign_len = tls->pending.cipher_suite->signature->sign(tls, ptr, buf + sizeof(buf) - ptr, tls_get_dh_params_hash, server_ecdh_params_ptr, ptr - server_ecdh_params_ptr); if (sign_len < 0) return false; ptr += sign_len; } tls_tx_handshake(tls, TLS_SERVER_KEY_EXCHANGE, buf, ptr - buf); return true; } static void tls_handle_ecdhe_server_key_xchg(struct l_tls *tls, const uint8_t *buf, size_t len) { struct tls_ecdhe_params *params; uint16_t namedcurve; const uint8_t *server_ecdh_params_ptr = buf; size_t point_bytes; /* RFC 8422, Section 5.4 */ if (len < 5) goto decode_error; if (*buf != 3) { TLS_DISCONNECT(TLS_ALERT_ILLEGAL_PARAM, 0, "Unsupported (deprecated?) ECCurveType %u", *buf); return; } namedcurve = l_get_be16(buf + 1); buf += 3; len -= 3; tls->negotiated_curve = tls_find_group(namedcurve); if (!tls->negotiated_curve || tls->negotiated_curve->type != TLS_GROUP_TYPE_EC) { TLS_DISCONNECT(TLS_ALERT_ILLEGAL_PARAM, 0, "Unsupported NamedCurve %u", namedcurve); return; } TLS_DEBUG("Negotiated %s", tls->negotiated_curve->name); if (*buf < 1) goto decode_error; point_bytes = *buf++ - 1; if (*buf != 4) { /* uncompressed */ TLS_DISCONNECT(TLS_ALERT_ILLEGAL_PARAM, 0, "Unsupported (deprecated?) PointConversionForm " "%u", *buf); return; } buf++; len -= 2; if (len < point_bytes) goto decode_error; /* * RFC 8422, Section 5.11: "A receiving party MUST check that the * x and y parameters from the peer's public value satisfy the * curve equation, y^2 = x^3 + ax + b mod p." * This happens in l_ecc_point_from_data when the L_ECC_POINT_TYPE_FULL * format is used. */ params = l_new(struct tls_ecdhe_params, 1); params->curve = l_ecc_curve_get_tls_group(tls->negotiated_curve->id); params->public = l_ecc_point_from_data(params->curve, L_ECC_POINT_TYPE_FULL, buf, len); tls->pending.key_xchg_params = params; buf += point_bytes; len -= point_bytes; if (!params->public || point_bytes != 2 * l_ecc_curve_get_scalar_bytes(params->curve)) { TLS_DISCONNECT(TLS_ALERT_DECODE_ERROR, 0, "ServerKeyExchange.params.public decode error"); return; } if (tls->pending.cipher_suite->signature) { if (!tls->pending.cipher_suite->signature->verify(tls, buf, len, tls_get_dh_params_hash, server_ecdh_params_ptr, buf - server_ecdh_params_ptr)) return; } else { if (len) goto decode_error; } TLS_SET_STATE(TLS_HANDSHAKE_WAIT_HELLO_DONE); return; decode_error: TLS_DISCONNECT(TLS_ALERT_DECODE_ERROR, 0, "ServerKeyExchange decode error"); } static bool tls_send_ecdhe_client_key_xchg(struct l_tls *tls) { uint8_t buf[1024]; uint8_t *ptr = buf + TLS_HANDSHAKE_HEADER_SIZE; uint8_t pre_master_secret[128]; ssize_t pre_master_secret_len; struct tls_ecdhe_params *params = tls->pending.key_xchg_params; struct l_ecc_point *our_public; struct l_ecc_scalar *secret; /* RFC 8422, Section 5.7 */ if (!l_ecdh_generate_key_pair(params->curve, ¶ms->private, &our_public)) { TLS_DISCONNECT(TLS_ALERT_INTERNAL_ERROR, 0, "Generating ECDH key pair failed"); return false; } ptr += tls_write_ecpoint(ptr, buf + sizeof(buf) - ptr, tls->negotiated_curve, our_public); l_ecc_point_free(our_public); /* * Neither 5.4 or 5.7 "Actions" paragraphs say when the ECDH shared * secret is calculated but we can either do this in * tls_handle_ecdhe_server_key_xchg or here. In both cases we only * need to store the public key in the client's key_xchg_params and * can free all of the params after sending the ClientKeyExchange. * By doing this calculation here we're aligned with RSA and also * with the server mode where the shared secret can only be * calculated after the ClientKeyExchange is received. */ if (!l_ecdh_generate_shared_secret(params->private, params->public, &secret)) { TLS_DISCONNECT(TLS_ALERT_INTERNAL_ERROR, 0, "Generating ECDH shared-secret failed"); return false; } tls_free_ecdhe_params(tls); pre_master_secret_len = l_ecc_scalar_get_data(secret, pre_master_secret, sizeof(pre_master_secret)); l_ecc_scalar_free(secret); if (pre_master_secret_len < 0) { TLS_DISCONNECT(TLS_ALERT_INTERNAL_ERROR, 0, "l_ecc_scalar_get_data(secret) failed"); return false; } tls_tx_handshake(tls, TLS_CLIENT_KEY_EXCHANGE, buf, ptr - buf); tls_generate_master_secret(tls, pre_master_secret, pre_master_secret_len); explicit_bzero(pre_master_secret, pre_master_secret_len); return true; } static void tls_handle_ecdhe_client_key_xchg(struct l_tls *tls, const uint8_t *buf, size_t len) { struct tls_ecdhe_params *params = tls->pending.key_xchg_params; uint8_t pre_master_secret[128]; ssize_t pre_master_secret_len; struct l_ecc_point *other_public; struct l_ecc_scalar *secret; size_t point_bytes = 2 * l_ecc_curve_get_scalar_bytes(params->curve); /* RFC 8422, Section 5.7 */ if (len < 2) goto decode_error; if (*buf++ != 1 + point_bytes) goto decode_error; if (*buf != 4) { /* uncompressed */ TLS_DISCONNECT(TLS_ALERT_ILLEGAL_PARAM, 0, "Unsupported (deprecated?) PointConversionForm " "%u", *buf); return; } buf++; len -= 2; if (len != point_bytes) goto decode_error; /* * RFC 8422, Section 5.11: "A receiving party MUST check that the * x and y parameters from the peer's public value satisfy the * curve equation, y^2 = x^3 + ax + b mod p." * This happens in l_ecc_point_from_data when the L_ECC_POINT_TYPE_FULL * format is used. */ other_public = l_ecc_point_from_data(params->curve, L_ECC_POINT_TYPE_FULL, buf, len); if (!other_public) { TLS_DISCONNECT(TLS_ALERT_DECODE_ERROR, 0, "ClientKeyExchange.exchange_keys.ecdh_Yc " "decode error"); return; } if (!l_ecdh_generate_shared_secret(params->private, other_public, &secret)) { TLS_DISCONNECT(TLS_ALERT_INTERNAL_ERROR, 0, "Generating ECDH shared-secret failed"); return; } tls_free_ecdhe_params(tls); l_ecc_point_free(other_public); pre_master_secret_len = l_ecc_scalar_get_data(secret, pre_master_secret, sizeof(pre_master_secret)); l_ecc_scalar_free(secret); if (pre_master_secret_len < 0) { TLS_DISCONNECT(TLS_ALERT_INTERNAL_ERROR, 0, "l_ecc_scalar_get_data(secret) failed"); return; } tls_generate_master_secret(tls, pre_master_secret, pre_master_secret_len); explicit_bzero(pre_master_secret, pre_master_secret_len); return; decode_error: TLS_DISCONNECT(TLS_ALERT_DECODE_ERROR, 0, "ClientKeyExchange decode error"); } static struct tls_key_exchange_algorithm tls_ecdhe = { .need_ecc = true, .send_server_key_exchange = tls_send_ecdhe_server_key_xchg, .handle_server_key_exchange = tls_handle_ecdhe_server_key_xchg, .send_client_key_exchange = tls_send_ecdhe_client_key_xchg, .handle_client_key_exchange = tls_handle_ecdhe_client_key_xchg, .free_params = tls_free_ecdhe_params, }; /* Maximum FF DH prime modulus size in bytes */ #define TLS_DHE_MAX_SIZE 1024 struct tls_dhe_params { size_t prime_len; struct l_key *prime; struct l_key *generator; struct l_key *private; struct l_key *public; }; static void tls_free_dhe_params(struct l_tls *tls) { struct tls_dhe_params *params = tls->pending.key_xchg_params; if (!params) return; tls->pending.key_xchg_params = NULL; l_key_free(params->prime); l_key_free(params->generator); l_key_free(params->private); l_key_free(params->public); l_free(params); } static bool tls_send_dhe_server_key_xchg(struct l_tls *tls) { uint8_t buf[1024 + TLS_DHE_MAX_SIZE * 3]; uint8_t *ptr = buf + TLS_HANDSHAKE_HEADER_SIZE; struct tls_dhe_params *params; const uint8_t *prime_buf; uint8_t generator_buf = tls->negotiated_ff_group->ff.generator; uint8_t public_buf[TLS_DHE_MAX_SIZE]; size_t public_len; unsigned int zeros = 0; ssize_t sign_len; const uint8_t *server_dh_params_ptr; params = l_new(struct tls_dhe_params, 1); prime_buf = tls->negotiated_ff_group->ff.prime; params->prime_len = tls->negotiated_ff_group->ff.prime_len; params->prime = l_key_new(L_KEY_RAW, prime_buf, params->prime_len); params->generator = l_key_new(L_KEY_RAW, &generator_buf, 1); if (!params->prime || !params->generator) { TLS_DISCONNECT(TLS_ALERT_INTERNAL_ERROR, 0, "l_key_new failed"); goto free_params; } params->private = l_key_generate_dh_private(prime_buf, params->prime_len); if (!params->private) { TLS_DISCONNECT(TLS_ALERT_INTERNAL_ERROR, 0, "l_key_generate_dh_private failed"); goto free_params; } memset(public_buf, 0, sizeof(public_buf)); public_len = params->prime_len; if (!l_key_compute_dh_public(params->generator, params->private, params->prime, public_buf, &public_len)) { TLS_DISCONNECT(TLS_ALERT_INTERNAL_ERROR, 0, "l_key_compute_dh_public failed"); goto free_params; } while (zeros < public_len && public_buf[zeros] == 0x00) zeros++; server_dh_params_ptr = ptr; /* RFC 5246, Section 7.4.3 */ l_put_be16(params->prime_len, ptr); memcpy(ptr + 2, prime_buf, params->prime_len); ptr += 2 + params->prime_len; l_put_be16(1, ptr); memcpy(ptr + 2, &generator_buf, 1); ptr += 2 + 1; l_put_be16(public_len - zeros, ptr); memcpy(ptr + 2, public_buf + zeros, public_len - zeros); ptr += 2 + public_len - zeros; if (tls->pending.cipher_suite->signature) { sign_len = tls->pending.cipher_suite->signature->sign(tls, ptr, buf + sizeof(buf) - ptr, tls_get_dh_params_hash, server_dh_params_ptr, ptr - server_dh_params_ptr); if (sign_len < 0) goto free_params; ptr += sign_len; } tls->pending.key_xchg_params = params; tls_tx_handshake(tls, TLS_SERVER_KEY_EXCHANGE, buf, ptr - buf); return true; free_params: l_key_free(params->prime); l_key_free(params->generator); l_key_free(params->private); l_free(params); return false; } static void tls_handle_dhe_server_key_xchg(struct l_tls *tls, const uint8_t *buf, size_t len) { struct tls_dhe_params *params = NULL; const uint8_t *prime_buf; const uint8_t *generator_buf; size_t generator_len; const uint8_t *public_buf; size_t public_len; const uint8_t *server_dh_params_ptr = buf; if (len < 2) goto decode_error; params = l_new(struct tls_dhe_params, 1); params->prime_len = l_get_be16(buf); if (len < 2 + params->prime_len + 2) goto decode_error; prime_buf = buf + 2; buf += 2 + params->prime_len; len -= 2 + params->prime_len; /* Strip leading zeros for the length checks later */ while (params->prime_len && prime_buf[0] == 0x00) { prime_buf++; params->prime_len--; } generator_len = l_get_be16(buf); if (len < 2 + generator_len + 2) goto decode_error; generator_buf = buf + 2; buf += 2 + generator_len; len -= 2 + generator_len; public_len = l_get_be16(buf); if (len < 2 + public_len) goto decode_error; public_buf = buf + 2; buf += 2 + public_len; len -= 2 + public_len; /* * Validate the values received. Without requiring RFC 7919 from * the server, and there are many servers that don't implement it * yet, we basically have to blindly accept the provided prime value. * We have no way to confirm that it's actually prime or that it's a * "safe prime" or that it forms a group without small sub-groups. * There's also no way to whitelist all valid values. But we do a * basic sanity check and require it to be 1536-bit or longer, the * minimum length required by the Linux kernel for keyctl_dh_compute(). * The generator must also be at least within the min & max interval * for the private/public values. */ if (params->prime_len > TLS_DHE_MAX_SIZE || params->prime_len < 192 || !(prime_buf[params->prime_len - 1] & 1)) { TLS_DISCONNECT(TLS_ALERT_HANDSHAKE_FAIL, 0, "Server DH prime modulus invalid"); goto free_params; } if (!l_key_validate_dh_payload(generator_buf, generator_len, prime_buf, params->prime_len)) { TLS_DISCONNECT(TLS_ALERT_HANDSHAKE_FAIL, 0, "Server DH generator value invalid"); goto free_params; } /* * Just output a warning if the server sent group parameters not * offered in our RFC 7919 Supported Groups extension. */ if (!tls_find_ff_group(prime_buf, params->prime_len, generator_buf, generator_len)) TLS_DEBUG("Warning: using server's custom %i-bit FF DH group", (int) (params->prime_len * 8)); /* * RFC 7919 Section 3.0: * "the client MUST verify that dh_Ys is in the range * 1 < dh_Ys < dh_p - 1. If dh_Ys is not in this range, the client * MUST terminate the connection with a fatal handshake_failure(40) * alert." */ if (!l_key_validate_dh_payload(public_buf, public_len, prime_buf, params->prime_len)) { TLS_DISCONNECT(TLS_ALERT_HANDSHAKE_FAIL, 0, "Server DH public value invalid"); goto free_params; } params->prime = l_key_new(L_KEY_RAW, prime_buf, params->prime_len); params->generator = l_key_new(L_KEY_RAW, generator_buf, generator_len); params->public = l_key_new(L_KEY_RAW, public_buf, public_len); if (!params->prime || !params->generator || !params->public) { TLS_DISCONNECT(TLS_ALERT_INTERNAL_ERROR, 0, "l_key_new failed"); goto free_params; } /* Do this now so we don't need prime_buf in send_client_key_xchg */ params->private = l_key_generate_dh_private(prime_buf, params->prime_len); if (!params->private) { TLS_DISCONNECT(TLS_ALERT_INTERNAL_ERROR, 0, "l_key_generate_dh_private failed"); goto free_params; } tls->pending.key_xchg_params = params; if (tls->pending.cipher_suite->signature) { if (!tls->pending.cipher_suite->signature->verify(tls, buf, len, tls_get_dh_params_hash, server_dh_params_ptr, buf - server_dh_params_ptr)) return; } else { if (len) goto decode_error; } TLS_SET_STATE(TLS_HANDSHAKE_WAIT_HELLO_DONE); return; decode_error: TLS_DISCONNECT(TLS_ALERT_DECODE_ERROR, 0, "ServerKeyExchange decode error"); free_params: if (params) { l_key_free(params->prime); l_key_free(params->generator); l_key_free(params->public); l_free(params); } } static bool tls_send_dhe_client_key_xchg(struct l_tls *tls) { struct tls_dhe_params *params = tls->pending.key_xchg_params; uint8_t buf[128 + params->prime_len]; uint8_t *ptr = buf + TLS_HANDSHAKE_HEADER_SIZE; uint8_t public_buf[params->prime_len]; size_t public_len; unsigned int zeros = 0; uint8_t pre_master_secret[params->prime_len]; size_t pre_master_secret_len; public_len = params->prime_len; memset(public_buf, 0, sizeof(public_buf)); if (!l_key_compute_dh_public(params->generator, params->private, params->prime, public_buf, &public_len)) { TLS_DISCONNECT(TLS_ALERT_INTERNAL_ERROR, 0, "l_key_compute_dh_public failed"); return false; } while (zeros < public_len && public_buf[zeros] == 0x00) zeros++; l_put_be16(public_len - zeros, ptr); memcpy(ptr + 2, public_buf + zeros, public_len - zeros); ptr += 2 + public_len - zeros; pre_master_secret_len = params->prime_len; zeros = 0; if (!l_key_compute_dh_secret(params->public, params->private, params->prime, pre_master_secret, &pre_master_secret_len)) { TLS_DISCONNECT(TLS_ALERT_INTERNAL_ERROR, 0, "Generating DH shared-secret failed"); return false; } while (zeros < pre_master_secret_len && pre_master_secret[zeros] == 0x00) zeros++; tls_tx_handshake(tls, TLS_CLIENT_KEY_EXCHANGE, buf, ptr - buf); tls_free_dhe_params(tls); tls_generate_master_secret(tls, pre_master_secret + zeros, pre_master_secret_len - zeros); explicit_bzero(pre_master_secret, pre_master_secret_len); return true; } static void tls_handle_dhe_client_key_xchg(struct l_tls *tls, const uint8_t *buf, size_t len) { struct tls_dhe_params *params = tls->pending.key_xchg_params; uint8_t pre_master_secret[params->prime_len]; size_t pre_master_secret_len; size_t public_len; unsigned int zeros = 0; if (len < 2) goto decode_error; public_len = l_get_be16(buf); buf += 2; len -= 2; if (public_len != len) goto decode_error; /* * RFC 7919 Section 4: * "the server MUST verify that 1 < dh_Yc < dh_p - 1. If dh_Yc is * out of range, the server MUST terminate the connection with * a fatal handshake_failure(40) alert." */ if (!l_key_validate_dh_payload(buf, public_len, tls->negotiated_ff_group->ff.prime, params->prime_len)) { TLS_DISCONNECT(TLS_ALERT_HANDSHAKE_FAIL, 0, "Client DH public value invalid"); return; } params->public = l_key_new(L_KEY_RAW, buf, public_len); if (!params->public) { TLS_DISCONNECT(TLS_ALERT_INTERNAL_ERROR, 0, "l_key_new failed"); return; } pre_master_secret_len = params->prime_len; if (!l_key_compute_dh_secret(params->public, params->private, params->prime, pre_master_secret, &pre_master_secret_len)) { TLS_DISCONNECT(TLS_ALERT_INTERNAL_ERROR, 0, "Generating DH shared-secret failed"); return; } while (zeros < pre_master_secret_len && pre_master_secret[zeros] == 0x00) zeros++; tls_free_dhe_params(tls); tls_generate_master_secret(tls, pre_master_secret + zeros, pre_master_secret_len - zeros); explicit_bzero(pre_master_secret, pre_master_secret_len); return; decode_error: TLS_DISCONNECT(TLS_ALERT_DECODE_ERROR, 0, "ClientKeyExchange decode error"); } static struct tls_key_exchange_algorithm tls_dhe = { .need_ecc = true, .send_server_key_exchange = tls_send_dhe_server_key_xchg, .handle_server_key_exchange = tls_handle_dhe_server_key_xchg, .send_client_key_exchange = tls_send_dhe_client_key_xchg, .handle_client_key_exchange = tls_handle_dhe_client_key_xchg, .free_params = tls_free_dhe_params, }; static struct tls_bulk_encryption_algorithm tls_aes128 = { .cipher_type = TLS_CIPHER_BLOCK, .l_id = L_CIPHER_AES_CBC, .key_length = 16, .iv_length = 16, .block_length = 16, }, tls_aes256 = { .cipher_type = TLS_CIPHER_BLOCK, .l_id = L_CIPHER_AES_CBC, .key_length = 32, .iv_length = 16, .block_length = 16, }, tls_3des_ede = { .cipher_type = TLS_CIPHER_BLOCK, .l_id = L_CIPHER_DES3_EDE_CBC, .key_length = 24, .iv_length = 8, .block_length = 8, }, tls_aes128_gcm = { .cipher_type = TLS_CIPHER_AEAD, .l_aead_id = L_AEAD_CIPHER_AES_GCM, .key_length = 16, .iv_length = 12, .fixed_iv_length = 4, .auth_tag_length = 16, }, tls_aes256_gcm = { .cipher_type = TLS_CIPHER_AEAD, .l_aead_id = L_AEAD_CIPHER_AES_GCM, .key_length = 32, .iv_length = 12, .fixed_iv_length = 4, .auth_tag_length = 16, }; static struct tls_mac_algorithm tls_sha = { .id = 2, .hmac_type = L_CHECKSUM_SHA1, .mac_length = 20, }, tls_sha256 = { .id = 4, .hmac_type = L_CHECKSUM_SHA256, .mac_length = 32, }, tls_sha384 = { .id = 5, .hmac_type = L_CHECKSUM_SHA384, .mac_length = 48, }; static struct tls_cipher_suite tls_rsa_with_3des_ede_cbc_sha = { .id = { 0x00, 0x0a }, .name = "TLS_RSA_WITH_3DES_EDE_CBC_SHA", .verify_data_length = 12, .encryption = &tls_3des_ede, .mac = &tls_sha, .signature = &tls_rsa_signature, .key_xchg = &tls_rsa_key_xchg, }, tls_dhe_rsa_with_3des_ede_cbc_sha = { .id = { 0x00, 0x16 }, .name = "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA", .verify_data_length = 12, .encryption = &tls_3des_ede, .mac = &tls_sha, .signature = &tls_rsa_signature, .key_xchg = &tls_dhe, }, tls_rsa_with_aes_128_cbc_sha = { .id = { 0x00, 0x2f }, .name = "TLS_RSA_WITH_AES_128_CBC_SHA", .verify_data_length = 12, .encryption = &tls_aes128, .mac = &tls_sha, .signature = &tls_rsa_signature, .key_xchg = &tls_rsa_key_xchg, }, tls_dhe_rsa_with_aes_128_cbc_sha = { .id = { 0x00, 0x33 }, .name = "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", .verify_data_length = 12, .encryption = &tls_aes128, .mac = &tls_sha, .signature = &tls_rsa_signature, .key_xchg = &tls_dhe, }, tls_rsa_with_aes_256_cbc_sha = { .id = { 0x00, 0x35 }, .name = "TLS_RSA_WITH_AES_256_CBC_SHA", .verify_data_length = 12, .encryption = &tls_aes256, .mac = &tls_sha, .signature = &tls_rsa_signature, .key_xchg = &tls_rsa_key_xchg, }, tls_dhe_rsa_with_aes_256_cbc_sha = { .id = { 0x00, 0x39 }, .name = "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", .verify_data_length = 12, .encryption = &tls_aes256, .mac = &tls_sha, .signature = &tls_rsa_signature, .key_xchg = &tls_dhe, }, tls_rsa_with_aes_128_cbc_sha256 = { .id = { 0x00, 0x3c }, .name = "TLS_RSA_WITH_AES_128_CBC_SHA256", .verify_data_length = 12, .encryption = &tls_aes128, .mac = &tls_sha256, .signature = &tls_rsa_signature, .key_xchg = &tls_rsa_key_xchg, }, tls_rsa_with_aes_256_cbc_sha256 = { .id = { 0x00, 0x3d }, .name = "TLS_RSA_WITH_AES_256_CBC_SHA256", .verify_data_length = 12, .encryption = &tls_aes256, .mac = &tls_sha256, .signature = &tls_rsa_signature, .key_xchg = &tls_rsa_key_xchg, }, tls_dhe_rsa_with_aes_128_cbc_sha256 = { .id = { 0x00, 0x67 }, .name = "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", .verify_data_length = 12, .encryption = &tls_aes128, .mac = &tls_sha256, .signature = &tls_rsa_signature, .key_xchg = &tls_dhe, }, tls_dhe_rsa_with_aes_256_cbc_sha256 = { .id = { 0x00, 0x6b }, .name = "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", .verify_data_length = 12, .encryption = &tls_aes256, .mac = &tls_sha256, .signature = &tls_rsa_signature, .key_xchg = &tls_dhe, }, tls_rsa_with_aes_128_gcm_sha256 = { .id = { 0x00, 0x9c }, .name = "TLS_RSA_WITH_AES_128_GCM_SHA256", .verify_data_length = 12, .encryption = &tls_aes128_gcm, .signature = &tls_rsa_signature, .key_xchg = &tls_rsa_key_xchg, }, tls_rsa_with_aes_256_gcm_sha384 = { .id = { 0x00, 0x9d }, .name = "TLS_RSA_WITH_AES_256_GCM_SHA384", .verify_data_length = 12, .encryption = &tls_aes256_gcm, .prf_hmac = L_CHECKSUM_SHA384, .signature = &tls_rsa_signature, .key_xchg = &tls_rsa_key_xchg, }, tls_dhe_rsa_with_aes_128_gcm_sha256 = { .id = { 0x00, 0x9e }, .name = "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", .verify_data_length = 12, .encryption = &tls_aes128_gcm, .signature = &tls_rsa_signature, .key_xchg = &tls_dhe, }, tls_dhe_rsa_with_aes_256_gcm_sha384 = { .id = { 0x00, 0x9f }, .name = "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", .verify_data_length = 12, .encryption = &tls_aes256_gcm, .prf_hmac = L_CHECKSUM_SHA384, .signature = &tls_rsa_signature, .key_xchg = &tls_dhe, }, tls_ecdhe_rsa_with_3des_ede_cbc_sha = { .id = { 0xc0, 0x12 }, .name = "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", .verify_data_length = 12, .encryption = &tls_3des_ede, .mac = &tls_sha, .signature = &tls_rsa_signature, .key_xchg = &tls_ecdhe, }, tls_ecdhe_rsa_with_aes_128_cbc_sha = { .id = { 0xc0, 0x13 }, .name = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", .verify_data_length = 12, .encryption = &tls_aes128, .mac = &tls_sha, .signature = &tls_rsa_signature, .key_xchg = &tls_ecdhe, }, tls_ecdhe_rsa_with_aes_256_cbc_sha = { .id = { 0xc0, 0x14 }, .name = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", .verify_data_length = 12, .encryption = &tls_aes256, .mac = &tls_sha, .signature = &tls_rsa_signature, .key_xchg = &tls_ecdhe, }, tls_ecdhe_rsa_with_aes_128_cbc_sha256 = { .id = { 0xc0, 0x27 }, .name = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", .verify_data_length = 12, .encryption = &tls_aes128, .mac = &tls_sha256, .signature = &tls_rsa_signature, .key_xchg = &tls_ecdhe, }, tls_ecdhe_rsa_with_aes_256_cbc_sha384 = { .id = { 0xc0, 0x28 }, .name = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", .verify_data_length = 12, .encryption = &tls_aes256, .mac = &tls_sha384, .prf_hmac = L_CHECKSUM_SHA384, .signature = &tls_rsa_signature, .key_xchg = &tls_ecdhe, }, tls_ecdhe_rsa_with_aes_128_gcm_sha256 = { .id = { 0xc0, 0x2f }, .name = "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", .verify_data_length = 12, .encryption = &tls_aes128_gcm, .signature = &tls_rsa_signature, .key_xchg = &tls_ecdhe, }, tls_ecdhe_rsa_with_aes_256_gcm_sha384 = { .id = { 0xc0, 0x30 }, .name = "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", .verify_data_length = 12, .encryption = &tls_aes256_gcm, .prf_hmac = L_CHECKSUM_SHA384, .signature = &tls_rsa_signature, .key_xchg = &tls_ecdhe, }; struct tls_cipher_suite *tls_cipher_suite_pref[] = { &tls_ecdhe_rsa_with_aes_256_cbc_sha, &tls_ecdhe_rsa_with_aes_128_cbc_sha, &tls_dhe_rsa_with_aes_256_cbc_sha, &tls_dhe_rsa_with_aes_128_cbc_sha, &tls_rsa_with_aes_256_cbc_sha, &tls_rsa_with_aes_128_cbc_sha, &tls_ecdhe_rsa_with_aes_256_cbc_sha384, &tls_ecdhe_rsa_with_aes_128_cbc_sha256, &tls_dhe_rsa_with_aes_256_cbc_sha256, &tls_dhe_rsa_with_aes_128_cbc_sha256, &tls_rsa_with_aes_256_cbc_sha256, &tls_rsa_with_aes_128_cbc_sha256, &tls_ecdhe_rsa_with_aes_256_gcm_sha384, &tls_ecdhe_rsa_with_aes_128_gcm_sha256, &tls_dhe_rsa_with_aes_256_gcm_sha384, &tls_dhe_rsa_with_aes_128_gcm_sha256, &tls_rsa_with_aes_256_gcm_sha384, &tls_rsa_with_aes_128_gcm_sha256, &tls_ecdhe_rsa_with_3des_ede_cbc_sha, &tls_dhe_rsa_with_3des_ede_cbc_sha, &tls_rsa_with_3des_ede_cbc_sha, NULL, };