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