1*8edacedfSDaniel Fojt /* $OpenBSD: ssl_sigalgs.c,v 1.21 2020/05/09 16:52:15 beck Exp $ */ 272c33676SMaxim Ag /* 3*8edacedfSDaniel Fojt * Copyright (c) 2018-2020 Bob Beck <beck@openbsd.org> 472c33676SMaxim Ag * 572c33676SMaxim Ag * Permission to use, copy, modify, and/or distribute this software for any 672c33676SMaxim Ag * purpose with or without fee is hereby granted, provided that the above 772c33676SMaxim Ag * copyright notice and this permission notice appear in all copies. 872c33676SMaxim Ag * 972c33676SMaxim Ag * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1072c33676SMaxim Ag * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1172c33676SMaxim Ag * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 1272c33676SMaxim Ag * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1372c33676SMaxim Ag * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 1472c33676SMaxim Ag * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 1572c33676SMaxim Ag * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1672c33676SMaxim Ag */ 1772c33676SMaxim Ag #include <string.h> 1872c33676SMaxim Ag #include <stdlib.h> 1972c33676SMaxim Ag 2072c33676SMaxim Ag #include <openssl/evp.h> 2172c33676SMaxim Ag 2272c33676SMaxim Ag #include "bytestring.h" 2372c33676SMaxim Ag #include "ssl_locl.h" 2472c33676SMaxim Ag #include "ssl_sigalgs.h" 2572c33676SMaxim Ag #include "tls13_internal.h" 2672c33676SMaxim Ag 2772c33676SMaxim Ag const struct ssl_sigalg sigalgs[] = { 2872c33676SMaxim Ag { 2972c33676SMaxim Ag .value = SIGALG_RSA_PKCS1_SHA512, 3072c33676SMaxim Ag .md = EVP_sha512, 3172c33676SMaxim Ag .key_type = EVP_PKEY_RSA, 3272c33676SMaxim Ag }, 3372c33676SMaxim Ag { 3472c33676SMaxim Ag .value = SIGALG_ECDSA_SECP521R1_SHA512, 3572c33676SMaxim Ag .md = EVP_sha512, 3672c33676SMaxim Ag .key_type = EVP_PKEY_EC, 3772c33676SMaxim Ag .curve_nid = NID_secp521r1, 3872c33676SMaxim Ag }, 3972c33676SMaxim Ag #ifndef OPENSSL_NO_GOST 4072c33676SMaxim Ag { 4172c33676SMaxim Ag .value = SIGALG_GOSTR12_512_STREEBOG_512, 4272c33676SMaxim Ag .md = EVP_streebog512, 4372c33676SMaxim Ag .key_type = EVP_PKEY_GOSTR12_512, 4472c33676SMaxim Ag }, 4572c33676SMaxim Ag #endif 4672c33676SMaxim Ag { 4772c33676SMaxim Ag .value = SIGALG_RSA_PKCS1_SHA384, 4872c33676SMaxim Ag .md = EVP_sha384, 4972c33676SMaxim Ag .key_type = EVP_PKEY_RSA, 5072c33676SMaxim Ag }, 5172c33676SMaxim Ag { 5272c33676SMaxim Ag .value = SIGALG_ECDSA_SECP384R1_SHA384, 5372c33676SMaxim Ag .md = EVP_sha384, 5472c33676SMaxim Ag .key_type = EVP_PKEY_EC, 5572c33676SMaxim Ag .curve_nid = NID_secp384r1, 5672c33676SMaxim Ag }, 5772c33676SMaxim Ag { 5872c33676SMaxim Ag .value = SIGALG_RSA_PKCS1_SHA256, 5972c33676SMaxim Ag .md = EVP_sha256, 6072c33676SMaxim Ag .key_type = EVP_PKEY_RSA, 6172c33676SMaxim Ag }, 6272c33676SMaxim Ag { 6372c33676SMaxim Ag .value = SIGALG_ECDSA_SECP256R1_SHA256, 6472c33676SMaxim Ag .md = EVP_sha256, 6572c33676SMaxim Ag .key_type = EVP_PKEY_EC, 6672c33676SMaxim Ag .curve_nid = NID_X9_62_prime256v1, 6772c33676SMaxim Ag }, 6872c33676SMaxim Ag #ifndef OPENSSL_NO_GOST 6972c33676SMaxim Ag { 7072c33676SMaxim Ag .value = SIGALG_GOSTR12_256_STREEBOG_256, 7172c33676SMaxim Ag .md = EVP_streebog256, 7272c33676SMaxim Ag .key_type = EVP_PKEY_GOSTR12_256, 7372c33676SMaxim Ag }, 7472c33676SMaxim Ag { 7572c33676SMaxim Ag .value = SIGALG_GOSTR01_GOST94, 7672c33676SMaxim Ag .md = EVP_gostr341194, 7772c33676SMaxim Ag .key_type = EVP_PKEY_GOSTR01, 7872c33676SMaxim Ag }, 7972c33676SMaxim Ag #endif 8072c33676SMaxim Ag { 8172c33676SMaxim Ag .value = SIGALG_RSA_PSS_RSAE_SHA256, 8272c33676SMaxim Ag .md = EVP_sha256, 8372c33676SMaxim Ag .key_type = EVP_PKEY_RSA, 8472c33676SMaxim Ag .flags = SIGALG_FLAG_RSA_PSS, 8572c33676SMaxim Ag }, 8672c33676SMaxim Ag { 8772c33676SMaxim Ag .value = SIGALG_RSA_PSS_RSAE_SHA384, 8872c33676SMaxim Ag .md = EVP_sha384, 8972c33676SMaxim Ag .key_type = EVP_PKEY_RSA, 9072c33676SMaxim Ag .flags = SIGALG_FLAG_RSA_PSS, 9172c33676SMaxim Ag }, 9272c33676SMaxim Ag { 9372c33676SMaxim Ag .value = SIGALG_RSA_PSS_RSAE_SHA512, 9472c33676SMaxim Ag .md = EVP_sha512, 9572c33676SMaxim Ag .key_type = EVP_PKEY_RSA, 9672c33676SMaxim Ag .flags = SIGALG_FLAG_RSA_PSS, 9772c33676SMaxim Ag }, 9872c33676SMaxim Ag { 9972c33676SMaxim Ag .value = SIGALG_RSA_PSS_PSS_SHA256, 10072c33676SMaxim Ag .md = EVP_sha256, 10172c33676SMaxim Ag .key_type = EVP_PKEY_RSA, 10272c33676SMaxim Ag .flags = SIGALG_FLAG_RSA_PSS, 10372c33676SMaxim Ag }, 10472c33676SMaxim Ag { 10572c33676SMaxim Ag .value = SIGALG_RSA_PSS_PSS_SHA384, 10672c33676SMaxim Ag .md = EVP_sha384, 10772c33676SMaxim Ag .key_type = EVP_PKEY_RSA, 10872c33676SMaxim Ag .flags = SIGALG_FLAG_RSA_PSS, 10972c33676SMaxim Ag }, 11072c33676SMaxim Ag { 11172c33676SMaxim Ag .value = SIGALG_RSA_PSS_PSS_SHA512, 11272c33676SMaxim Ag .md = EVP_sha512, 11372c33676SMaxim Ag .key_type = EVP_PKEY_RSA, 11472c33676SMaxim Ag .flags = SIGALG_FLAG_RSA_PSS, 11572c33676SMaxim Ag }, 11672c33676SMaxim Ag { 11772c33676SMaxim Ag .value = SIGALG_RSA_PKCS1_SHA224, 11872c33676SMaxim Ag .md = EVP_sha224, 11972c33676SMaxim Ag .key_type = EVP_PKEY_RSA, 12072c33676SMaxim Ag }, 12172c33676SMaxim Ag { 12272c33676SMaxim Ag .value = SIGALG_ECDSA_SECP224R1_SHA224, 12372c33676SMaxim Ag .md = EVP_sha224, 12472c33676SMaxim Ag .key_type = EVP_PKEY_EC, 12572c33676SMaxim Ag }, 12672c33676SMaxim Ag { 12772c33676SMaxim Ag .value = SIGALG_RSA_PKCS1_SHA1, 12872c33676SMaxim Ag .key_type = EVP_PKEY_RSA, 12972c33676SMaxim Ag .md = EVP_sha1, 13072c33676SMaxim Ag }, 13172c33676SMaxim Ag { 13272c33676SMaxim Ag .value = SIGALG_ECDSA_SHA1, 13372c33676SMaxim Ag .key_type = EVP_PKEY_EC, 13472c33676SMaxim Ag .md = EVP_sha1, 13572c33676SMaxim Ag }, 13672c33676SMaxim Ag { 13772c33676SMaxim Ag .value = SIGALG_RSA_PKCS1_MD5_SHA1, 13872c33676SMaxim Ag .key_type = EVP_PKEY_RSA, 13972c33676SMaxim Ag .md = EVP_md5_sha1, 14072c33676SMaxim Ag }, 14172c33676SMaxim Ag { 14272c33676SMaxim Ag .value = SIGALG_NONE, 14372c33676SMaxim Ag }, 14472c33676SMaxim Ag }; 14572c33676SMaxim Ag 14672c33676SMaxim Ag /* Sigalgs for tls 1.3, in preference order, */ 14772c33676SMaxim Ag uint16_t tls13_sigalgs[] = { 14872c33676SMaxim Ag SIGALG_RSA_PSS_RSAE_SHA512, 14972c33676SMaxim Ag SIGALG_RSA_PKCS1_SHA512, 15072c33676SMaxim Ag SIGALG_ECDSA_SECP521R1_SHA512, 15172c33676SMaxim Ag SIGALG_RSA_PSS_RSAE_SHA384, 15272c33676SMaxim Ag SIGALG_RSA_PKCS1_SHA384, 15372c33676SMaxim Ag SIGALG_ECDSA_SECP384R1_SHA384, 15472c33676SMaxim Ag SIGALG_RSA_PSS_RSAE_SHA256, 15572c33676SMaxim Ag SIGALG_RSA_PKCS1_SHA256, 15672c33676SMaxim Ag SIGALG_ECDSA_SECP256R1_SHA256, 15772c33676SMaxim Ag }; 15872c33676SMaxim Ag size_t tls13_sigalgs_len = (sizeof(tls13_sigalgs) / sizeof(tls13_sigalgs[0])); 15972c33676SMaxim Ag 16072c33676SMaxim Ag /* Sigalgs for tls 1.2, in preference order, */ 16172c33676SMaxim Ag uint16_t tls12_sigalgs[] = { 16272c33676SMaxim Ag SIGALG_RSA_PSS_RSAE_SHA512, 16372c33676SMaxim Ag SIGALG_RSA_PKCS1_SHA512, 16472c33676SMaxim Ag SIGALG_ECDSA_SECP521R1_SHA512, 16572c33676SMaxim Ag SIGALG_RSA_PSS_RSAE_SHA384, 16672c33676SMaxim Ag SIGALG_RSA_PKCS1_SHA384, 16772c33676SMaxim Ag SIGALG_ECDSA_SECP384R1_SHA384, 16872c33676SMaxim Ag SIGALG_RSA_PSS_RSAE_SHA256, 16972c33676SMaxim Ag SIGALG_RSA_PKCS1_SHA256, 17072c33676SMaxim Ag SIGALG_ECDSA_SECP256R1_SHA256, 17172c33676SMaxim Ag SIGALG_RSA_PKCS1_SHA1, /* XXX */ 17272c33676SMaxim Ag SIGALG_ECDSA_SHA1, /* XXX */ 17372c33676SMaxim Ag }; 17472c33676SMaxim Ag size_t tls12_sigalgs_len = (sizeof(tls12_sigalgs) / sizeof(tls12_sigalgs[0])); 17572c33676SMaxim Ag 17672c33676SMaxim Ag const struct ssl_sigalg * 17772c33676SMaxim Ag ssl_sigalg_lookup(uint16_t sigalg) 17872c33676SMaxim Ag { 17972c33676SMaxim Ag int i; 18072c33676SMaxim Ag 18172c33676SMaxim Ag for (i = 0; sigalgs[i].value != SIGALG_NONE; i++) { 18272c33676SMaxim Ag if (sigalgs[i].value == sigalg) 18372c33676SMaxim Ag return &sigalgs[i]; 18472c33676SMaxim Ag } 18572c33676SMaxim Ag 18672c33676SMaxim Ag return NULL; 18772c33676SMaxim Ag } 18872c33676SMaxim Ag 18972c33676SMaxim Ag const struct ssl_sigalg * 19072c33676SMaxim Ag ssl_sigalg(uint16_t sigalg, uint16_t *values, size_t len) 19172c33676SMaxim Ag { 19272c33676SMaxim Ag int i; 19372c33676SMaxim Ag 19472c33676SMaxim Ag for (i = 0; i < len; i++) { 19572c33676SMaxim Ag if (values[i] == sigalg) 19672c33676SMaxim Ag return ssl_sigalg_lookup(sigalg); 19772c33676SMaxim Ag } 19872c33676SMaxim Ag 19972c33676SMaxim Ag return NULL; 20072c33676SMaxim Ag } 20172c33676SMaxim Ag 20272c33676SMaxim Ag int 20372c33676SMaxim Ag ssl_sigalgs_build(CBB *cbb, uint16_t *values, size_t len) 20472c33676SMaxim Ag { 20572c33676SMaxim Ag size_t i; 20672c33676SMaxim Ag 20772c33676SMaxim Ag for (i = 0; sigalgs[i].value != SIGALG_NONE; i++); 20872c33676SMaxim Ag if (len > i) 20972c33676SMaxim Ag return 0; 21072c33676SMaxim Ag 21172c33676SMaxim Ag /* XXX check for duplicates and other sanity BS? */ 21272c33676SMaxim Ag 21372c33676SMaxim Ag /* Add values in order as long as they are supported. */ 21472c33676SMaxim Ag for (i = 0; i < len; i++) { 21572c33676SMaxim Ag /* Do not allow the legacy value for < 1.2 to be used */ 21672c33676SMaxim Ag if (values[i] == SIGALG_RSA_PKCS1_MD5_SHA1) 21772c33676SMaxim Ag return 0; 21872c33676SMaxim Ag 21972c33676SMaxim Ag if (ssl_sigalg_lookup(values[i]) != NULL) { 22072c33676SMaxim Ag if (!CBB_add_u16(cbb, values[i])) 22172c33676SMaxim Ag return 0; 22272c33676SMaxim Ag } else 22372c33676SMaxim Ag return 0; 22472c33676SMaxim Ag } 22572c33676SMaxim Ag return 1; 22672c33676SMaxim Ag } 22772c33676SMaxim Ag 22872c33676SMaxim Ag int 22972c33676SMaxim Ag ssl_sigalg_pkey_ok(const struct ssl_sigalg *sigalg, EVP_PKEY *pkey, 23072c33676SMaxim Ag int check_curve) 23172c33676SMaxim Ag { 23272c33676SMaxim Ag if (sigalg == NULL || pkey == NULL) 23372c33676SMaxim Ag return 0; 23472c33676SMaxim Ag if (sigalg->key_type != pkey->type) 23572c33676SMaxim Ag return 0; 23672c33676SMaxim Ag 23772c33676SMaxim Ag if ((sigalg->flags & SIGALG_FLAG_RSA_PSS)) { 23872c33676SMaxim Ag /* 23972c33676SMaxim Ag * RSA PSS Must have an RSA key that needs to be at 24072c33676SMaxim Ag * least as big as twice the size of the hash + 2 24172c33676SMaxim Ag */ 24272c33676SMaxim Ag if (pkey->type != EVP_PKEY_RSA || 24372c33676SMaxim Ag EVP_PKEY_size(pkey) < (2 * EVP_MD_size(sigalg->md()) + 2)) 24472c33676SMaxim Ag return 0; 24572c33676SMaxim Ag } 24672c33676SMaxim Ag 24772c33676SMaxim Ag if (pkey->type == EVP_PKEY_EC && check_curve) { 24872c33676SMaxim Ag /* Curve must match for EC keys. */ 24972c33676SMaxim Ag if (sigalg->curve_nid == 0) 25072c33676SMaxim Ag return 0; 25172c33676SMaxim Ag if (EC_GROUP_get_curve_name(EC_KEY_get0_group 25272c33676SMaxim Ag (EVP_PKEY_get0_EC_KEY(pkey))) != sigalg->curve_nid) { 25372c33676SMaxim Ag return 0; 25472c33676SMaxim Ag } 25572c33676SMaxim Ag } 25672c33676SMaxim Ag 25772c33676SMaxim Ag return 1; 25872c33676SMaxim Ag } 25972c33676SMaxim Ag 26072c33676SMaxim Ag const struct ssl_sigalg * 26172c33676SMaxim Ag ssl_sigalg_select(SSL *s, EVP_PKEY *pkey) 26272c33676SMaxim Ag { 26372c33676SMaxim Ag uint16_t *tls_sigalgs = tls12_sigalgs; 26472c33676SMaxim Ag size_t tls_sigalgs_len = tls12_sigalgs_len; 26572c33676SMaxim Ag int check_curve = 0; 26672c33676SMaxim Ag CBS cbs; 26772c33676SMaxim Ag 26872c33676SMaxim Ag if (TLS1_get_version(s) >= TLS1_3_VERSION) { 26972c33676SMaxim Ag tls_sigalgs = tls13_sigalgs; 27072c33676SMaxim Ag tls_sigalgs_len = tls13_sigalgs_len; 27172c33676SMaxim Ag check_curve = 1; 27272c33676SMaxim Ag } 27372c33676SMaxim Ag 27472c33676SMaxim Ag /* Pre TLS 1.2 defaults */ 27572c33676SMaxim Ag if (!SSL_USE_SIGALGS(s)) { 27672c33676SMaxim Ag switch (pkey->type) { 27772c33676SMaxim Ag case EVP_PKEY_RSA: 27872c33676SMaxim Ag return ssl_sigalg_lookup(SIGALG_RSA_PKCS1_MD5_SHA1); 27972c33676SMaxim Ag case EVP_PKEY_EC: 28072c33676SMaxim Ag return ssl_sigalg_lookup(SIGALG_ECDSA_SHA1); 28172c33676SMaxim Ag #ifndef OPENSSL_NO_GOST 28272c33676SMaxim Ag case EVP_PKEY_GOSTR01: 28372c33676SMaxim Ag return ssl_sigalg_lookup(SIGALG_GOSTR01_GOST94); 28472c33676SMaxim Ag #endif 28572c33676SMaxim Ag } 28672c33676SMaxim Ag SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE); 28772c33676SMaxim Ag return (NULL); 28872c33676SMaxim Ag } 28972c33676SMaxim Ag 29072c33676SMaxim Ag /* 29172c33676SMaxim Ag * RFC 5246 allows a TLS 1.2 client to send no sigalgs, in 29272c33676SMaxim Ag * which case the server must use the the default. 29372c33676SMaxim Ag */ 29472c33676SMaxim Ag if (TLS1_get_version(s) < TLS1_3_VERSION && 29572c33676SMaxim Ag S3I(s)->hs.sigalgs == NULL) { 29672c33676SMaxim Ag switch (pkey->type) { 29772c33676SMaxim Ag case EVP_PKEY_RSA: 29872c33676SMaxim Ag return ssl_sigalg_lookup(SIGALG_RSA_PKCS1_SHA1); 29972c33676SMaxim Ag case EVP_PKEY_EC: 30072c33676SMaxim Ag return ssl_sigalg_lookup(SIGALG_ECDSA_SHA1); 30172c33676SMaxim Ag #ifndef OPENSSL_NO_GOST 30272c33676SMaxim Ag case EVP_PKEY_GOSTR01: 30372c33676SMaxim Ag return ssl_sigalg_lookup(SIGALG_GOSTR01_GOST94); 30472c33676SMaxim Ag #endif 30572c33676SMaxim Ag } 30672c33676SMaxim Ag SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE); 30772c33676SMaxim Ag return (NULL); 30872c33676SMaxim Ag } 30972c33676SMaxim Ag 31072c33676SMaxim Ag /* 31172c33676SMaxim Ag * If we get here, we have client or server sent sigalgs, use one. 31272c33676SMaxim Ag */ 31372c33676SMaxim Ag CBS_init(&cbs, S3I(s)->hs.sigalgs, S3I(s)->hs.sigalgs_len); 31472c33676SMaxim Ag while (CBS_len(&cbs) > 0) { 31572c33676SMaxim Ag uint16_t sig_alg; 31672c33676SMaxim Ag const struct ssl_sigalg *sigalg; 31772c33676SMaxim Ag 31872c33676SMaxim Ag if (!CBS_get_u16(&cbs, &sig_alg)) 31972c33676SMaxim Ag return 0; 32072c33676SMaxim Ag 32172c33676SMaxim Ag if ((sigalg = ssl_sigalg(sig_alg, tls_sigalgs, 32272c33676SMaxim Ag tls_sigalgs_len)) == NULL) 32372c33676SMaxim Ag continue; 32472c33676SMaxim Ag 325f015dc58SDaniel Fojt /* RSA cannot be used without PSS in TLSv1.3. */ 326f015dc58SDaniel Fojt if (TLS1_get_version(s) >= TLS1_3_VERSION && 327f015dc58SDaniel Fojt sigalg->key_type == EVP_PKEY_RSA && 328f015dc58SDaniel Fojt (sigalg->flags & SIGALG_FLAG_RSA_PSS) == 0) 329f015dc58SDaniel Fojt continue; 330f015dc58SDaniel Fojt 33172c33676SMaxim Ag if (ssl_sigalg_pkey_ok(sigalg, pkey, check_curve)) 33272c33676SMaxim Ag return sigalg; 33372c33676SMaxim Ag } 33472c33676SMaxim Ag 33572c33676SMaxim Ag SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE); 33672c33676SMaxim Ag return NULL; 33772c33676SMaxim Ag } 338