1 // Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
2 // Copyright 2005 Nokia. All rights reserved.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // https://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15
16 #include <openssl/ssl.h>
17
18 #include <string_view>
19
20 #include <openssl/buf.h>
21 #include <openssl/digest.h>
22 #include <openssl/err.h>
23
24 #include "internal.h"
25
26
27 BSSL_NAMESPACE_BEGIN
28
SSLTranscript(bool is_dtls)29 SSLTranscript::SSLTranscript(bool is_dtls) : is_dtls_(is_dtls) {}
30
~SSLTranscript()31 SSLTranscript::~SSLTranscript() {}
32
Init()33 bool SSLTranscript::Init() {
34 buffer_.reset(BUF_MEM_new());
35 if (!buffer_) {
36 return false;
37 }
38
39 hash_.Reset();
40 return true;
41 }
42
InitHash(uint16_t version,const SSL_CIPHER * cipher)43 bool SSLTranscript::InitHash(uint16_t version, const SSL_CIPHER *cipher) {
44 version_ = version;
45 const EVP_MD *md = ssl_get_handshake_digest(version, cipher);
46 if (Digest() == md) {
47 // No need to re-hash the buffer.
48 return true;
49 }
50 if (!HashBuffer(hash_.get(), md)) {
51 return false;
52 }
53 if (is_dtls_ && version_ >= TLS1_3_VERSION) {
54 // In DTLS 1.3, prior to the call to InitHash, the message (if present) in
55 // the buffer has the DTLS 1.2 header. After the call to InitHash, the TLS
56 // 1.3 header is written by SSLTranscript::Update. If the buffer isn't freed
57 // here, it would have a mix of different header formats and using it would
58 // yield wrong results. However, there's no need for the buffer once the
59 // version and the digest for the cipher suite are known, so the buffer is
60 // freed here to avoid potential misuse of the SSLTranscript object.
61 FreeBuffer();
62 }
63 return true;
64 }
65
HashBuffer(EVP_MD_CTX * ctx,const EVP_MD * digest) const66 bool SSLTranscript::HashBuffer(EVP_MD_CTX *ctx, const EVP_MD *digest) const {
67 if (!EVP_DigestInit_ex(ctx, digest, nullptr)) {
68 return false;
69 }
70 if (!is_dtls_ || version_ < TLS1_3_VERSION) {
71 return EVP_DigestUpdate(ctx, buffer_->data, buffer_->length);
72 }
73
74 // If the version is DTLS 1.3 and we still have a buffer, then there should be
75 // at most a single DTLSHandshake message in the buffer, for the ClientHello.
76 // On the server side, the version (DTLS 1.3) and cipher suite are chosen in
77 // response to the first ClientHello, and InitHash is called before that
78 // ClientHello is added to the SSLTranscript, so the buffer is empty if this
79 // SSLTranscript is on the server.
80 if (buffer_->length == 0) {
81 return true;
82 }
83
84 // On the client side, we can receive either a ServerHello or
85 // HelloRetryRequest in response to the ClientHello. Regardless of which
86 // message we receive, the client code calls InitHash before updating the
87 // transcript with that message, so the ClientHello is the only message in the
88 // buffer. In DTLS 1.3, we need to skip the message_seq, fragment_offset, and
89 // fragment_length fields from the DTLSHandshake message in the buffer. The
90 // structure of a DTLSHandshake message is as follows (RFC 9147, section 5.2):
91 //
92 // struct {
93 // HandshakeType msg_type; /* handshake type */
94 // uint24 length; /* bytes in message */
95 // uint16 message_seq; /* DTLS-required field */
96 // uint24 fragment_offset; /* DTLS-required field */
97 // uint24 fragment_length; /* DTLS-required field */
98 // select (msg_type) {
99 // /* omitted for brevity */
100 // } body;
101 // } DTLSHandshake;
102 CBS buf, header;
103 CBS_init(&buf, reinterpret_cast<uint8_t *>(buffer_->data), buffer_->length);
104 if (!CBS_get_bytes(&buf, &header, 4) || //
105 !CBS_skip(&buf, 8) || //
106 !EVP_DigestUpdate(ctx, CBS_data(&header), CBS_len(&header)) || //
107 !EVP_DigestUpdate(ctx, CBS_data(&buf), CBS_len(&buf))) {
108 return false;
109 }
110 return true;
111 }
112
FreeBuffer()113 void SSLTranscript::FreeBuffer() { buffer_.reset(); }
114
DigestLen() const115 size_t SSLTranscript::DigestLen() const { return EVP_MD_size(Digest()); }
116
Digest() const117 const EVP_MD *SSLTranscript::Digest() const {
118 return EVP_MD_CTX_get0_md(hash_.get());
119 }
120
UpdateForHelloRetryRequest()121 bool SSLTranscript::UpdateForHelloRetryRequest() {
122 if (buffer_) {
123 buffer_->length = 0;
124 }
125
126 uint8_t old_hash[EVP_MAX_MD_SIZE];
127 size_t hash_len;
128 if (!GetHash(old_hash, &hash_len)) {
129 return false;
130 }
131 const uint8_t header[4] = {SSL3_MT_MESSAGE_HASH, 0, 0,
132 static_cast<uint8_t>(hash_len)};
133 if (!EVP_DigestInit_ex(hash_.get(), Digest(), nullptr) ||
134 !AddToBufferOrHash(header) ||
135 !AddToBufferOrHash(Span(old_hash, hash_len))) {
136 return false;
137 }
138 return true;
139 }
140
CopyToHashContext(EVP_MD_CTX * ctx,const EVP_MD * digest) const141 bool SSLTranscript::CopyToHashContext(EVP_MD_CTX *ctx,
142 const EVP_MD *digest) const {
143 const EVP_MD *transcript_digest = Digest();
144 if (transcript_digest != nullptr &&
145 EVP_MD_type(transcript_digest) == EVP_MD_type(digest)) {
146 return EVP_MD_CTX_copy_ex(ctx, hash_.get());
147 }
148
149 if (buffer_) {
150 return HashBuffer(ctx, digest);
151 }
152
153 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
154 return false;
155 }
156
Update(Span<const uint8_t> in)157 bool SSLTranscript::Update(Span<const uint8_t> in) {
158 if (!is_dtls_ || version_ < TLS1_3_VERSION) {
159 return AddToBufferOrHash(in);
160 }
161 if (in.size() < DTLS1_HM_HEADER_LENGTH) {
162 return false;
163 }
164 // The message passed into Update is the whole Handshake or DTLSHandshake
165 // message, including the msg_type and length. In DTLS, the DTLSHandshake
166 // message also has message_seq, fragment_offset, and fragment_length
167 // fields. In DTLS 1.3, those fields are omitted so that the same
168 // transcript format as TLS 1.3 is used. This means we write the 1-byte
169 // msg_type, 3-byte length, then skip 2+3+3 bytes for the DTLS-specific
170 // fields that get omitted.
171 if (!AddToBufferOrHash(in.subspan(0, 4)) ||
172 !AddToBufferOrHash(in.subspan(12))) {
173 return false;
174 }
175 return true;
176 }
177
AddToBufferOrHash(Span<const uint8_t> in)178 bool SSLTranscript::AddToBufferOrHash(Span<const uint8_t> in) {
179 // Depending on the state of the handshake, either the handshake buffer may be
180 // active, the rolling hash, or both.
181 if (buffer_ && //
182 !BUF_MEM_append(buffer_.get(), in.data(), in.size())) {
183 return false;
184 }
185
186 if (EVP_MD_CTX_md(hash_.get()) != NULL) {
187 EVP_DigestUpdate(hash_.get(), in.data(), in.size());
188 }
189
190 return true;
191 }
192
GetHash(uint8_t * out,size_t * out_len) const193 bool SSLTranscript::GetHash(uint8_t *out, size_t *out_len) const {
194 ScopedEVP_MD_CTX ctx;
195 unsigned len;
196 if (!EVP_MD_CTX_copy_ex(ctx.get(), hash_.get()) ||
197 !EVP_DigestFinal_ex(ctx.get(), out, &len)) {
198 return false;
199 }
200 *out_len = len;
201 return true;
202 }
203
GetFinishedMAC(uint8_t * out,size_t * out_len,const SSL_SESSION * session,bool from_server) const204 bool SSLTranscript::GetFinishedMAC(uint8_t *out, size_t *out_len,
205 const SSL_SESSION *session,
206 bool from_server) const {
207 uint8_t digest[EVP_MAX_MD_SIZE];
208 size_t digest_len;
209 if (!GetHash(digest, &digest_len)) {
210 return false;
211 }
212
213 std::string_view label = from_server ? "server finished" : "client finished";
214 static const size_t kFinishedLen = 12;
215 if (!tls1_prf(Digest(), Span(out, kFinishedLen), session->secret, label,
216 Span(digest, digest_len), {})) {
217 return false;
218 }
219
220 *out_len = kFinishedLen;
221 return true;
222 }
223
224 BSSL_NAMESPACE_END
225