1/* 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.
7 *
8 * 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).
14 *
15 * 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.
21 *
22 * 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 :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 *    the apps directory (application code) you must include an acknowledgement:
38 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * 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.
51 *
52 * 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
65 *    notice, this list of conditions and the following disclaimer.
66 *
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
136#include <openssl/ssl.h>
137
138#include <assert.h>
139#include <string.h>
140
141#include <openssl/buf.h>
142#include <openssl/digest.h>
143#include <openssl/err.h>
144#include <openssl/mem.h>
145#include <openssl/md5.h>
146#include <openssl/nid.h>
147#include <openssl/sha.h>
148
149#include "../crypto/internal.h"
150#include "internal.h"
151
152
153int SSL_TRANSCRIPT_init(SSL_TRANSCRIPT *transcript) {
154  SSL_TRANSCRIPT_cleanup(transcript);
155  transcript->buffer = BUF_MEM_new();
156  return transcript->buffer != NULL;
157}
158
159/* init_digest_with_data calls |EVP_DigestInit_ex| on |ctx| with |md| and then
160 * writes the data in |buf| to it. */
161static int init_digest_with_data(EVP_MD_CTX *ctx, const EVP_MD *md,
162                                 const BUF_MEM *buf) {
163  if (!EVP_DigestInit_ex(ctx, md, NULL)) {
164    return 0;
165  }
166  EVP_DigestUpdate(ctx, buf->data, buf->length);
167  return 1;
168}
169
170int SSL_TRANSCRIPT_init_hash(SSL_TRANSCRIPT *transcript, uint16_t version,
171                             int algorithm_prf) {
172  const EVP_MD *md = ssl_get_handshake_digest(algorithm_prf, version);
173
174  /* To support SSL 3.0's Finished and CertificateVerify constructions,
175   * EVP_md5_sha1() is split into MD5 and SHA-1 halves. When SSL 3.0 is removed,
176   * we can simplify this. */
177  if (md == EVP_md5_sha1()) {
178    if (!init_digest_with_data(&transcript->md5, EVP_md5(),
179                               transcript->buffer)) {
180      return 0;
181    }
182    md = EVP_sha1();
183  }
184
185  if (!init_digest_with_data(&transcript->hash, md, transcript->buffer)) {
186    return 0;
187  }
188
189  return 1;
190}
191
192void SSL_TRANSCRIPT_cleanup(SSL_TRANSCRIPT *transcript) {
193  SSL_TRANSCRIPT_free_buffer(transcript);
194  EVP_MD_CTX_cleanup(&transcript->hash);
195  EVP_MD_CTX_cleanup(&transcript->md5);
196}
197
198void SSL_TRANSCRIPT_free_buffer(SSL_TRANSCRIPT *transcript) {
199  BUF_MEM_free(transcript->buffer);
200  transcript->buffer = NULL;
201}
202
203size_t SSL_TRANSCRIPT_digest_len(const SSL_TRANSCRIPT *transcript) {
204  return EVP_MD_size(SSL_TRANSCRIPT_md(transcript));
205}
206
207const EVP_MD *SSL_TRANSCRIPT_md(const SSL_TRANSCRIPT *transcript) {
208  if (EVP_MD_CTX_md(&transcript->md5) != NULL) {
209    return EVP_md5_sha1();
210  }
211  return EVP_MD_CTX_md(&transcript->hash);
212}
213
214int SSL_TRANSCRIPT_update(SSL_TRANSCRIPT *transcript, const uint8_t *in,
215                          size_t in_len) {
216  /* Depending on the state of the handshake, either the handshake buffer may be
217   * active, the rolling hash, or both. */
218  if (transcript->buffer != NULL) {
219    size_t new_len = transcript->buffer->length + in_len;
220    if (new_len < in_len) {
221      OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
222      return 0;
223    }
224    if (!BUF_MEM_grow(transcript->buffer, new_len)) {
225      return 0;
226    }
227    OPENSSL_memcpy(transcript->buffer->data + new_len - in_len, in, in_len);
228  }
229
230  if (EVP_MD_CTX_md(&transcript->hash) != NULL) {
231    EVP_DigestUpdate(&transcript->hash, in, in_len);
232  }
233  if (EVP_MD_CTX_md(&transcript->md5) != NULL) {
234    EVP_DigestUpdate(&transcript->md5, in, in_len);
235  }
236
237  return 1;
238}
239
240int SSL_TRANSCRIPT_get_hash(const SSL_TRANSCRIPT *transcript, uint8_t *out,
241                            size_t *out_len) {
242  int ret = 0;
243  EVP_MD_CTX ctx;
244  EVP_MD_CTX_init(&ctx);
245  unsigned md5_len = 0;
246  if (EVP_MD_CTX_md(&transcript->md5) != NULL) {
247    if (!EVP_MD_CTX_copy_ex(&ctx, &transcript->md5) ||
248        !EVP_DigestFinal_ex(&ctx, out, &md5_len)) {
249      goto err;
250    }
251  }
252
253  unsigned len;
254  if (!EVP_MD_CTX_copy_ex(&ctx, &transcript->hash) ||
255      !EVP_DigestFinal_ex(&ctx, out + md5_len, &len)) {
256    goto err;
257  }
258
259  *out_len = md5_len + len;
260  ret = 1;
261
262err:
263  EVP_MD_CTX_cleanup(&ctx);
264  return ret;
265}
266
267static int ssl3_handshake_mac(SSL_TRANSCRIPT *transcript,
268                              const SSL_SESSION *session,
269                              const EVP_MD_CTX *ctx_template,
270                              const char *sender, size_t sender_len,
271                              uint8_t *p, size_t *out_len) {
272  unsigned int len;
273  size_t npad, n;
274  unsigned int i;
275  uint8_t md_buf[EVP_MAX_MD_SIZE];
276  EVP_MD_CTX ctx;
277
278  EVP_MD_CTX_init(&ctx);
279  if (!EVP_MD_CTX_copy_ex(&ctx, ctx_template)) {
280    EVP_MD_CTX_cleanup(&ctx);
281    OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP);
282    return 0;
283  }
284
285  static const uint8_t kPad1[48] = {
286      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
287      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
288      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
289      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
290  };
291
292  static const uint8_t kPad2[48] = {
293      0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
294      0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
295      0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
296      0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
297  };
298
299  n = EVP_MD_CTX_size(&ctx);
300
301  npad = (48 / n) * n;
302  if (sender != NULL) {
303    EVP_DigestUpdate(&ctx, sender, sender_len);
304  }
305  EVP_DigestUpdate(&ctx, session->master_key, session->master_key_length);
306  EVP_DigestUpdate(&ctx, kPad1, npad);
307  EVP_DigestFinal_ex(&ctx, md_buf, &i);
308
309  if (!EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL)) {
310    EVP_MD_CTX_cleanup(&ctx);
311    OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP);
312    return 0;
313  }
314  EVP_DigestUpdate(&ctx, session->master_key, session->master_key_length);
315  EVP_DigestUpdate(&ctx, kPad2, npad);
316  EVP_DigestUpdate(&ctx, md_buf, i);
317  EVP_DigestFinal_ex(&ctx, p, &len);
318
319  EVP_MD_CTX_cleanup(&ctx);
320
321  *out_len = len;
322  return 1;
323}
324
325int SSL_TRANSCRIPT_ssl3_cert_verify_hash(SSL_TRANSCRIPT *transcript,
326                                         uint8_t *out, size_t *out_len,
327                                         const SSL_SESSION *session,
328                                         int signature_algorithm) {
329  if (SSL_TRANSCRIPT_md(transcript) != EVP_md5_sha1()) {
330    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
331    return 0;
332  }
333
334  if (signature_algorithm == SSL_SIGN_RSA_PKCS1_MD5_SHA1) {
335    size_t md5_len, len;
336    if (!ssl3_handshake_mac(transcript, session, &transcript->md5, NULL, 0, out,
337                            &md5_len) ||
338        !ssl3_handshake_mac(transcript, session, &transcript->hash, NULL, 0,
339                            out + md5_len, &len)) {
340      return 0;
341    }
342    *out_len = md5_len + len;
343    return 1;
344  }
345
346  if (signature_algorithm == SSL_SIGN_ECDSA_SHA1) {
347    return ssl3_handshake_mac(transcript, session, &transcript->hash, NULL, 0,
348                              out, out_len);
349  }
350
351  OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
352  return 0;
353}
354
355int SSL_TRANSCRIPT_finish_mac(SSL_TRANSCRIPT *transcript, uint8_t *out,
356                              size_t *out_len, const SSL_SESSION *session,
357                              int from_server, uint16_t version) {
358  if (version == SSL3_VERSION) {
359    if (SSL_TRANSCRIPT_md(transcript) != EVP_md5_sha1()) {
360      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
361      return 0;
362    }
363
364    const char *sender = from_server ? SSL3_MD_SERVER_FINISHED_CONST
365                                     : SSL3_MD_CLIENT_FINISHED_CONST;
366    const size_t sender_len = 4;
367    size_t md5_len, len;
368    if (!ssl3_handshake_mac(transcript, session, &transcript->md5, sender,
369                            sender_len, out, &md5_len) ||
370        !ssl3_handshake_mac(transcript, session, &transcript->hash, sender,
371                            sender_len, out + md5_len, &len)) {
372      return 0;
373    }
374
375    *out_len = md5_len + len;
376    return 1;
377  }
378
379  /* At this point, the handshake should have released the handshake buffer on
380   * its own. */
381  assert(transcript->buffer == NULL);
382
383  const char *label = TLS_MD_CLIENT_FINISH_CONST;
384  size_t label_len = TLS_MD_SERVER_FINISH_CONST_SIZE;
385  if (from_server) {
386    label = TLS_MD_SERVER_FINISH_CONST;
387    label_len = TLS_MD_SERVER_FINISH_CONST_SIZE;
388  }
389
390  uint8_t digests[EVP_MAX_MD_SIZE];
391  size_t digests_len;
392  if (!SSL_TRANSCRIPT_get_hash(transcript, digests, &digests_len)) {
393    return 0;
394  }
395
396  static const size_t kFinishedLen = 12;
397  if (!tls1_prf(SSL_TRANSCRIPT_md(transcript), out, kFinishedLen,
398                session->master_key, session->master_key_length, label,
399                label_len, digests, digests_len, NULL, 0)) {
400    return 0;
401  }
402
403  *out_len = kFinishedLen;
404  return 1;
405}
406