Coverage Report

Created: 2026-08-31 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl/ssl/s3_enc.c
Line
Count
Source
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 <openssl/evp.h>
14
#include <openssl/core_names.h>
15
#include "internal/cryptlib.h"
16
#include "internal/ssl_unwrap.h"
17
18
void ssl3_cleanup_key_block(SSL_CONNECTION *s)
19
0
{
20
0
    OPENSSL_clear_free(s->s3.tmp.key_block, s->s3.tmp.key_block_length);
21
0
    s->s3.tmp.key_block = NULL;
22
0
    s->s3.tmp.key_block_length = 0;
23
0
}
24
25
int ssl3_init_finished_mac(SSL_CONNECTION *s)
26
0
{
27
0
    BIO *buf = BIO_new(BIO_s_mem());
28
29
0
    if (buf == NULL) {
30
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_BIO_LIB);
31
0
        return 0;
32
0
    }
33
0
    ssl3_free_digest_list(s);
34
0
    s->s3.handshake_buffer = buf;
35
0
    (void)BIO_set_close(s->s3.handshake_buffer, BIO_CLOSE);
36
0
    return 1;
37
0
}
38
39
/*
40
 * Free digest list. Also frees handshake buffer since they are always freed
41
 * together.
42
 */
43
44
void ssl3_free_digest_list(SSL_CONNECTION *s)
45
0
{
46
0
    BIO_free(s->s3.handshake_buffer);
47
0
    s->s3.handshake_buffer = NULL;
48
0
    EVP_MD_CTX_free(s->s3.handshake_dgst);
49
0
    s->s3.handshake_dgst = NULL;
50
0
}
51
52
int ssl3_finish_mac(SSL_CONNECTION *s, const unsigned char *buf, size_t len)
53
0
{
54
0
    int ret;
55
56
0
    if (s->s3.handshake_dgst == NULL) {
57
        /* Note: this writes to a memory BIO so a failure is a fatal error */
58
0
        if (len > INT_MAX) {
59
0
            SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_OVERFLOW_ERROR);
60
0
            return 0;
61
0
        }
62
0
        ret = BIO_write(s->s3.handshake_buffer, (void *)buf, (int)len);
63
0
        if (ret <= 0 || ret != (int)len) {
64
0
            SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
65
0
            return 0;
66
0
        }
67
0
    } else {
68
        /*
69
         * rfc9147:
70
         * In DTLS 1.3, the message transcript is computed over the
71
         * original TLS 1.3-style Handshake messages without the
72
         * message_seq, fragment_offset, and fragment_length values. Note
73
         * that this is a change from DTLS 1.2 where those values were
74
         * included in the transcript.
75
         *
76
         * So this means that we record the full handshake messages in
77
         * s->s3.handshake_buffer while s->s3.handshake_dgst is not in use and then
78
         * we calculate the digest when initiating s->s3.handshake_dgst at which
79
         * point we know what the protocol version is.
80
         */
81
0
        if (s->negotiated_version == DTLS1_3_VERSION) {
82
0
            if (!dtls13_transcript_hash_update(s->s3.handshake_dgst, buf, len)) {
83
0
                SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
84
0
                return 0;
85
0
            }
86
0
        } else {
87
0
            if (!EVP_DigestUpdate(s->s3.handshake_dgst, buf, len)) {
88
0
                SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
89
0
                return 0;
90
0
            }
91
0
        }
92
0
    }
93
0
    return 1;
94
0
}
95
96
int ssl3_digest_cached_records(SSL_CONNECTION *s, int keep)
97
0
{
98
0
    const EVP_MD *md;
99
0
    long hdatalen;
100
0
    void *hdata;
101
102
0
    if (s->s3.handshake_dgst == NULL) {
103
0
        hdatalen = BIO_get_mem_data(s->s3.handshake_buffer, &hdata);
104
0
        if (hdatalen <= 0) {
105
0
            SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_HANDSHAKE_LENGTH);
106
0
            return 0;
107
0
        }
108
109
0
        s->s3.handshake_dgst = EVP_MD_CTX_new();
110
0
        if (s->s3.handshake_dgst == NULL) {
111
0
            SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
112
0
            return 0;
113
0
        }
114
115
0
        md = ssl_handshake_md(s);
116
0
        if (md == NULL) {
117
0
            SSLfatal(s, SSL_AD_INTERNAL_ERROR,
118
0
                SSL_R_NO_SUITABLE_DIGEST_ALGORITHM);
119
0
            return 0;
120
0
        }
121
0
        if (!EVP_DigestInit_ex(s->s3.handshake_dgst, md, NULL)) {
122
0
            SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
123
0
            return 0;
124
0
        }
125
0
        if (!ssl3_finish_mac(s, hdata, hdatalen)) {
126
            /* SSLfatal() already called */
127
0
            return 0;
128
0
        }
129
0
    }
130
0
    if (keep == 0) {
131
0
        BIO_free(s->s3.handshake_buffer);
132
0
        s->s3.handshake_buffer = NULL;
133
0
    }
134
135
0
    return 1;
136
0
}