xref: /openbsd-src/lib/libssl/ssl_sigalgs.c (revision ccf5fc624c26da6d74c37ba18834beadc35e2bad)
1*ccf5fc62Sbeck /* $OpenBSD: ssl_sigalgs.c,v 1.50 2024/07/09 13:43:57 beck Exp $ */
296b1ac03Sbeck /*
3c07686ceSbeck  * Copyright (c) 2018-2020 Bob Beck <beck@openbsd.org>
421424b10Sjsing  * Copyright (c) 2021 Joel Sing <jsing@openbsd.org>
596b1ac03Sbeck  *
696b1ac03Sbeck  * Permission to use, copy, modify, and/or distribute this software for any
796b1ac03Sbeck  * purpose with or without fee is hereby granted, provided that the above
896b1ac03Sbeck  * copyright notice and this permission notice appear in all copies.
996b1ac03Sbeck  *
1096b1ac03Sbeck  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1196b1ac03Sbeck  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1296b1ac03Sbeck  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
1396b1ac03Sbeck  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1496b1ac03Sbeck  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
1596b1ac03Sbeck  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
1696b1ac03Sbeck  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1796b1ac03Sbeck  */
1821424b10Sjsing 
1996b1ac03Sbeck #include <string.h>
2096b1ac03Sbeck #include <stdlib.h>
2196b1ac03Sbeck 
2296b1ac03Sbeck #include <openssl/evp.h>
23f4dd87b5Sjsing #include <openssl/opensslconf.h>
2496b1ac03Sbeck 
2596b1ac03Sbeck #include "bytestring.h"
26c9675a23Stb #include "ssl_local.h"
2796b1ac03Sbeck #include "ssl_sigalgs.h"
2896b1ac03Sbeck #include "tls13_internal.h"
2996b1ac03Sbeck 
3096b1ac03Sbeck const struct ssl_sigalg sigalgs[] = {
3196b1ac03Sbeck 	{
3296b1ac03Sbeck 		.value = SIGALG_RSA_PKCS1_SHA512,
3396b1ac03Sbeck 		.key_type = EVP_PKEY_RSA,
34e3d56dc6Sjsing 		.md = EVP_sha512,
35fe57aeedStb 		.security_level = 5,
3696b1ac03Sbeck 	},
3796b1ac03Sbeck 	{
388b21e38aSbeck 		.value = SIGALG_ECDSA_SECP521R1_SHA512,
3996b1ac03Sbeck 		.key_type = EVP_PKEY_EC,
40e3d56dc6Sjsing 		.md = EVP_sha512,
41fe57aeedStb 		.security_level = 5,
42c5270c5dStb 		.group_nid = NID_secp521r1,
4396b1ac03Sbeck 	},
4496b1ac03Sbeck 	{
4596b1ac03Sbeck 		.value = SIGALG_RSA_PKCS1_SHA384,
4696b1ac03Sbeck 		.key_type = EVP_PKEY_RSA,
47e3d56dc6Sjsing 		.md = EVP_sha384,
48fe57aeedStb 		.security_level = 4,
4996b1ac03Sbeck 	},
5096b1ac03Sbeck 	{
5196b1ac03Sbeck 		.value = SIGALG_ECDSA_SECP384R1_SHA384,
5296b1ac03Sbeck 		.key_type = EVP_PKEY_EC,
53e3d56dc6Sjsing 		.md = EVP_sha384,
54fe57aeedStb 		.security_level = 4,
55c5270c5dStb 		.group_nid = NID_secp384r1,
5696b1ac03Sbeck 	},
5796b1ac03Sbeck 	{
5896b1ac03Sbeck 		.value = SIGALG_RSA_PKCS1_SHA256,
5996b1ac03Sbeck 		.key_type = EVP_PKEY_RSA,
60e3d56dc6Sjsing 		.md = EVP_sha256,
61fe57aeedStb 		.security_level = 3,
6296b1ac03Sbeck 	},
6396b1ac03Sbeck 	{
6496b1ac03Sbeck 		.value = SIGALG_ECDSA_SECP256R1_SHA256,
6596b1ac03Sbeck 		.key_type = EVP_PKEY_EC,
66e3d56dc6Sjsing 		.md = EVP_sha256,
67fe57aeedStb 		.security_level = 3,
68c5270c5dStb 		.group_nid = NID_X9_62_prime256v1,
6996b1ac03Sbeck 	},
7096b1ac03Sbeck 	{
7196b1ac03Sbeck 		.value = SIGALG_RSA_PSS_RSAE_SHA256,
7296b1ac03Sbeck 		.key_type = EVP_PKEY_RSA,
73e3d56dc6Sjsing 		.md = EVP_sha256,
74fe57aeedStb 		.security_level = 3,
7596b1ac03Sbeck 		.flags = SIGALG_FLAG_RSA_PSS,
7696b1ac03Sbeck 	},
7796b1ac03Sbeck 	{
7896b1ac03Sbeck 		.value = SIGALG_RSA_PSS_RSAE_SHA384,
7996b1ac03Sbeck 		.key_type = EVP_PKEY_RSA,
80e3d56dc6Sjsing 		.md = EVP_sha384,
81fe57aeedStb 		.security_level = 4,
8296b1ac03Sbeck 		.flags = SIGALG_FLAG_RSA_PSS,
8396b1ac03Sbeck 	},
8496b1ac03Sbeck 	{
8596b1ac03Sbeck 		.value = SIGALG_RSA_PSS_RSAE_SHA512,
8696b1ac03Sbeck 		.key_type = EVP_PKEY_RSA,
87e3d56dc6Sjsing 		.md = EVP_sha512,
88fe57aeedStb 		.security_level = 5,
8996b1ac03Sbeck 		.flags = SIGALG_FLAG_RSA_PSS,
9096b1ac03Sbeck 	},
9196b1ac03Sbeck 	{
9296b1ac03Sbeck 		.value = SIGALG_RSA_PSS_PSS_SHA256,
9396b1ac03Sbeck 		.key_type = EVP_PKEY_RSA,
94e3d56dc6Sjsing 		.md = EVP_sha256,
95fe57aeedStb 		.security_level = 3,
9696b1ac03Sbeck 		.flags = SIGALG_FLAG_RSA_PSS,
9796b1ac03Sbeck 	},
9896b1ac03Sbeck 	{
9996b1ac03Sbeck 		.value = SIGALG_RSA_PSS_PSS_SHA384,
10096b1ac03Sbeck 		.key_type = EVP_PKEY_RSA,
101e3d56dc6Sjsing 		.md = EVP_sha384,
102fe57aeedStb 		.security_level = 4,
10396b1ac03Sbeck 		.flags = SIGALG_FLAG_RSA_PSS,
10496b1ac03Sbeck 	},
10596b1ac03Sbeck 	{
10696b1ac03Sbeck 		.value = SIGALG_RSA_PSS_PSS_SHA512,
10796b1ac03Sbeck 		.key_type = EVP_PKEY_RSA,
108e3d56dc6Sjsing 		.md = EVP_sha512,
109fe57aeedStb 		.security_level = 5,
11096b1ac03Sbeck 		.flags = SIGALG_FLAG_RSA_PSS,
11196b1ac03Sbeck 	},
11296b1ac03Sbeck 	{
11396b1ac03Sbeck 		.value = SIGALG_RSA_PKCS1_SHA224,
11496b1ac03Sbeck 		.key_type = EVP_PKEY_RSA,
115e3d56dc6Sjsing 		.md = EVP_sha224,
116fe57aeedStb 		.security_level = 2,
11796b1ac03Sbeck 	},
11896b1ac03Sbeck 	{
11996b1ac03Sbeck 		.value = SIGALG_ECDSA_SECP224R1_SHA224,
12096b1ac03Sbeck 		.key_type = EVP_PKEY_EC,
121e3d56dc6Sjsing 		.md = EVP_sha224,
122fe57aeedStb 		.security_level = 2,
12396b1ac03Sbeck 	},
12496b1ac03Sbeck 	{
12596b1ac03Sbeck 		.value = SIGALG_RSA_PKCS1_SHA1,
12696b1ac03Sbeck 		.key_type = EVP_PKEY_RSA,
127948d5146Sbeck 		.md = EVP_sha1,
128fe57aeedStb 		.security_level = 1,
12996b1ac03Sbeck 	},
13096b1ac03Sbeck 	{
13196b1ac03Sbeck 		.value = SIGALG_ECDSA_SHA1,
13296b1ac03Sbeck 		.key_type = EVP_PKEY_EC,
13396b1ac03Sbeck 		.md = EVP_sha1,
134fe57aeedStb 		.security_level = 1,
13596b1ac03Sbeck 	},
13696b1ac03Sbeck 	{
1372fab3c32Sbeck 		.value = SIGALG_RSA_PKCS1_MD5_SHA1,
1382fab3c32Sbeck 		.key_type = EVP_PKEY_RSA,
1392fab3c32Sbeck 		.md = EVP_md5_sha1,
140fe57aeedStb 		.security_level = 1,
1412fab3c32Sbeck 	},
1422fab3c32Sbeck 	{
14396b1ac03Sbeck 		.value = SIGALG_NONE,
14496b1ac03Sbeck 	},
14596b1ac03Sbeck };
14696b1ac03Sbeck 
147eb6a17d1Sjsing /* Sigalgs for TLSv1.3, in preference order. */
1485b35b8bbSguenther const uint16_t tls13_sigalgs[] = {
1493e29903bSbeck 	SIGALG_RSA_PSS_RSAE_SHA512,
1503e29903bSbeck 	SIGALG_RSA_PKCS1_SHA512,
1518b21e38aSbeck 	SIGALG_ECDSA_SECP521R1_SHA512,
1523e29903bSbeck 	SIGALG_RSA_PSS_RSAE_SHA384,
1533e29903bSbeck 	SIGALG_RSA_PKCS1_SHA384,
1543e29903bSbeck 	SIGALG_ECDSA_SECP384R1_SHA384,
1553e29903bSbeck 	SIGALG_RSA_PSS_RSAE_SHA256,
1563e29903bSbeck 	SIGALG_RSA_PKCS1_SHA256,
1573e29903bSbeck 	SIGALG_ECDSA_SECP256R1_SHA256,
1583e29903bSbeck };
1595b35b8bbSguenther const size_t tls13_sigalgs_len = (sizeof(tls13_sigalgs) / sizeof(tls13_sigalgs[0]));
1603e29903bSbeck 
161eb6a17d1Sjsing /* Sigalgs for TLSv1.2, in preference order. */
1625b35b8bbSguenther const uint16_t tls12_sigalgs[] = {
1633e29903bSbeck 	SIGALG_RSA_PSS_RSAE_SHA512,
164d924cf6aSbeck 	SIGALG_RSA_PKCS1_SHA512,
1658b21e38aSbeck 	SIGALG_ECDSA_SECP521R1_SHA512,
1663e29903bSbeck 	SIGALG_RSA_PSS_RSAE_SHA384,
167d924cf6aSbeck 	SIGALG_RSA_PKCS1_SHA384,
168d924cf6aSbeck 	SIGALG_ECDSA_SECP384R1_SHA384,
1693e29903bSbeck 	SIGALG_RSA_PSS_RSAE_SHA256,
170d924cf6aSbeck 	SIGALG_RSA_PKCS1_SHA256,
171d924cf6aSbeck 	SIGALG_ECDSA_SECP256R1_SHA256,
172d924cf6aSbeck 	SIGALG_RSA_PKCS1_SHA1, /* XXX */
173d924cf6aSbeck 	SIGALG_ECDSA_SHA1,     /* XXX */
174d924cf6aSbeck };
1755b35b8bbSguenther const size_t tls12_sigalgs_len = (sizeof(tls12_sigalgs) / sizeof(tls12_sigalgs[0]));
176d924cf6aSbeck 
177c4b0c3ceSjsing static void
ssl_sigalgs_for_version(uint16_t tls_version,const uint16_t ** out_values,size_t * out_len)178c4b0c3ceSjsing ssl_sigalgs_for_version(uint16_t tls_version, const uint16_t **out_values,
179c4b0c3ceSjsing     size_t *out_len)
180c4b0c3ceSjsing {
181c4b0c3ceSjsing 	if (tls_version >= TLS1_3_VERSION) {
182c4b0c3ceSjsing 		*out_values = tls13_sigalgs;
183c4b0c3ceSjsing 		*out_len = tls13_sigalgs_len;
184c4b0c3ceSjsing 	} else {
185c4b0c3ceSjsing 		*out_values = tls12_sigalgs;
186c4b0c3ceSjsing 		*out_len = tls12_sigalgs_len;
187c4b0c3ceSjsing 	}
188c4b0c3ceSjsing }
189c4b0c3ceSjsing 
19058ed3333Sjsing static const struct ssl_sigalg *
ssl_sigalg_lookup(uint16_t value)191d2a2fa5fSjsing ssl_sigalg_lookup(uint16_t value)
19296b1ac03Sbeck {
19396b1ac03Sbeck 	int i;
19496b1ac03Sbeck 
19596b1ac03Sbeck 	for (i = 0; sigalgs[i].value != SIGALG_NONE; i++) {
196d2a2fa5fSjsing 		if (sigalgs[i].value == value)
19796b1ac03Sbeck 			return &sigalgs[i];
19896b1ac03Sbeck 	}
19996b1ac03Sbeck 
20096b1ac03Sbeck 	return NULL;
20196b1ac03Sbeck }
20296b1ac03Sbeck 
20358ed3333Sjsing static const struct ssl_sigalg *
ssl_sigalg_from_value(SSL * s,uint16_t value)204468bde53Sjsing ssl_sigalg_from_value(SSL *s, uint16_t value)
20596b1ac03Sbeck {
206d2a2fa5fSjsing 	const uint16_t *values;
207d2a2fa5fSjsing 	size_t len;
2082b3aa98dSbeck 	int i;
20996b1ac03Sbeck 
21002876cc3Sjsing 	ssl_sigalgs_for_version(s->s3->hs.negotiated_tls_version,
211468bde53Sjsing 	    &values, &len);
212d2a2fa5fSjsing 
2132b3aa98dSbeck 	for (i = 0; i < len; i++) {
214d2a2fa5fSjsing 		if (values[i] == value)
215d2a2fa5fSjsing 			return ssl_sigalg_lookup(value);
2162b3aa98dSbeck 	}
21796b1ac03Sbeck 
21896b1ac03Sbeck 	return NULL;
21996b1ac03Sbeck }
22096b1ac03Sbeck 
22196b1ac03Sbeck int
ssl_sigalgs_build(uint16_t tls_version,CBB * cbb,int security_level)222678f3880Stb ssl_sigalgs_build(uint16_t tls_version, CBB *cbb, int security_level)
22396b1ac03Sbeck {
224678f3880Stb 	const struct ssl_sigalg *sigalg;
225c4b0c3ceSjsing 	const uint16_t *values;
226c4b0c3ceSjsing 	size_t len;
227d924cf6aSbeck 	size_t i;
228678f3880Stb 	int ret = 0;
22996b1ac03Sbeck 
230c4b0c3ceSjsing 	ssl_sigalgs_for_version(tls_version, &values, &len);
231c4b0c3ceSjsing 
232d924cf6aSbeck 	/* Add values in order as long as they are supported. */
233d924cf6aSbeck 	for (i = 0; i < len; i++) {
234eb6a17d1Sjsing 		/* Do not allow the legacy value for < 1.2 to be used. */
2352fab3c32Sbeck 		if (values[i] == SIGALG_RSA_PKCS1_MD5_SHA1)
2362fab3c32Sbeck 			return 0;
237678f3880Stb 		if ((sigalg = ssl_sigalg_lookup(values[i])) == NULL)
238d924cf6aSbeck 			return 0;
239678f3880Stb 		if (sigalg->security_level < security_level)
240678f3880Stb 			continue;
241678f3880Stb 
242eb6a17d1Sjsing 		if (!CBB_add_u16(cbb, values[i]))
24396b1ac03Sbeck 			return 0;
244678f3880Stb 
245678f3880Stb 		ret = 1;
24696b1ac03Sbeck 	}
247678f3880Stb 	return ret;
24896b1ac03Sbeck }
24981230f72Sbeck 
250ca7ca908Sjsing static const struct ssl_sigalg *
ssl_sigalg_for_legacy(SSL * s,EVP_PKEY * pkey)251ca7ca908Sjsing ssl_sigalg_for_legacy(SSL *s, EVP_PKEY *pkey)
252ca7ca908Sjsing {
2534fde5609Stb 	if (SSL_get_security_level(s) > 1)
2544fde5609Stb 		return NULL;
2554fde5609Stb 
256ca7ca908Sjsing 	/* Default signature algorithms used for TLSv1.2 and earlier. */
2575c273ab3Stb 	switch (EVP_PKEY_id(pkey)) {
258ca7ca908Sjsing 	case EVP_PKEY_RSA:
25902876cc3Sjsing 		if (s->s3->hs.negotiated_tls_version < TLS1_2_VERSION)
260ca7ca908Sjsing 			return ssl_sigalg_lookup(SIGALG_RSA_PKCS1_MD5_SHA1);
261ca7ca908Sjsing 		return ssl_sigalg_lookup(SIGALG_RSA_PKCS1_SHA1);
262ca7ca908Sjsing 	case EVP_PKEY_EC:
263ca7ca908Sjsing 		return ssl_sigalg_lookup(SIGALG_ECDSA_SHA1);
264ca7ca908Sjsing 	}
265ca7ca908Sjsing 	SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE);
2660a11d68fStb 	return NULL;
267ca7ca908Sjsing }
268ca7ca908Sjsing 
26958ed3333Sjsing static int
ssl_sigalg_pkey_ok(SSL * s,const struct ssl_sigalg * sigalg,EVP_PKEY * pkey)2709bba4ac0Sjsing ssl_sigalg_pkey_ok(SSL *s, const struct ssl_sigalg *sigalg, EVP_PKEY *pkey)
27181230f72Sbeck {
2723ef2d76bSbeck 	if (sigalg == NULL || pkey == NULL)
27381230f72Sbeck 		return 0;
2745c273ab3Stb 	if (sigalg->key_type != EVP_PKEY_id(pkey))
2753ef2d76bSbeck 		return 0;
2763ef2d76bSbeck 
277b3e0802aSjsing 	/* RSA PSS must have a sufficiently large RSA key. */
2789bba4ac0Sjsing 	if ((sigalg->flags & SIGALG_FLAG_RSA_PSS)) {
2795c273ab3Stb 		if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA ||
2803ef2d76bSbeck 		    EVP_PKEY_size(pkey) < (2 * EVP_MD_size(sigalg->md()) + 2))
2813ef2d76bSbeck 			return 0;
2823ef2d76bSbeck 	}
2833ef2d76bSbeck 
2841fd41f50Stb 	if (!ssl_security_sigalg_check(s, pkey))
2859ba7321cStb 		return 0;
2869ba7321cStb 
28702876cc3Sjsing 	if (s->s3->hs.negotiated_tls_version < TLS1_3_VERSION)
2881312944bSjsing 		return 1;
2891312944bSjsing 
2909bba4ac0Sjsing 	/* RSA cannot be used without PSS in TLSv1.3. */
2911312944bSjsing 	if (sigalg->key_type == EVP_PKEY_RSA &&
2929bba4ac0Sjsing 	    (sigalg->flags & SIGALG_FLAG_RSA_PSS) == 0)
2939bba4ac0Sjsing 		return 0;
2949bba4ac0Sjsing 
295c5270c5dStb 	/* Ensure that group matches for EC keys. */
2965c273ab3Stb 	if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) {
297c5270c5dStb 		if (sigalg->group_nid == 0)
2983ef2d76bSbeck 			return 0;
2999bba4ac0Sjsing 		if (EC_GROUP_get_curve_name(EC_KEY_get0_group(
300c5270c5dStb 		    EVP_PKEY_get0_EC_KEY(pkey))) != sigalg->group_nid)
30196b13b45Sjsing 			return 0;
302c59f6b05Sbeck 	}
3033ef2d76bSbeck 
3043ef2d76bSbeck 	return 1;
30581230f72Sbeck }
30696b13b45Sjsing 
30796b13b45Sjsing const struct ssl_sigalg *
ssl_sigalg_select(SSL * s,EVP_PKEY * pkey)30896b13b45Sjsing ssl_sigalg_select(SSL *s, EVP_PKEY *pkey)
30996b13b45Sjsing {
31096b13b45Sjsing 	CBS cbs;
31196b13b45Sjsing 
312ca7ca908Sjsing 	if (!SSL_USE_SIGALGS(s))
313ca7ca908Sjsing 		return ssl_sigalg_for_legacy(s, pkey);
31496b13b45Sjsing 
31596b13b45Sjsing 	/*
316ca7ca908Sjsing 	 * RFC 5246 allows a TLS 1.2 client to send no sigalgs extension,
317ca7ca908Sjsing 	 * in which case the server must use the default.
31896b13b45Sjsing 	 */
31902876cc3Sjsing 	if (s->s3->hs.negotiated_tls_version < TLS1_3_VERSION &&
32002876cc3Sjsing 	    s->s3->hs.sigalgs == NULL)
321ca7ca908Sjsing 		return ssl_sigalg_for_legacy(s, pkey);
32296b13b45Sjsing 
32396b13b45Sjsing 	/*
32496b13b45Sjsing 	 * If we get here, we have client or server sent sigalgs, use one.
32596b13b45Sjsing 	 */
32602876cc3Sjsing 	CBS_init(&cbs, s->s3->hs.sigalgs, s->s3->hs.sigalgs_len);
32796b13b45Sjsing 	while (CBS_len(&cbs) > 0) {
32896b13b45Sjsing 		const struct ssl_sigalg *sigalg;
329d2a2fa5fSjsing 		uint16_t sigalg_value;
33096b13b45Sjsing 
331d2a2fa5fSjsing 		if (!CBS_get_u16(&cbs, &sigalg_value))
3328e8b8cacStb 			return NULL;
33396b13b45Sjsing 
334468bde53Sjsing 		if ((sigalg = ssl_sigalg_from_value(s, sigalg_value)) == NULL)
33596b13b45Sjsing 			continue;
3369bba4ac0Sjsing 		if (ssl_sigalg_pkey_ok(s, sigalg, pkey))
33796b13b45Sjsing 			return sigalg;
33896b13b45Sjsing 	}
33996b13b45Sjsing 
34096b13b45Sjsing 	return NULL;
34196b13b45Sjsing }
34221424b10Sjsing 
34321424b10Sjsing const struct ssl_sigalg *
ssl_sigalg_for_peer(SSL * s,EVP_PKEY * pkey,uint16_t sigalg_value)34421424b10Sjsing ssl_sigalg_for_peer(SSL *s, EVP_PKEY *pkey, uint16_t sigalg_value)
34521424b10Sjsing {
34621424b10Sjsing 	const struct ssl_sigalg *sigalg;
34721424b10Sjsing 
34821424b10Sjsing 	if (!SSL_USE_SIGALGS(s))
34921424b10Sjsing 		return ssl_sigalg_for_legacy(s, pkey);
35021424b10Sjsing 
351468bde53Sjsing 	if ((sigalg = ssl_sigalg_from_value(s, sigalg_value)) == NULL) {
35221424b10Sjsing 		SSLerror(s, SSL_R_UNKNOWN_DIGEST);
3530a11d68fStb 		return NULL;
35421424b10Sjsing 	}
35521424b10Sjsing 	if (!ssl_sigalg_pkey_ok(s, sigalg, pkey)) {
35621424b10Sjsing 		SSLerror(s, SSL_R_WRONG_SIGNATURE_TYPE);
3570a11d68fStb 		return NULL;
35821424b10Sjsing 	}
35921424b10Sjsing 
36021424b10Sjsing 	return sigalg;
36121424b10Sjsing }
362