Coverage Report

Created: 2026-03-09 06:55

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
0
        ret = EVP_DigestUpdate(s->s3.handshake_dgst, buf, len);
69
0
        if (!ret) {
70
0
            SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
71
0
            return 0;
72
0
        }
73
0
    }
74
0
    return 1;
75
0
}
76
77
int ssl3_digest_cached_records(SSL_CONNECTION *s, int keep)
78
0
{
79
0
    const EVP_MD *md;
80
0
    long hdatalen;
81
0
    void *hdata;
82
83
0
    if (s->s3.handshake_dgst == NULL) {
84
0
        hdatalen = BIO_get_mem_data(s->s3.handshake_buffer, &hdata);
85
0
        if (hdatalen <= 0) {
86
0
            SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_HANDSHAKE_LENGTH);
87
0
            return 0;
88
0
        }
89
90
0
        s->s3.handshake_dgst = EVP_MD_CTX_new();
91
0
        if (s->s3.handshake_dgst == NULL) {
92
0
            SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
93
0
            return 0;
94
0
        }
95
96
0
        md = ssl_handshake_md(s);
97
0
        if (md == NULL) {
98
0
            SSLfatal(s, SSL_AD_INTERNAL_ERROR,
99
0
                SSL_R_NO_SUITABLE_DIGEST_ALGORITHM);
100
0
            return 0;
101
0
        }
102
0
        if (!EVP_DigestInit_ex(s->s3.handshake_dgst, md, NULL)
103
0
            || !EVP_DigestUpdate(s->s3.handshake_dgst, hdata, hdatalen)) {
104
0
            SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
105
0
            return 0;
106
0
        }
107
0
    }
108
0
    if (keep == 0) {
109
0
        BIO_free(s->s3.handshake_buffer);
110
0
        s->s3.handshake_buffer = NULL;
111
0
    }
112
113
0
    return 1;
114
0
}