Message ID | 20220718160222.10634-7-denkenz@gmail.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [1/9] cert/key: Add support for EC based certificates | expand |
Context | Check | Description |
---|---|---|
tedd_an/pre-ci_am | success | Success |
On Mon, 18 Jul 2022, Denis Kenzior wrote: > --- > ell/tls-suites.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 119 insertions(+) > > diff --git a/ell/tls-suites.c b/ell/tls-suites.c > index bc6a756422b3..34141ab7fa56 100644 > --- a/ell/tls-suites.c > +++ b/ell/tls-suites.c > @@ -262,6 +262,81 @@ static struct tls_signature_algorithm tls_rsa_signature = { > .verify = tls_rsa_verify, > }; > > +static bool tls_ecdsa_validate_cert_key(struct l_cert *cert) > +{ > + return l_cert_get_pubkey_type(cert) == L_CERT_KEY_ECC; > +} > + > +static bool tls_ecdsa_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) > +{ > + /* RFC 8422, Section 5.10: "SHA-1 is used in TLS 1.1 and earlier" */ > + enum handshake_hash_type hash = HANDSHAKE_HASH_SHA1; > + enum l_checksum_type sign_checksum_type; > + const uint8_t *opaque; > + uint16_t opaque_len; > + uint8_t expected[HANDSHAKE_HASH_MAX_SIZE]; > + size_t expected_len; > + bool success; > + > + opaque = validate_digitally_signed(tls, in, in_len, > + SIGNATURE_ALGORITHM_ECDSA, &opaque_len); > + if (!opaque) > + return false; > + > + if (tls->negotiated_version >= L_TLS_V12) { > + hash = find_hash_by_id(in[0]); > + if (hash == __HANDSHAKE_HASH_COUNT) { > + TLS_DISCONNECT(TLS_ALERT_DECRYPT_ERROR, 0, > + "Unknown hash type %i", in[0]); > + return false; > + } > + > + /* Hash should match the curve, refer to RFC 5480, Section 4 */ > + switch (tls->peer_pubkey_size) { > + case 32: > + if (hash != HANDSHAKE_HASH_SHA256 && > + hash != HANDSHAKE_HASH_SHA384) > + goto bad_hash; > + > + break; > + case 48: > + if (hash != HANDSHAKE_HASH_SHA384) > + goto bad_hash; > + > + break; > + bad_hash: > + default: > + TLS_DISCONNECT(TLS_ALERT_DECRYPT_ERROR, 0, > + "Invalid hash %i", > + in[0]); > + } > + } > + > + get_hash(tls, hash, data, data_len, expected, &expected_len); > + sign_checksum_type = tls_handshake_hash_data[hash].l_id; > + > + success = l_key_verify(tls->peer_pubkey, L_KEY_ECDSA_X962, > + sign_checksum_type, expected, opaque, > + expected_len, opaque_len); > + > + 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_ecdsa_signature = { > + .id = 3, /* SignatureAlgorithm.ecdsa */ > + .validate_cert_key_type = tls_ecdsa_validate_cert_key, > + .verify = tls_ecdsa_verify, > +}; > + > static bool tls_send_rsa_client_key_xchg(struct l_tls *tls) > { > uint8_t buf[1024 + 32]; > @@ -1350,11 +1425,52 @@ static struct tls_cipher_suite tls_rsa_with_3des_ede_cbc_sha = { > .prf_hmac = L_CHECKSUM_SHA384, > .signature = &tls_rsa_signature, > .key_xchg = &tls_ecdhe, > +}, tls_ecdhe_ecdsa_with_3des_ede_cbc_sha = { > + .id = { 0xc0, 0x08 }, > + .name = "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", > + .verify_data_length = 12, > + .encryption = &tls_3des_ede, > + .mac = &tls_sha, > + .signature = &tls_ecdsa_signature, > + .key_xchg = &tls_ecdhe, > +}, tls_ecdhe_ecdsa_with_aes_128_cbc_sha = { > + .id = { 0xc0, 0x09 }, > + .name = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", > + .verify_data_length = 12, > + .encryption = &tls_aes128, > + .mac = &tls_sha, > + .signature = &tls_ecdsa_signature, > + .key_xchg = &tls_ecdhe, > +}, tls_ecdhe_ecdsa_with_aes_256_cbc_sha = { > + .id = { 0xc0, 0x0a }, > + .name = "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", > + .verify_data_length = 12, > + .encryption = &tls_aes256, > + .mac = &tls_sha, > + .signature = &tls_ecdsa_signature, > + .key_xchg = &tls_ecdhe, > +}, tls_ecdhe_ecdsa_with_aes_128_gcm_sha256 = { > + .id = { 0xc0, 0x2b }, > + .name = "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", > + .verify_data_length = 12, > + .encryption = &tls_aes128_gcm, > + .signature = &tls_ecdsa_signature, > + .key_xchg = &tls_ecdhe, > +}, tls_ecdhe_ecdsa_with_aes_256_gcm_sha384 = { > + .id = { 0xc0, 0x2c }, > + .name = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", > + .verify_data_length = 12, > + .encryption = &tls_aes256_gcm, > + .prf_hmac = L_CHECKSUM_SHA384, > + .signature = &tls_ecdsa_signature, > + .key_xchg = &tls_ecdhe, > }; These new suites fail in unit/test-tls with the 5.18.11-200.fc36.x86_64 kernel (latest Fedora 36): TEST: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA test-tls: unit/test-tls.c:661: test_tls_with_ver: Assertion `!!l_tls_start(s[1].tls) == !test->expect_client_start_fail' failed. I started commenting out each failed test, also verified the failure with TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA and TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384. Didn't try the last couple cases (GCM_SHA256 and 3DES). > > struct tls_cipher_suite *tls_cipher_suite_pref[] = { > &tls_ecdhe_rsa_with_aes_256_cbc_sha, > + &tls_ecdhe_ecdsa_with_aes_256_cbc_sha, > &tls_ecdhe_rsa_with_aes_128_cbc_sha, > + &tls_ecdhe_ecdsa_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, > @@ -1367,11 +1483,14 @@ struct tls_cipher_suite *tls_cipher_suite_pref[] = { > &tls_rsa_with_aes_128_cbc_sha256, > &tls_ecdhe_rsa_with_aes_256_gcm_sha384, > &tls_ecdhe_rsa_with_aes_128_gcm_sha256, > + &tls_ecdhe_ecdsa_with_aes_256_gcm_sha384, > + &tls_ecdhe_ecdsa_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_ecdhe_ecdsa_with_3des_ede_cbc_sha, > &tls_dhe_rsa_with_3des_ede_cbc_sha, > &tls_rsa_with_3des_ede_cbc_sha, > NULL, > -- > 2.35.1 > > > -- Mat Martineau Intel
diff --git a/ell/tls-suites.c b/ell/tls-suites.c index bc6a756422b3..34141ab7fa56 100644 --- a/ell/tls-suites.c +++ b/ell/tls-suites.c @@ -262,6 +262,81 @@ static struct tls_signature_algorithm tls_rsa_signature = { .verify = tls_rsa_verify, }; +static bool tls_ecdsa_validate_cert_key(struct l_cert *cert) +{ + return l_cert_get_pubkey_type(cert) == L_CERT_KEY_ECC; +} + +static bool tls_ecdsa_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) +{ + /* RFC 8422, Section 5.10: "SHA-1 is used in TLS 1.1 and earlier" */ + enum handshake_hash_type hash = HANDSHAKE_HASH_SHA1; + enum l_checksum_type sign_checksum_type; + const uint8_t *opaque; + uint16_t opaque_len; + uint8_t expected[HANDSHAKE_HASH_MAX_SIZE]; + size_t expected_len; + bool success; + + opaque = validate_digitally_signed(tls, in, in_len, + SIGNATURE_ALGORITHM_ECDSA, &opaque_len); + if (!opaque) + return false; + + if (tls->negotiated_version >= L_TLS_V12) { + hash = find_hash_by_id(in[0]); + if (hash == __HANDSHAKE_HASH_COUNT) { + TLS_DISCONNECT(TLS_ALERT_DECRYPT_ERROR, 0, + "Unknown hash type %i", in[0]); + return false; + } + + /* Hash should match the curve, refer to RFC 5480, Section 4 */ + switch (tls->peer_pubkey_size) { + case 32: + if (hash != HANDSHAKE_HASH_SHA256 && + hash != HANDSHAKE_HASH_SHA384) + goto bad_hash; + + break; + case 48: + if (hash != HANDSHAKE_HASH_SHA384) + goto bad_hash; + + break; + bad_hash: + default: + TLS_DISCONNECT(TLS_ALERT_DECRYPT_ERROR, 0, + "Invalid hash %i", + in[0]); + } + } + + get_hash(tls, hash, data, data_len, expected, &expected_len); + sign_checksum_type = tls_handshake_hash_data[hash].l_id; + + success = l_key_verify(tls->peer_pubkey, L_KEY_ECDSA_X962, + sign_checksum_type, expected, opaque, + expected_len, opaque_len); + + 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_ecdsa_signature = { + .id = 3, /* SignatureAlgorithm.ecdsa */ + .validate_cert_key_type = tls_ecdsa_validate_cert_key, + .verify = tls_ecdsa_verify, +}; + static bool tls_send_rsa_client_key_xchg(struct l_tls *tls) { uint8_t buf[1024 + 32]; @@ -1350,11 +1425,52 @@ static struct tls_cipher_suite tls_rsa_with_3des_ede_cbc_sha = { .prf_hmac = L_CHECKSUM_SHA384, .signature = &tls_rsa_signature, .key_xchg = &tls_ecdhe, +}, tls_ecdhe_ecdsa_with_3des_ede_cbc_sha = { + .id = { 0xc0, 0x08 }, + .name = "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", + .verify_data_length = 12, + .encryption = &tls_3des_ede, + .mac = &tls_sha, + .signature = &tls_ecdsa_signature, + .key_xchg = &tls_ecdhe, +}, tls_ecdhe_ecdsa_with_aes_128_cbc_sha = { + .id = { 0xc0, 0x09 }, + .name = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + .verify_data_length = 12, + .encryption = &tls_aes128, + .mac = &tls_sha, + .signature = &tls_ecdsa_signature, + .key_xchg = &tls_ecdhe, +}, tls_ecdhe_ecdsa_with_aes_256_cbc_sha = { + .id = { 0xc0, 0x0a }, + .name = "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + .verify_data_length = 12, + .encryption = &tls_aes256, + .mac = &tls_sha, + .signature = &tls_ecdsa_signature, + .key_xchg = &tls_ecdhe, +}, tls_ecdhe_ecdsa_with_aes_128_gcm_sha256 = { + .id = { 0xc0, 0x2b }, + .name = "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + .verify_data_length = 12, + .encryption = &tls_aes128_gcm, + .signature = &tls_ecdsa_signature, + .key_xchg = &tls_ecdhe, +}, tls_ecdhe_ecdsa_with_aes_256_gcm_sha384 = { + .id = { 0xc0, 0x2c }, + .name = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + .verify_data_length = 12, + .encryption = &tls_aes256_gcm, + .prf_hmac = L_CHECKSUM_SHA384, + .signature = &tls_ecdsa_signature, + .key_xchg = &tls_ecdhe, }; struct tls_cipher_suite *tls_cipher_suite_pref[] = { &tls_ecdhe_rsa_with_aes_256_cbc_sha, + &tls_ecdhe_ecdsa_with_aes_256_cbc_sha, &tls_ecdhe_rsa_with_aes_128_cbc_sha, + &tls_ecdhe_ecdsa_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, @@ -1367,11 +1483,14 @@ struct tls_cipher_suite *tls_cipher_suite_pref[] = { &tls_rsa_with_aes_128_cbc_sha256, &tls_ecdhe_rsa_with_aes_256_gcm_sha384, &tls_ecdhe_rsa_with_aes_128_gcm_sha256, + &tls_ecdhe_ecdsa_with_aes_256_gcm_sha384, + &tls_ecdhe_ecdsa_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_ecdhe_ecdsa_with_3des_ede_cbc_sha, &tls_dhe_rsa_with_3des_ede_cbc_sha, &tls_rsa_with_3des_ede_cbc_sha, NULL,