blob: 4a00d0f2565b86dc29f62d18690d6aad5683f05b [file] [log] [blame]
Adam Langley95c29f32014-06-20 12:00:00 -07001/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
David Benjamin820731a2015-07-23 20:01:51 -04007 *
Adam Langley95c29f32014-06-20 12:00:00 -07008 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
David Benjamin820731a2015-07-23 20:01:51 -040014 *
Adam Langley95c29f32014-06-20 12:00:00 -070015 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
David Benjamin820731a2015-07-23 20:01:51 -040021 *
Adam Langley95c29f32014-06-20 12:00:00 -070022 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
David Benjamin820731a2015-07-23 20:01:51 -040036 * 4. If you include any Windows specific code (or a derivative thereof) from
Adam Langley95c29f32014-06-20 12:00:00 -070037 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
David Benjamin820731a2015-07-23 20:01:51 -040039 *
Adam Langley95c29f32014-06-20 12:00:00 -070040 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
David Benjamin820731a2015-07-23 20:01:51 -040051 *
Adam Langley95c29f32014-06-20 12:00:00 -070052 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.]
56 */
57/* ====================================================================
58 * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved.
59 *
60 * Redistribution and use in source and binary forms, with or without
61 * modification, are permitted provided that the following conditions
62 * are met:
63 *
64 * 1. Redistributions of source code must retain the above copyright
David Benjamin820731a2015-07-23 20:01:51 -040065 * notice, this list of conditions and the following disclaimer.
Adam Langley95c29f32014-06-20 12:00:00 -070066 *
67 * 2. Redistributions in binary form must reproduce the above copyright
68 * notice, this list of conditions and the following disclaimer in
69 * the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3. All advertising materials mentioning features or use of this
73 * software must display the following acknowledgment:
74 * "This product includes software developed by the OpenSSL Project
75 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
76 *
77 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
78 * endorse or promote products derived from this software without
79 * prior written permission. For written permission, please contact
80 * openssl-core@openssl.org.
81 *
82 * 5. Products derived from this software may not be called "OpenSSL"
83 * nor may "OpenSSL" appear in their names without prior written
84 * permission of the OpenSSL Project.
85 *
86 * 6. Redistributions of any form whatsoever must retain the following
87 * acknowledgment:
88 * "This product includes software developed by the OpenSSL Project
89 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
90 *
91 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
92 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
95 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
100 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
101 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
102 * OF THE POSSIBILITY OF SUCH DAMAGE.
103 * ====================================================================
104 *
105 * This product includes cryptographic software written by Eric Young
106 * (eay@cryptsoft.com). This product includes software written by Tim
107 * Hudson (tjh@cryptsoft.com).
108 *
109 */
110/* ====================================================================
111 * Copyright 2005 Nokia. All rights reserved.
112 *
113 * The portions of the attached software ("Contribution") is developed by
114 * Nokia Corporation and is licensed pursuant to the OpenSSL open source
115 * license.
116 *
117 * The Contribution, originally written by Mika Kousa and Pasi Eronen of
118 * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
119 * support (see RFC 4279) to OpenSSL.
120 *
121 * No patent licenses or other rights except those expressly stated in
122 * the OpenSSL open source license shall be deemed granted or received
123 * expressly, by implication, estoppel, or otherwise.
124 *
125 * No assurances are provided by Nokia that the Contribution does not
126 * infringe the patent or other intellectual property rights of any third
127 * party or that the license provides you with all the necessary rights
128 * to make use of the Contribution.
129 *
130 * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
131 * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
132 * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
133 * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
134 * OTHERWISE. */
135
David Benjamin9e4e01e2015-09-15 01:48:04 -0400136#include <openssl/ssl.h>
137
Adam Langley95c29f32014-06-20 12:00:00 -0700138#include <assert.h>
David Benjaminf0ae1702015-04-07 23:05:04 -0400139#include <string.h>
Adam Langley95c29f32014-06-20 12:00:00 -0700140
Steven Valdez908ac192017-01-12 13:17:07 -0500141#include <openssl/buf.h>
142#include <openssl/digest.h>
Adam Langley95c29f32014-06-20 12:00:00 -0700143#include <openssl/err.h>
Adam Langley95c29f32014-06-20 12:00:00 -0700144#include <openssl/mem.h>
145#include <openssl/md5.h>
David Benjamin98193672016-03-25 18:07:11 -0400146#include <openssl/nid.h>
Steven Valdez908ac192017-01-12 13:17:07 -0500147#include <openssl/sha.h>
Adam Langley95c29f32014-06-20 12:00:00 -0700148
David Benjamin17cf2cb2016-12-13 01:07:13 -0500149#include "../crypto/internal.h"
David Benjamin2ee94aa2015-04-07 22:38:30 -0400150#include "internal.h"
Adam Langley95c29f32014-06-20 12:00:00 -0700151
David Benjamin17cf2cb2016-12-13 01:07:13 -0500152
David Benjamin86e95b82017-07-18 16:34:25 -0400153namespace bssl {
154
David Benjamin6dc8bf62017-07-19 16:38:21 -0400155SSLTranscript::SSLTranscript() {}
156
157SSLTranscript::~SSLTranscript() {}
158
159bool SSLTranscript::Init() {
160 buffer_.reset(BUF_MEM_new());
161 if (!buffer_) {
162 return false;
163 }
164
165 hash_.Reset();
166 md5_.Reset();
167 return true;
Adam Langleybe2900a2014-12-18 12:09:04 -0800168}
Adam Langley95c29f32014-06-20 12:00:00 -0700169
David Benjamin6dc8bf62017-07-19 16:38:21 -0400170/* InitDigestWithData calls |EVP_DigestInit_ex| on |ctx| with |md| and then
David Benjaminb0883312015-08-06 09:54:13 -0400171 * writes the data in |buf| to it. */
David Benjamin6dc8bf62017-07-19 16:38:21 -0400172static bool InitDigestWithData(EVP_MD_CTX *ctx, const EVP_MD *md,
173 const BUF_MEM *buf) {
David Benjaminb0883312015-08-06 09:54:13 -0400174 if (!EVP_DigestInit_ex(ctx, md, NULL)) {
David Benjamin6dc8bf62017-07-19 16:38:21 -0400175 return false;
Adam Langleybe2900a2014-12-18 12:09:04 -0800176 }
David Benjaminb0883312015-08-06 09:54:13 -0400177 EVP_DigestUpdate(ctx, buf->data, buf->length);
David Benjamin6dc8bf62017-07-19 16:38:21 -0400178 return true;
David Benjaminb0883312015-08-06 09:54:13 -0400179}
Adam Langley95c29f32014-06-20 12:00:00 -0700180
David Benjamin6dc8bf62017-07-19 16:38:21 -0400181bool SSLTranscript::InitHash(uint16_t version, int algorithm_prf) {
Steven Valdez908ac192017-01-12 13:17:07 -0500182 const EVP_MD *md = ssl_get_handshake_digest(algorithm_prf, version);
David Benjaminb0883312015-08-06 09:54:13 -0400183
Steven Valdez908ac192017-01-12 13:17:07 -0500184 /* To support SSL 3.0's Finished and CertificateVerify constructions,
185 * EVP_md5_sha1() is split into MD5 and SHA-1 halves. When SSL 3.0 is removed,
186 * we can simplify this. */
187 if (md == EVP_md5_sha1()) {
David Benjamin6dc8bf62017-07-19 16:38:21 -0400188 if (!InitDigestWithData(md5_.get(), EVP_md5(), buffer_.get())) {
189 return false;
Steven Valdez908ac192017-01-12 13:17:07 -0500190 }
191 md = EVP_sha1();
David Benjaminb0883312015-08-06 09:54:13 -0400192 }
193
David Benjamin6dc8bf62017-07-19 16:38:21 -0400194 return InitDigestWithData(hash_.get(), md, buffer_.get());
David Benjamin9550c3a2015-08-05 08:50:34 -0400195}
196
David Benjamin6dc8bf62017-07-19 16:38:21 -0400197void SSLTranscript::FreeBuffer() {
198 buffer_.reset();
David Benjamin9550c3a2015-08-05 08:50:34 -0400199}
200
David Benjamin6dc8bf62017-07-19 16:38:21 -0400201size_t SSLTranscript::DigestLen() const {
202 return EVP_MD_size(Digest());
David Benjamin9550c3a2015-08-05 08:50:34 -0400203}
204
David Benjamin6dc8bf62017-07-19 16:38:21 -0400205const EVP_MD *SSLTranscript::Digest() const {
206 if (EVP_MD_CTX_md(md5_.get()) != nullptr) {
Steven Valdez908ac192017-01-12 13:17:07 -0500207 return EVP_md5_sha1();
208 }
David Benjamin6dc8bf62017-07-19 16:38:21 -0400209 return EVP_MD_CTX_md(hash_.get());
Steven Valdez908ac192017-01-12 13:17:07 -0500210}
211
David Benjamin6dc8bf62017-07-19 16:38:21 -0400212bool SSLTranscript::Update(const uint8_t *in, size_t in_len) {
David Benjamin9550c3a2015-08-05 08:50:34 -0400213 /* Depending on the state of the handshake, either the handshake buffer may be
214 * active, the rolling hash, or both. */
David Benjamin6dc8bf62017-07-19 16:38:21 -0400215 if (buffer_) {
216 size_t new_len = buffer_->length + in_len;
David Benjamin5375fd52015-08-06 01:32:10 -0400217 if (new_len < in_len) {
218 OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
David Benjamin6dc8bf62017-07-19 16:38:21 -0400219 return false;
David Benjamin5375fd52015-08-06 01:32:10 -0400220 }
David Benjamin6dc8bf62017-07-19 16:38:21 -0400221 if (!BUF_MEM_grow(buffer_.get(), new_len)) {
222 return false;
David Benjamin5375fd52015-08-06 01:32:10 -0400223 }
David Benjamin6dc8bf62017-07-19 16:38:21 -0400224 OPENSSL_memcpy(buffer_->data + new_len - in_len, in, in_len);
Adam Langleybe2900a2014-12-18 12:09:04 -0800225 }
Adam Langley0fbf33a2014-06-20 12:00:00 -0700226
David Benjamin6dc8bf62017-07-19 16:38:21 -0400227 if (EVP_MD_CTX_md(hash_.get()) != NULL) {
228 EVP_DigestUpdate(hash_.get(), in, in_len);
David Benjaminb0883312015-08-06 09:54:13 -0400229 }
David Benjamin6dc8bf62017-07-19 16:38:21 -0400230 if (EVP_MD_CTX_md(md5_.get()) != NULL) {
231 EVP_DigestUpdate(md5_.get(), in, in_len);
David Benjamin9550c3a2015-08-05 08:50:34 -0400232 }
Steven Valdez908ac192017-01-12 13:17:07 -0500233
David Benjamin6dc8bf62017-07-19 16:38:21 -0400234 return true;
Adam Langleybe2900a2014-12-18 12:09:04 -0800235}
Adam Langley0fbf33a2014-06-20 12:00:00 -0700236
David Benjamin6dc8bf62017-07-19 16:38:21 -0400237bool SSLTranscript::GetHash(uint8_t *out, size_t *out_len) {
238 ScopedEVP_MD_CTX ctx;
Steven Valdez908ac192017-01-12 13:17:07 -0500239 unsigned md5_len = 0;
David Benjamin6dc8bf62017-07-19 16:38:21 -0400240 if (EVP_MD_CTX_md(md5_.get()) != NULL) {
241 if (!EVP_MD_CTX_copy_ex(ctx.get(), md5_.get()) ||
242 !EVP_DigestFinal_ex(ctx.get(), out, &md5_len)) {
243 return false;
Steven Valdez908ac192017-01-12 13:17:07 -0500244 }
245 }
246
247 unsigned len;
David Benjamin6dc8bf62017-07-19 16:38:21 -0400248 if (!EVP_MD_CTX_copy_ex(ctx.get(), hash_.get()) ||
249 !EVP_DigestFinal_ex(ctx.get(), out + md5_len, &len)) {
250 return false;
Steven Valdez908ac192017-01-12 13:17:07 -0500251 }
252
253 *out_len = md5_len + len;
David Benjamin6dc8bf62017-07-19 16:38:21 -0400254 return true;
Steven Valdez908ac192017-01-12 13:17:07 -0500255}
256
David Benjamin6dc8bf62017-07-19 16:38:21 -0400257static bool SSL3HandshakeMAC(const SSL_SESSION *session,
258 const EVP_MD_CTX *ctx_template, const char *sender,
259 size_t sender_len, uint8_t *p, size_t *out_len) {
260 ScopedEVP_MD_CTX ctx;
261 if (!EVP_MD_CTX_copy_ex(ctx.get(), ctx_template)) {
David Benjamin3570d732015-06-29 00:28:17 -0400262 OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP);
David Benjamin6dc8bf62017-07-19 16:38:21 -0400263 return false;
Adam Langleybe2900a2014-12-18 12:09:04 -0800264 }
Adam Langley95c29f32014-06-20 12:00:00 -0700265
David Benjamin23b0a652015-12-29 23:41:34 -0500266 static const uint8_t kPad1[48] = {
267 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
268 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
269 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
270 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
271 };
272
273 static const uint8_t kPad2[48] = {
274 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
275 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
276 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
277 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
278 };
279
David Benjamin6dc8bf62017-07-19 16:38:21 -0400280 size_t n = EVP_MD_CTX_size(ctx.get());
Adam Langley95c29f32014-06-20 12:00:00 -0700281
David Benjamin6dc8bf62017-07-19 16:38:21 -0400282 size_t npad = (48 / n) * n;
283 EVP_DigestUpdate(ctx.get(), sender, sender_len);
284 EVP_DigestUpdate(ctx.get(), session->master_key, session->master_key_length);
285 EVP_DigestUpdate(ctx.get(), kPad1, npad);
286 unsigned md_buf_len;
287 uint8_t md_buf[EVP_MAX_MD_SIZE];
288 EVP_DigestFinal_ex(ctx.get(), md_buf, &md_buf_len);
Adam Langley95c29f32014-06-20 12:00:00 -0700289
David Benjamin6dc8bf62017-07-19 16:38:21 -0400290 if (!EVP_DigestInit_ex(ctx.get(), EVP_MD_CTX_md(ctx.get()), NULL)) {
David Benjamin3570d732015-06-29 00:28:17 -0400291 OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP);
David Benjamin6dc8bf62017-07-19 16:38:21 -0400292 return false;
Adam Langleybe2900a2014-12-18 12:09:04 -0800293 }
David Benjamin6dc8bf62017-07-19 16:38:21 -0400294 EVP_DigestUpdate(ctx.get(), session->master_key, session->master_key_length);
295 EVP_DigestUpdate(ctx.get(), kPad2, npad);
296 EVP_DigestUpdate(ctx.get(), md_buf, md_buf_len);
297 unsigned len;
298 EVP_DigestFinal_ex(ctx.get(), p, &len);
Adam Langley95c29f32014-06-20 12:00:00 -0700299
Steven Valdez908ac192017-01-12 13:17:07 -0500300 *out_len = len;
David Benjamin6dc8bf62017-07-19 16:38:21 -0400301 return true;
Adam Langleybe2900a2014-12-18 12:09:04 -0800302}
Adam Langley95c29f32014-06-20 12:00:00 -0700303
David Benjamin6dc8bf62017-07-19 16:38:21 -0400304bool SSLTranscript::GetSSL3CertVerifyHash(uint8_t *out, size_t *out_len,
305 const SSL_SESSION *session,
306 uint16_t signature_algorithm) {
307 if (Digest() != EVP_md5_sha1()) {
Steven Valdez2b8415e2016-06-30 13:27:23 -0400308 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
David Benjamin6dc8bf62017-07-19 16:38:21 -0400309 return false;
Steven Valdez2b8415e2016-06-30 13:27:23 -0400310 }
311
Steven Valdez908ac192017-01-12 13:17:07 -0500312 if (signature_algorithm == SSL_SIGN_RSA_PKCS1_MD5_SHA1) {
313 size_t md5_len, len;
David Benjamin6dc8bf62017-07-19 16:38:21 -0400314 if (!SSL3HandshakeMAC(session, md5_.get(), NULL, 0, out, &md5_len) ||
315 !SSL3HandshakeMAC(session, hash_.get(), NULL, 0, out + md5_len, &len)) {
316 return false;
Steven Valdez908ac192017-01-12 13:17:07 -0500317 }
318 *out_len = md5_len + len;
David Benjamin6dc8bf62017-07-19 16:38:21 -0400319 return true;
Steven Valdez908ac192017-01-12 13:17:07 -0500320 }
321
322 if (signature_algorithm == SSL_SIGN_ECDSA_SHA1) {
David Benjamin6dc8bf62017-07-19 16:38:21 -0400323 return SSL3HandshakeMAC(session, hash_.get(), NULL, 0, out, out_len);
Steven Valdez908ac192017-01-12 13:17:07 -0500324 }
325
326 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
David Benjamin6dc8bf62017-07-19 16:38:21 -0400327 return false;
Steven Valdez2b8415e2016-06-30 13:27:23 -0400328}
David Benjamin23b0a652015-12-29 23:41:34 -0500329
David Benjamin6dc8bf62017-07-19 16:38:21 -0400330bool SSLTranscript::GetFinishedMAC(uint8_t *out, size_t *out_len,
331 const SSL_SESSION *session, bool from_server,
332 uint16_t version) {
Steven Valdez908ac192017-01-12 13:17:07 -0500333 if (version == SSL3_VERSION) {
David Benjamin6dc8bf62017-07-19 16:38:21 -0400334 if (Digest() != EVP_md5_sha1()) {
Steven Valdez908ac192017-01-12 13:17:07 -0500335 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
David Benjamin6dc8bf62017-07-19 16:38:21 -0400336 return false;
Steven Valdez908ac192017-01-12 13:17:07 -0500337 }
338
339 const char *sender = from_server ? SSL3_MD_SERVER_FINISHED_CONST
340 : SSL3_MD_CLIENT_FINISHED_CONST;
341 const size_t sender_len = 4;
342 size_t md5_len, len;
David Benjamin6dc8bf62017-07-19 16:38:21 -0400343 if (!SSL3HandshakeMAC(session, md5_.get(), sender, sender_len, out,
344 &md5_len) ||
345 !SSL3HandshakeMAC(session, hash_.get(), sender, sender_len,
346 out + md5_len, &len)) {
347 return false;
Steven Valdez908ac192017-01-12 13:17:07 -0500348 }
349
350 *out_len = md5_len + len;
David Benjamin6dc8bf62017-07-19 16:38:21 -0400351 return true;
Steven Valdez908ac192017-01-12 13:17:07 -0500352 }
353
354 /* At this point, the handshake should have released the handshake buffer on
355 * its own. */
David Benjamin6dc8bf62017-07-19 16:38:21 -0400356 assert(!buffer_);
Steven Valdez908ac192017-01-12 13:17:07 -0500357
358 const char *label = TLS_MD_CLIENT_FINISH_CONST;
359 size_t label_len = TLS_MD_SERVER_FINISH_CONST_SIZE;
360 if (from_server) {
361 label = TLS_MD_SERVER_FINISH_CONST;
362 label_len = TLS_MD_SERVER_FINISH_CONST_SIZE;
363 }
364
365 uint8_t digests[EVP_MAX_MD_SIZE];
366 size_t digests_len;
David Benjamin6dc8bf62017-07-19 16:38:21 -0400367 if (!GetHash(digests, &digests_len)) {
368 return false;
Steven Valdez908ac192017-01-12 13:17:07 -0500369 }
370
371 static const size_t kFinishedLen = 12;
David Benjamin6dc8bf62017-07-19 16:38:21 -0400372 if (!tls1_prf(Digest(), out, kFinishedLen, session->master_key,
373 session->master_key_length, label, label_len, digests,
374 digests_len, NULL, 0)) {
375 return false;
Steven Valdez908ac192017-01-12 13:17:07 -0500376 }
377
378 *out_len = kFinishedLen;
David Benjamin6dc8bf62017-07-19 16:38:21 -0400379 return true;
Steven Valdez908ac192017-01-12 13:17:07 -0500380}
David Benjamin86e95b82017-07-18 16:34:25 -0400381
382} // namespace bssl