Home | History | Annotate | Line # | Download | only in ssl
      1 /*
      2  * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
      3  * Copyright 2005 Nokia. All rights reserved.
      4  *
      5  * Licensed under the Apache License 2.0 (the "License").  You may not use
      6  * this file except in compliance with the License.  You can obtain a copy
      7  * in the file LICENSE in the source distribution or at
      8  * https://www.openssl.org/source/license.html
      9  */
     10 
     11 #include <stdio.h>
     12 #include "ssl_local.h"
     13 #include "record/record_local.h"
     14 #include "internal/ktls.h"
     15 #include "internal/cryptlib.h"
     16 #include "internal/ssl_unwrap.h"
     17 #include <openssl/comp.h>
     18 #include <openssl/evp.h>
     19 #include <openssl/kdf.h>
     20 #include <openssl/rand.h>
     21 #include <openssl/obj_mac.h>
     22 #include <openssl/core_names.h>
     23 #include <openssl/trace.h>
     24 
     25 /* seed1 through seed5 are concatenated */
     26 static int tls1_PRF(SSL_CONNECTION *s,
     27     const void *seed1, size_t seed1_len,
     28     const void *seed2, size_t seed2_len,
     29     const void *seed3, size_t seed3_len,
     30     const void *seed4, size_t seed4_len,
     31     const void *seed5, size_t seed5_len,
     32     const unsigned char *sec, size_t slen,
     33     unsigned char *out, size_t olen, int fatal)
     34 {
     35     const EVP_MD *md = ssl_prf_md(s);
     36     EVP_KDF *kdf;
     37     EVP_KDF_CTX *kctx = NULL;
     38     OSSL_PARAM params[8], *p = params;
     39     const char *mdname;
     40 
     41     if (md == NULL) {
     42         /* Should never happen */
     43         if (fatal)
     44             SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
     45         else
     46             ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
     47         return 0;
     48     }
     49     kdf = EVP_KDF_fetch(SSL_CONNECTION_GET_CTX(s)->libctx,
     50         OSSL_KDF_NAME_TLS1_PRF,
     51         SSL_CONNECTION_GET_CTX(s)->propq);
     52     if (kdf == NULL)
     53         goto err;
     54     kctx = EVP_KDF_CTX_new(kdf);
     55     EVP_KDF_free(kdf);
     56     if (kctx == NULL)
     57         goto err;
     58     mdname = EVP_MD_get0_name(md);
     59     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
     60         (char *)mdname, 0);
     61     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SECRET,
     62         (unsigned char *)sec,
     63         (size_t)slen);
     64     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED,
     65         (void *)seed1, (size_t)seed1_len);
     66     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED,
     67         (void *)seed2, (size_t)seed2_len);
     68     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED,
     69         (void *)seed3, (size_t)seed3_len);
     70     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED,
     71         (void *)seed4, (size_t)seed4_len);
     72     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED,
     73         (void *)seed5, (size_t)seed5_len);
     74     *p = OSSL_PARAM_construct_end();
     75     if (EVP_KDF_derive(kctx, out, olen, params)) {
     76         EVP_KDF_CTX_free(kctx);
     77         return 1;
     78     }
     79 
     80 err:
     81     if (fatal)
     82         SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
     83     else
     84         ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
     85     EVP_KDF_CTX_free(kctx);
     86     return 0;
     87 }
     88 
     89 static int tls1_generate_key_block(SSL_CONNECTION *s, unsigned char *km,
     90     size_t num)
     91 {
     92     int ret;
     93 
     94     /* Calls SSLfatal() as required */
     95     ret = tls1_PRF(s,
     96         TLS_MD_KEY_EXPANSION_CONST,
     97         TLS_MD_KEY_EXPANSION_CONST_SIZE, s->s3.server_random,
     98         SSL3_RANDOM_SIZE, s->s3.client_random, SSL3_RANDOM_SIZE,
     99         NULL, 0, NULL, 0, s->session->master_key,
    100         s->session->master_key_length, km, num, 1);
    101 
    102     return ret;
    103 }
    104 
    105 static int tls_iv_length_within_key_block(const EVP_CIPHER *c)
    106 {
    107     /* If GCM/CCM mode only part of IV comes from PRF */
    108     if (EVP_CIPHER_get_mode(c) == EVP_CIPH_GCM_MODE)
    109         return EVP_GCM_TLS_FIXED_IV_LEN;
    110     else if (EVP_CIPHER_get_mode(c) == EVP_CIPH_CCM_MODE)
    111         return EVP_CCM_TLS_FIXED_IV_LEN;
    112     else
    113         return EVP_CIPHER_get_iv_length(c);
    114 }
    115 
    116 int tls1_change_cipher_state(SSL_CONNECTION *s, int which)
    117 {
    118     unsigned char *p, *mac_secret;
    119     unsigned char *key, *iv;
    120     const EVP_CIPHER *c;
    121     const SSL_COMP *comp = NULL;
    122     const EVP_MD *m;
    123     int mac_type;
    124     size_t mac_secret_size;
    125     size_t n, i, j, k, cl;
    126     int iivlen;
    127     /*
    128      * Taglen is only relevant for CCM ciphersuites. Other ciphersuites
    129      * ignore this value so we can default it to 0.
    130      */
    131     size_t taglen = 0;
    132     int direction;
    133 
    134     c = s->s3.tmp.new_sym_enc;
    135     m = s->s3.tmp.new_hash;
    136     mac_type = s->s3.tmp.new_mac_pkey_type;
    137 #ifndef OPENSSL_NO_COMP
    138     comp = s->s3.tmp.new_compression;
    139 #endif
    140 
    141     p = s->s3.tmp.key_block;
    142     i = mac_secret_size = s->s3.tmp.new_mac_secret_size;
    143 
    144     cl = EVP_CIPHER_get_key_length(c);
    145     j = cl;
    146     iivlen = tls_iv_length_within_key_block(c);
    147     if (iivlen < 0) {
    148         SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
    149         goto err;
    150     }
    151     k = iivlen;
    152     if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || (which == SSL3_CHANGE_CIPHER_SERVER_READ)) {
    153         mac_secret = &(p[0]);
    154         n = i + i;
    155         key = &(p[n]);
    156         n += j + j;
    157         iv = &(p[n]);
    158         n += k + k;
    159     } else {
    160         n = i;
    161         mac_secret = &(p[n]);
    162         n += i + j;
    163         key = &(p[n]);
    164         n += j + k;
    165         iv = &(p[n]);
    166         n += k;
    167     }
    168 
    169     if (n > s->s3.tmp.key_block_length) {
    170         SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
    171         goto err;
    172     }
    173 
    174     switch (EVP_CIPHER_get_mode(c)) {
    175     case EVP_CIPH_GCM_MODE:
    176         taglen = EVP_GCM_TLS_TAG_LEN;
    177         break;
    178     case EVP_CIPH_CCM_MODE:
    179         if ((s->s3.tmp.new_cipher->algorithm_enc
    180                 & (SSL_AES128CCM8 | SSL_AES256CCM8))
    181             != 0)
    182             taglen = EVP_CCM8_TLS_TAG_LEN;
    183         else
    184             taglen = EVP_CCM_TLS_TAG_LEN;
    185         break;
    186     default:
    187         if (EVP_CIPHER_is_a(c, "CHACHA20-POLY1305")) {
    188             taglen = EVP_CHACHAPOLY_TLS_TAG_LEN;
    189         } else {
    190             /* MAC secret size corresponds to the MAC output size */
    191             taglen = s->s3.tmp.new_mac_secret_size;
    192         }
    193         break;
    194     }
    195 
    196     if (which & SSL3_CC_READ) {
    197         if (s->ext.use_etm)
    198             s->s3.flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC_READ;
    199         else
    200             s->s3.flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC_READ;
    201 
    202         if (s->s3.tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
    203             s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM;
    204         else
    205             s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM;
    206 
    207         if (s->s3.tmp.new_cipher->algorithm2 & TLS1_TLSTREE)
    208             s->mac_flags |= SSL_MAC_FLAG_READ_MAC_TLSTREE;
    209         else
    210             s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_TLSTREE;
    211 
    212         direction = OSSL_RECORD_DIRECTION_READ;
    213     } else {
    214         if (s->ext.use_etm)
    215             s->s3.flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE;
    216         else
    217             s->s3.flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE;
    218 
    219         if (s->s3.tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
    220             s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM;
    221         else
    222             s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM;
    223 
    224         if (s->s3.tmp.new_cipher->algorithm2 & TLS1_TLSTREE)
    225             s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_TLSTREE;
    226         else
    227             s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_TLSTREE;
    228 
    229         direction = OSSL_RECORD_DIRECTION_WRITE;
    230     }
    231 
    232     if (SSL_CONNECTION_IS_DTLS(s))
    233         dtls1_increment_epoch(s, which);
    234 
    235     if (!ssl_set_new_record_layer(s, s->version, direction,
    236             OSSL_RECORD_PROTECTION_LEVEL_APPLICATION,
    237             NULL, 0, key, cl, iv, (size_t)k, mac_secret,
    238             mac_secret_size, c, taglen, mac_type,
    239             m, comp, NULL)) {
    240         /* SSLfatal already called */
    241         goto err;
    242     }
    243 
    244     OSSL_TRACE_BEGIN(TLS)
    245     {
    246         BIO_printf(trc_out, "which = %04X, key:\n", which);
    247         BIO_dump_indent(trc_out, key, EVP_CIPHER_get_key_length(c), 4);
    248         BIO_printf(trc_out, "iv:\n");
    249         BIO_dump_indent(trc_out, iv, k, 4);
    250     }
    251     OSSL_TRACE_END(TLS);
    252 
    253     return 1;
    254 err:
    255     return 0;
    256 }
    257 
    258 int tls1_setup_key_block(SSL_CONNECTION *s)
    259 {
    260     unsigned char *p;
    261     const EVP_CIPHER *c;
    262     const EVP_MD *hash;
    263     SSL_COMP *comp;
    264     int mac_type = NID_undef;
    265     size_t num, mac_secret_size = 0;
    266     int ret = 0;
    267     int ivlen;
    268 
    269     if (s->s3.tmp.key_block_length != 0)
    270         return 1;
    271 
    272     if (!ssl_cipher_get_evp(SSL_CONNECTION_GET_CTX(s), s->session, &c, &hash,
    273             &mac_type, &mac_secret_size, &comp,
    274             s->ext.use_etm)) {
    275         /* Error is already recorded */
    276         SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR);
    277         return 0;
    278     }
    279 
    280     ssl_evp_cipher_free(s->s3.tmp.new_sym_enc);
    281     s->s3.tmp.new_sym_enc = c;
    282     ssl_evp_md_free(s->s3.tmp.new_hash);
    283     s->s3.tmp.new_hash = hash;
    284     s->s3.tmp.new_mac_pkey_type = mac_type;
    285     s->s3.tmp.new_mac_secret_size = mac_secret_size;
    286     ivlen = tls_iv_length_within_key_block(c);
    287     if (ivlen < 0) {
    288         SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
    289         return 0;
    290     }
    291     num = mac_secret_size + EVP_CIPHER_get_key_length(c) + ivlen;
    292     num *= 2;
    293 
    294     ssl3_cleanup_key_block(s);
    295 
    296     if ((p = OPENSSL_malloc(num)) == NULL) {
    297         SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB);
    298         goto err;
    299     }
    300 
    301     s->s3.tmp.key_block_length = num;
    302     s->s3.tmp.key_block = p;
    303 
    304     OSSL_TRACE_BEGIN(TLS)
    305     {
    306         BIO_printf(trc_out, "key block length: %zu\n", num);
    307         BIO_printf(trc_out, "client random\n");
    308         BIO_dump_indent(trc_out, s->s3.client_random, SSL3_RANDOM_SIZE, 4);
    309         BIO_printf(trc_out, "server random\n");
    310         BIO_dump_indent(trc_out, s->s3.server_random, SSL3_RANDOM_SIZE, 4);
    311         BIO_printf(trc_out, "master key\n");
    312         BIO_dump_indent(trc_out,
    313             s->session->master_key,
    314             s->session->master_key_length, 4);
    315     }
    316     OSSL_TRACE_END(TLS);
    317 
    318     if (!tls1_generate_key_block(s, p, num)) {
    319         /* SSLfatal() already called */
    320         goto err;
    321     }
    322 
    323     OSSL_TRACE_BEGIN(TLS)
    324     {
    325         BIO_printf(trc_out, "key block\n");
    326         BIO_dump_indent(trc_out, p, num, 4);
    327     }
    328     OSSL_TRACE_END(TLS);
    329 
    330     ret = 1;
    331 err:
    332     return ret;
    333 }
    334 
    335 size_t tls1_final_finish_mac(SSL_CONNECTION *s, const char *str,
    336     size_t slen, unsigned char *out)
    337 {
    338     size_t hashlen;
    339     unsigned char hash[EVP_MAX_MD_SIZE];
    340     size_t finished_size = TLS1_FINISH_MAC_LENGTH;
    341 
    342     if (s->s3.tmp.new_cipher->algorithm_mkey & SSL_kGOST18)
    343         finished_size = 32;
    344 
    345     if (!ssl3_digest_cached_records(s, 0)) {
    346         /* SSLfatal() already called */
    347         return 0;
    348     }
    349 
    350     if (!ssl_handshake_hash(s, hash, sizeof(hash), &hashlen)) {
    351         /* SSLfatal() already called */
    352         return 0;
    353     }
    354 
    355     if (!tls1_PRF(s, str, slen, hash, hashlen, NULL, 0, NULL, 0, NULL, 0,
    356             s->session->master_key, s->session->master_key_length,
    357             out, finished_size, 1)) {
    358         /* SSLfatal() already called */
    359         return 0;
    360     }
    361     OPENSSL_cleanse(hash, hashlen);
    362     return finished_size;
    363 }
    364 
    365 int tls1_generate_master_secret(SSL_CONNECTION *s, unsigned char *out,
    366     unsigned char *p, size_t len,
    367     size_t *secret_size)
    368 {
    369     if (s->session->flags & SSL_SESS_FLAG_EXTMS) {
    370         unsigned char hash[EVP_MAX_MD_SIZE * 2];
    371         size_t hashlen;
    372         /*
    373          * Digest cached records keeping record buffer (if present): this won't
    374          * affect client auth because we're freezing the buffer at the same
    375          * point (after client key exchange and before certificate verify)
    376          */
    377         if (!ssl3_digest_cached_records(s, 1)
    378             || !ssl_handshake_hash(s, hash, sizeof(hash), &hashlen)) {
    379             /* SSLfatal() already called */
    380             return 0;
    381         }
    382         OSSL_TRACE_BEGIN(TLS)
    383         {
    384             BIO_printf(trc_out, "Handshake hashes:\n");
    385             BIO_dump(trc_out, (char *)hash, hashlen);
    386         }
    387         OSSL_TRACE_END(TLS);
    388         if (!tls1_PRF(s,
    389                 TLS_MD_EXTENDED_MASTER_SECRET_CONST,
    390                 TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE,
    391                 hash, hashlen,
    392                 NULL, 0,
    393                 NULL, 0,
    394                 NULL, 0, p, len, out,
    395                 SSL3_MASTER_SECRET_SIZE, 1)) {
    396             /* SSLfatal() already called */
    397             return 0;
    398         }
    399         OPENSSL_cleanse(hash, hashlen);
    400     } else {
    401         if (!tls1_PRF(s,
    402                 TLS_MD_MASTER_SECRET_CONST,
    403                 TLS_MD_MASTER_SECRET_CONST_SIZE,
    404                 s->s3.client_random, SSL3_RANDOM_SIZE,
    405                 NULL, 0,
    406                 s->s3.server_random, SSL3_RANDOM_SIZE,
    407                 NULL, 0, p, len, out,
    408                 SSL3_MASTER_SECRET_SIZE, 1)) {
    409             /* SSLfatal() already called */
    410             return 0;
    411         }
    412     }
    413 
    414     OSSL_TRACE_BEGIN(TLS)
    415     {
    416         BIO_printf(trc_out, "Premaster Secret:\n");
    417         BIO_dump_indent(trc_out, p, len, 4);
    418         BIO_printf(trc_out, "Client Random:\n");
    419         BIO_dump_indent(trc_out, s->s3.client_random, SSL3_RANDOM_SIZE, 4);
    420         BIO_printf(trc_out, "Server Random:\n");
    421         BIO_dump_indent(trc_out, s->s3.server_random, SSL3_RANDOM_SIZE, 4);
    422         BIO_printf(trc_out, "Master Secret:\n");
    423         BIO_dump_indent(trc_out,
    424             s->session->master_key,
    425             SSL3_MASTER_SECRET_SIZE, 4);
    426     }
    427     OSSL_TRACE_END(TLS);
    428 
    429     *secret_size = SSL3_MASTER_SECRET_SIZE;
    430     return 1;
    431 }
    432 
    433 int tls1_export_keying_material(SSL_CONNECTION *s, unsigned char *out,
    434     size_t olen, const char *label, size_t llen,
    435     const unsigned char *context,
    436     size_t contextlen, int use_context)
    437 {
    438     unsigned char *val = NULL;
    439     size_t vallen = 0, currentvalpos;
    440     int rv = 0;
    441 
    442     /*
    443      * RFC 5705 embeds context length as uint16; reject longer context
    444      * before proceeding.
    445      */
    446     if (contextlen > 0xffff) {
    447         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
    448         return 0;
    449     }
    450 
    451     /*
    452      * construct PRF arguments we construct the PRF argument ourself rather
    453      * than passing separate values into the TLS PRF to ensure that the
    454      * concatenation of values does not create a prohibited label.
    455      */
    456     vallen = llen + SSL3_RANDOM_SIZE * 2;
    457     if (use_context) {
    458         vallen += 2 + contextlen;
    459     }
    460 
    461     val = OPENSSL_malloc(vallen);
    462     if (val == NULL)
    463         goto ret;
    464     currentvalpos = 0;
    465     memcpy(val + currentvalpos, (unsigned char *)label, llen);
    466     currentvalpos += llen;
    467     memcpy(val + currentvalpos, s->s3.client_random, SSL3_RANDOM_SIZE);
    468     currentvalpos += SSL3_RANDOM_SIZE;
    469     memcpy(val + currentvalpos, s->s3.server_random, SSL3_RANDOM_SIZE);
    470     currentvalpos += SSL3_RANDOM_SIZE;
    471 
    472     if (use_context) {
    473         val[currentvalpos] = (contextlen >> 8) & 0xff;
    474         currentvalpos++;
    475         val[currentvalpos] = contextlen & 0xff;
    476         currentvalpos++;
    477         if ((contextlen > 0) || (context != NULL)) {
    478             memcpy(val + currentvalpos, context, contextlen);
    479         }
    480     }
    481 
    482     /*
    483      * disallow prohibited labels note that SSL3_RANDOM_SIZE > max(prohibited
    484      * label len) = 15, so size of val > max(prohibited label len) = 15 and
    485      * the comparisons won't have buffer overflow
    486      */
    487     if (memcmp(val, TLS_MD_CLIENT_FINISH_CONST,
    488             TLS_MD_CLIENT_FINISH_CONST_SIZE)
    489         == 0)
    490         goto err1;
    491     if (memcmp(val, TLS_MD_SERVER_FINISH_CONST,
    492             TLS_MD_SERVER_FINISH_CONST_SIZE)
    493         == 0)
    494         goto err1;
    495     if (memcmp(val, TLS_MD_MASTER_SECRET_CONST,
    496             TLS_MD_MASTER_SECRET_CONST_SIZE)
    497         == 0)
    498         goto err1;
    499     if (memcmp(val, TLS_MD_EXTENDED_MASTER_SECRET_CONST,
    500             TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE)
    501         == 0)
    502         goto err1;
    503     if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST,
    504             TLS_MD_KEY_EXPANSION_CONST_SIZE)
    505         == 0)
    506         goto err1;
    507 
    508     rv = tls1_PRF(s,
    509         val, vallen,
    510         NULL, 0,
    511         NULL, 0,
    512         NULL, 0,
    513         NULL, 0,
    514         s->session->master_key, s->session->master_key_length,
    515         out, olen, 0);
    516 
    517     goto ret;
    518 err1:
    519     ERR_raise(ERR_LIB_SSL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL);
    520 ret:
    521     OPENSSL_clear_free(val, vallen);
    522     return rv;
    523 }
    524 
    525 int tls1_alert_code(int code)
    526 {
    527     switch (code) {
    528     case SSL_AD_CLOSE_NOTIFY:
    529         return SSL3_AD_CLOSE_NOTIFY;
    530     case SSL_AD_UNEXPECTED_MESSAGE:
    531         return SSL3_AD_UNEXPECTED_MESSAGE;
    532     case SSL_AD_BAD_RECORD_MAC:
    533         return SSL3_AD_BAD_RECORD_MAC;
    534     case SSL_AD_DECRYPTION_FAILED:
    535         return TLS1_AD_DECRYPTION_FAILED;
    536     case SSL_AD_RECORD_OVERFLOW:
    537         return TLS1_AD_RECORD_OVERFLOW;
    538     case SSL_AD_DECOMPRESSION_FAILURE:
    539         return SSL3_AD_DECOMPRESSION_FAILURE;
    540     case SSL_AD_HANDSHAKE_FAILURE:
    541         return SSL3_AD_HANDSHAKE_FAILURE;
    542     case SSL_AD_NO_CERTIFICATE:
    543         return -1;
    544     case SSL_AD_BAD_CERTIFICATE:
    545         return SSL3_AD_BAD_CERTIFICATE;
    546     case SSL_AD_UNSUPPORTED_CERTIFICATE:
    547         return SSL3_AD_UNSUPPORTED_CERTIFICATE;
    548     case SSL_AD_CERTIFICATE_REVOKED:
    549         return SSL3_AD_CERTIFICATE_REVOKED;
    550     case SSL_AD_CERTIFICATE_EXPIRED:
    551         return SSL3_AD_CERTIFICATE_EXPIRED;
    552     case SSL_AD_CERTIFICATE_UNKNOWN:
    553         return SSL3_AD_CERTIFICATE_UNKNOWN;
    554     case SSL_AD_ILLEGAL_PARAMETER:
    555         return SSL3_AD_ILLEGAL_PARAMETER;
    556     case SSL_AD_UNKNOWN_CA:
    557         return TLS1_AD_UNKNOWN_CA;
    558     case SSL_AD_ACCESS_DENIED:
    559         return TLS1_AD_ACCESS_DENIED;
    560     case SSL_AD_DECODE_ERROR:
    561         return TLS1_AD_DECODE_ERROR;
    562     case SSL_AD_DECRYPT_ERROR:
    563         return TLS1_AD_DECRYPT_ERROR;
    564     case SSL_AD_EXPORT_RESTRICTION:
    565         return TLS1_AD_EXPORT_RESTRICTION;
    566     case SSL_AD_PROTOCOL_VERSION:
    567         return TLS1_AD_PROTOCOL_VERSION;
    568     case SSL_AD_INSUFFICIENT_SECURITY:
    569         return TLS1_AD_INSUFFICIENT_SECURITY;
    570     case SSL_AD_INTERNAL_ERROR:
    571         return TLS1_AD_INTERNAL_ERROR;
    572     case SSL_AD_USER_CANCELLED:
    573         return TLS1_AD_USER_CANCELLED;
    574     case SSL_AD_NO_RENEGOTIATION:
    575         return TLS1_AD_NO_RENEGOTIATION;
    576     case SSL_AD_UNSUPPORTED_EXTENSION:
    577         return TLS1_AD_UNSUPPORTED_EXTENSION;
    578     case SSL_AD_CERTIFICATE_UNOBTAINABLE:
    579         return TLS1_AD_CERTIFICATE_UNOBTAINABLE;
    580     case SSL_AD_UNRECOGNIZED_NAME:
    581         return TLS1_AD_UNRECOGNIZED_NAME;
    582     case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
    583         return TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
    584     case SSL_AD_BAD_CERTIFICATE_HASH_VALUE:
    585         return TLS1_AD_BAD_CERTIFICATE_HASH_VALUE;
    586     case SSL_AD_UNKNOWN_PSK_IDENTITY:
    587         return TLS1_AD_UNKNOWN_PSK_IDENTITY;
    588     case SSL_AD_INAPPROPRIATE_FALLBACK:
    589         return TLS1_AD_INAPPROPRIATE_FALLBACK;
    590     case SSL_AD_NO_APPLICATION_PROTOCOL:
    591         return TLS1_AD_NO_APPLICATION_PROTOCOL;
    592     case SSL_AD_CERTIFICATE_REQUIRED:
    593         return SSL_AD_HANDSHAKE_FAILURE;
    594     case TLS13_AD_MISSING_EXTENSION:
    595         return SSL_AD_HANDSHAKE_FAILURE;
    596     default:
    597         return -1;
    598     }
    599 }
    600