Home | History | Annotate | Download | only in ssl
      1 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com)
      2  * All rights reserved.
      3  *
      4  * This package is an SSL implementation written
      5  * by Eric Young (eay (at) 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 (at) 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 (at) 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 (at) 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 (at) 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 (at) cryptsoft.com).  This product includes software written by Tim
    107  * Hudson (tjh (at) 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 
    153 int 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. */
    161 static 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 
    170 int 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 
    192 void 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 
    198 void SSL_TRANSCRIPT_free_buffer(SSL_TRANSCRIPT *transcript) {
    199   BUF_MEM_free(transcript->buffer);
    200   transcript->buffer = NULL;
    201 }
    202 
    203 size_t SSL_TRANSCRIPT_digest_len(const SSL_TRANSCRIPT *transcript) {
    204   return EVP_MD_size(SSL_TRANSCRIPT_md(transcript));
    205 }
    206 
    207 const 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 
    214 int 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 
    240 int 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 
    262 err:
    263   EVP_MD_CTX_cleanup(&ctx);
    264   return ret;
    265 }
    266 
    267 static 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 
    325 int 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 
    355 int 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