155714Skris/* ssl/s3_enc.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
8280304Sjkim *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15280304Sjkim *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
22280304Sjkim *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
37280304Sjkim * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40280304Sjkim *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
52280304Sjkim *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
58100928Snectar/* ====================================================================
59238405Sjkim * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
60100928Snectar *
61100928Snectar * Redistribution and use in source and binary forms, with or without
62100928Snectar * modification, are permitted provided that the following conditions
63100928Snectar * are met:
64100928Snectar *
65100928Snectar * 1. Redistributions of source code must retain the above copyright
66280304Sjkim *    notice, this list of conditions and the following disclaimer.
67100928Snectar *
68100928Snectar * 2. Redistributions in binary form must reproduce the above copyright
69100928Snectar *    notice, this list of conditions and the following disclaimer in
70100928Snectar *    the documentation and/or other materials provided with the
71100928Snectar *    distribution.
72100928Snectar *
73100928Snectar * 3. All advertising materials mentioning features or use of this
74100928Snectar *    software must display the following acknowledgment:
75100928Snectar *    "This product includes software developed by the OpenSSL Project
76100928Snectar *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77100928Snectar *
78100928Snectar * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79100928Snectar *    endorse or promote products derived from this software without
80100928Snectar *    prior written permission. For written permission, please contact
81100928Snectar *    openssl-core@openssl.org.
82100928Snectar *
83100928Snectar * 5. Products derived from this software may not be called "OpenSSL"
84100928Snectar *    nor may "OpenSSL" appear in their names without prior written
85100928Snectar *    permission of the OpenSSL Project.
86100928Snectar *
87100928Snectar * 6. Redistributions of any form whatsoever must retain the following
88100928Snectar *    acknowledgment:
89100928Snectar *    "This product includes software developed by the OpenSSL Project
90100928Snectar *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91100928Snectar *
92100928Snectar * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93100928Snectar * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94100928Snectar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95100928Snectar * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96100928Snectar * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97100928Snectar * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98100928Snectar * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99100928Snectar * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100100928Snectar * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101100928Snectar * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102100928Snectar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103100928Snectar * OF THE POSSIBILITY OF SUCH DAMAGE.
104100928Snectar * ====================================================================
105100928Snectar *
106100928Snectar * This product includes cryptographic software written by Eric Young
107100928Snectar * (eay@cryptsoft.com).  This product includes software written by Tim
108100928Snectar * Hudson (tjh@cryptsoft.com).
109100928Snectar *
110100928Snectar */
111238405Sjkim/* ====================================================================
112238405Sjkim * Copyright 2005 Nokia. All rights reserved.
113238405Sjkim *
114238405Sjkim * The portions of the attached software ("Contribution") is developed by
115238405Sjkim * Nokia Corporation and is licensed pursuant to the OpenSSL open source
116238405Sjkim * license.
117238405Sjkim *
118238405Sjkim * The Contribution, originally written by Mika Kousa and Pasi Eronen of
119238405Sjkim * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
120238405Sjkim * support (see RFC 4279) to OpenSSL.
121238405Sjkim *
122238405Sjkim * No patent licenses or other rights except those expressly stated in
123238405Sjkim * the OpenSSL open source license shall be deemed granted or received
124238405Sjkim * expressly, by implication, estoppel, or otherwise.
125238405Sjkim *
126238405Sjkim * No assurances are provided by Nokia that the Contribution does not
127238405Sjkim * infringe the patent or other intellectual property rights of any third
128238405Sjkim * party or that the license provides you with all the necessary rights
129238405Sjkim * to make use of the Contribution.
130238405Sjkim *
131238405Sjkim * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
132238405Sjkim * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
133238405Sjkim * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
134238405Sjkim * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
135238405Sjkim * OTHERWISE.
136238405Sjkim */
13755714Skris
13855714Skris#include <stdio.h>
139109998Smarkm#include "ssl_locl.h"
140109998Smarkm#include <openssl/evp.h>
14155714Skris#include <openssl/md5.h>
14255714Skris
143280304Sjkimstatic unsigned char ssl3_pad_1[48] = {
144280304Sjkim    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
145280304Sjkim    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
146280304Sjkim    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
147280304Sjkim    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
148280304Sjkim    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
149280304Sjkim    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
150280304Sjkim};
15155714Skris
152280304Sjkimstatic unsigned char ssl3_pad_2[48] = {
153280304Sjkim    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
154280304Sjkim    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
155280304Sjkim    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
156280304Sjkim    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
157280304Sjkim    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
158280304Sjkim    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
159280304Sjkim};
160280304Sjkim
161238405Sjkimstatic int ssl3_handshake_mac(SSL *s, int md_nid,
162280304Sjkim                              const char *sender, int len, unsigned char *p);
163109998Smarkmstatic int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
164280304Sjkim{
165280304Sjkim    EVP_MD_CTX m5;
166280304Sjkim    EVP_MD_CTX s1;
167280304Sjkim    unsigned char buf[16], smd[SHA_DIGEST_LENGTH];
168280304Sjkim    unsigned char c = 'A';
169280304Sjkim    unsigned int i, j, k;
17055714Skris
17155714Skris#ifdef CHARSET_EBCDIC
172280304Sjkim    c = os_toascii[c];          /* 'A' in ASCII */
17355714Skris#endif
174280304Sjkim    k = 0;
175280304Sjkim    EVP_MD_CTX_init(&m5);
176280304Sjkim    EVP_MD_CTX_set_flags(&m5, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
177280304Sjkim    EVP_MD_CTX_init(&s1);
178280304Sjkim    for (i = 0; (int)i < num; i += MD5_DIGEST_LENGTH) {
179280304Sjkim        k++;
180280304Sjkim        if (k > sizeof buf) {
181280304Sjkim            /* bug: 'buf' is too small for this ciphersuite */
182280304Sjkim            SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR);
183280304Sjkim            return 0;
184280304Sjkim        }
18555714Skris
186280304Sjkim        for (j = 0; j < k; j++)
187280304Sjkim            buf[j] = c;
188280304Sjkim        c++;
189280304Sjkim        EVP_DigestInit_ex(&s1, EVP_sha1(), NULL);
190280304Sjkim        EVP_DigestUpdate(&s1, buf, k);
191280304Sjkim        EVP_DigestUpdate(&s1, s->session->master_key,
192280304Sjkim                         s->session->master_key_length);
193280304Sjkim        EVP_DigestUpdate(&s1, s->s3->server_random, SSL3_RANDOM_SIZE);
194280304Sjkim        EVP_DigestUpdate(&s1, s->s3->client_random, SSL3_RANDOM_SIZE);
195280304Sjkim        EVP_DigestFinal_ex(&s1, smd, NULL);
19655714Skris
197280304Sjkim        EVP_DigestInit_ex(&m5, EVP_md5(), NULL);
198280304Sjkim        EVP_DigestUpdate(&m5, s->session->master_key,
199280304Sjkim                         s->session->master_key_length);
200280304Sjkim        EVP_DigestUpdate(&m5, smd, SHA_DIGEST_LENGTH);
201280304Sjkim        if ((int)(i + MD5_DIGEST_LENGTH) > num) {
202280304Sjkim            EVP_DigestFinal_ex(&m5, smd, NULL);
203280304Sjkim            memcpy(km, smd, (num - i));
204280304Sjkim        } else
205280304Sjkim            EVP_DigestFinal_ex(&m5, km, NULL);
20655714Skris
207280304Sjkim        km += MD5_DIGEST_LENGTH;
208280304Sjkim    }
209280304Sjkim    OPENSSL_cleanse(smd, SHA_DIGEST_LENGTH);
210280304Sjkim    EVP_MD_CTX_cleanup(&m5);
211280304Sjkim    EVP_MD_CTX_cleanup(&s1);
212280304Sjkim    return 1;
213280304Sjkim}
214280304Sjkim
21555714Skrisint ssl3_change_cipher_state(SSL *s, int which)
216280304Sjkim{
217280304Sjkim    unsigned char *p, *mac_secret;
218280304Sjkim    unsigned char exp_key[EVP_MAX_KEY_LENGTH];
219280304Sjkim    unsigned char exp_iv[EVP_MAX_IV_LENGTH];
220280304Sjkim    unsigned char *ms, *key, *iv, *er1, *er2;
221280304Sjkim    EVP_CIPHER_CTX *dd;
222280304Sjkim    const EVP_CIPHER *c;
223160814Ssimon#ifndef OPENSSL_NO_COMP
224280304Sjkim    COMP_METHOD *comp;
225160814Ssimon#endif
226280304Sjkim    const EVP_MD *m;
227280304Sjkim    EVP_MD_CTX md;
228280304Sjkim    int is_exp, n, i, j, k, cl;
229280304Sjkim    int reuse_dd = 0;
23055714Skris
231280304Sjkim    is_exp = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
232280304Sjkim    c = s->s3->tmp.new_sym_enc;
233280304Sjkim    m = s->s3->tmp.new_hash;
234280304Sjkim    /* m == NULL will lead to a crash later */
235280304Sjkim    OPENSSL_assert(m);
236160814Ssimon#ifndef OPENSSL_NO_COMP
237280304Sjkim    if (s->s3->tmp.new_compression == NULL)
238280304Sjkim        comp = NULL;
239280304Sjkim    else
240280304Sjkim        comp = s->s3->tmp.new_compression->method;
241160814Ssimon#endif
24255714Skris
243280304Sjkim    if (which & SSL3_CC_READ) {
244280304Sjkim        if (s->enc_read_ctx != NULL)
245280304Sjkim            reuse_dd = 1;
246280304Sjkim        else if ((s->enc_read_ctx =
247280304Sjkim                  OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
248280304Sjkim            goto err;
249280304Sjkim        else
250280304Sjkim            /*
251280304Sjkim             * make sure it's intialized in case we exit later with an error
252280304Sjkim             */
253280304Sjkim            EVP_CIPHER_CTX_init(s->enc_read_ctx);
254280304Sjkim        dd = s->enc_read_ctx;
255238405Sjkim
256291721Sjkim        if (ssl_replace_hash(&s->read_hash, m) == NULL) {
257291721Sjkim                SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
258291721Sjkim                goto err2;
259291721Sjkim        }
260160814Ssimon#ifndef OPENSSL_NO_COMP
261280304Sjkim        /* COMPRESS */
262280304Sjkim        if (s->expand != NULL) {
263280304Sjkim            COMP_CTX_free(s->expand);
264280304Sjkim            s->expand = NULL;
265280304Sjkim        }
266280304Sjkim        if (comp != NULL) {
267280304Sjkim            s->expand = COMP_CTX_new(comp);
268280304Sjkim            if (s->expand == NULL) {
269280304Sjkim                SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,
270280304Sjkim                       SSL_R_COMPRESSION_LIBRARY_ERROR);
271280304Sjkim                goto err2;
272280304Sjkim            }
273280304Sjkim            if (s->s3->rrec.comp == NULL)
274280304Sjkim                s->s3->rrec.comp = (unsigned char *)
275280304Sjkim                    OPENSSL_malloc(SSL3_RT_MAX_PLAIN_LENGTH);
276280304Sjkim            if (s->s3->rrec.comp == NULL)
277280304Sjkim                goto err;
278280304Sjkim        }
279160814Ssimon#endif
280280304Sjkim        memset(&(s->s3->read_sequence[0]), 0, 8);
281280304Sjkim        mac_secret = &(s->s3->read_mac_secret[0]);
282280304Sjkim    } else {
283280304Sjkim        if (s->enc_write_ctx != NULL)
284280304Sjkim            reuse_dd = 1;
285280304Sjkim        else if ((s->enc_write_ctx =
286280304Sjkim                  OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
287280304Sjkim            goto err;
288280304Sjkim        else
289280304Sjkim            /*
290280304Sjkim             * make sure it's intialized in case we exit later with an error
291280304Sjkim             */
292280304Sjkim            EVP_CIPHER_CTX_init(s->enc_write_ctx);
293280304Sjkim        dd = s->enc_write_ctx;
294291721Sjkim        if (ssl_replace_hash(&s->write_hash, m) == NULL) {
295291721Sjkim                SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
296291721Sjkim                goto err2;
297291721Sjkim        }
298160814Ssimon#ifndef OPENSSL_NO_COMP
299280304Sjkim        /* COMPRESS */
300280304Sjkim        if (s->compress != NULL) {
301280304Sjkim            COMP_CTX_free(s->compress);
302280304Sjkim            s->compress = NULL;
303280304Sjkim        }
304280304Sjkim        if (comp != NULL) {
305280304Sjkim            s->compress = COMP_CTX_new(comp);
306280304Sjkim            if (s->compress == NULL) {
307280304Sjkim                SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,
308280304Sjkim                       SSL_R_COMPRESSION_LIBRARY_ERROR);
309280304Sjkim                goto err2;
310280304Sjkim            }
311280304Sjkim        }
312160814Ssimon#endif
313280304Sjkim        memset(&(s->s3->write_sequence[0]), 0, 8);
314280304Sjkim        mac_secret = &(s->s3->write_mac_secret[0]);
315280304Sjkim    }
31655714Skris
317280304Sjkim    if (reuse_dd)
318280304Sjkim        EVP_CIPHER_CTX_cleanup(dd);
31955714Skris
320280304Sjkim    p = s->s3->tmp.key_block;
321280304Sjkim    i = EVP_MD_size(m);
322280304Sjkim    if (i < 0)
323280304Sjkim        goto err2;
324280304Sjkim    cl = EVP_CIPHER_key_length(c);
325280304Sjkim    j = is_exp ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ?
326280304Sjkim                  cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl;
327280304Sjkim    /* Was j=(is_exp)?5:EVP_CIPHER_key_length(c); */
328280304Sjkim    k = EVP_CIPHER_iv_length(c);
329280304Sjkim    if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
330280304Sjkim        (which == SSL3_CHANGE_CIPHER_SERVER_READ)) {
331280304Sjkim        ms = &(p[0]);
332280304Sjkim        n = i + i;
333280304Sjkim        key = &(p[n]);
334280304Sjkim        n += j + j;
335280304Sjkim        iv = &(p[n]);
336280304Sjkim        n += k + k;
337280304Sjkim        er1 = &(s->s3->client_random[0]);
338280304Sjkim        er2 = &(s->s3->server_random[0]);
339280304Sjkim    } else {
340280304Sjkim        n = i;
341280304Sjkim        ms = &(p[n]);
342280304Sjkim        n += i + j;
343280304Sjkim        key = &(p[n]);
344280304Sjkim        n += j + k;
345280304Sjkim        iv = &(p[n]);
346280304Sjkim        n += k;
347280304Sjkim        er1 = &(s->s3->server_random[0]);
348280304Sjkim        er2 = &(s->s3->client_random[0]);
349280304Sjkim    }
35055714Skris
351280304Sjkim    if (n > s->s3->tmp.key_block_length) {
352280304Sjkim        SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
353280304Sjkim        goto err2;
354280304Sjkim    }
35555714Skris
356280304Sjkim    EVP_MD_CTX_init(&md);
357280304Sjkim    memcpy(mac_secret, ms, i);
358280304Sjkim    if (is_exp) {
359280304Sjkim        /*
360280304Sjkim         * In here I set both the read and write key/iv to the same value
361280304Sjkim         * since only the correct one will be used :-).
362280304Sjkim         */
363280304Sjkim        EVP_DigestInit_ex(&md, EVP_md5(), NULL);
364280304Sjkim        EVP_DigestUpdate(&md, key, j);
365280304Sjkim        EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE);
366280304Sjkim        EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE);
367280304Sjkim        EVP_DigestFinal_ex(&md, &(exp_key[0]), NULL);
368280304Sjkim        key = &(exp_key[0]);
36955714Skris
370280304Sjkim        if (k > 0) {
371280304Sjkim            EVP_DigestInit_ex(&md, EVP_md5(), NULL);
372280304Sjkim            EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE);
373280304Sjkim            EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE);
374280304Sjkim            EVP_DigestFinal_ex(&md, &(exp_iv[0]), NULL);
375280304Sjkim            iv = &(exp_iv[0]);
376280304Sjkim        }
377280304Sjkim    }
37855714Skris
379280304Sjkim    s->session->key_arg_length = 0;
38055714Skris
381280304Sjkim    EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE));
38255714Skris
383280304Sjkim    OPENSSL_cleanse(&(exp_key[0]), sizeof(exp_key));
384280304Sjkim    OPENSSL_cleanse(&(exp_iv[0]), sizeof(exp_iv));
385280304Sjkim    EVP_MD_CTX_cleanup(&md);
386280304Sjkim    return (1);
387280304Sjkim err:
388280304Sjkim    SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE);
389280304Sjkim err2:
390280304Sjkim    return (0);
391280304Sjkim}
39255714Skris
39355714Skrisint ssl3_setup_key_block(SSL *s)
394280304Sjkim{
395280304Sjkim    unsigned char *p;
396280304Sjkim    const EVP_CIPHER *c;
397280304Sjkim    const EVP_MD *hash;
398280304Sjkim    int num;
399280304Sjkim    int ret = 0;
400280304Sjkim    SSL_COMP *comp;
40155714Skris
402280304Sjkim    if (s->s3->tmp.key_block_length != 0)
403280304Sjkim        return (1);
40455714Skris
405280304Sjkim    if (!ssl_cipher_get_evp(s->session, &c, &hash, NULL, NULL, &comp)) {
406280304Sjkim        SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
407280304Sjkim        return (0);
408280304Sjkim    }
40955714Skris
410280304Sjkim    s->s3->tmp.new_sym_enc = c;
411280304Sjkim    s->s3->tmp.new_hash = hash;
412160814Ssimon#ifdef OPENSSL_NO_COMP
413280304Sjkim    s->s3->tmp.new_compression = NULL;
414160814Ssimon#else
415280304Sjkim    s->s3->tmp.new_compression = comp;
416160814Ssimon#endif
41755714Skris
418280304Sjkim    num = EVP_MD_size(hash);
419280304Sjkim    if (num < 0)
420280304Sjkim        return 0;
421238405Sjkim
422280304Sjkim    num = EVP_CIPHER_key_length(c) + num + EVP_CIPHER_iv_length(c);
423280304Sjkim    num *= 2;
42455714Skris
425280304Sjkim    ssl3_cleanup_key_block(s);
42655714Skris
427280304Sjkim    if ((p = OPENSSL_malloc(num)) == NULL)
428280304Sjkim        goto err;
42955714Skris
430280304Sjkim    s->s3->tmp.key_block_length = num;
431280304Sjkim    s->s3->tmp.key_block = p;
432109998Smarkm
433280304Sjkim    ret = ssl3_generate_key_block(s, p, num);
434109998Smarkm
435280304Sjkim    if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) {
436280304Sjkim        /*
437280304Sjkim         * enable vulnerability countermeasure for CBC ciphers with known-IV
438280304Sjkim         * problem (http://www.openssl.org/~bodo/tls-cbc.txt)
439280304Sjkim         */
440280304Sjkim        s->s3->need_empty_fragments = 1;
441100936Snectar
442280304Sjkim        if (s->session->cipher != NULL) {
443280304Sjkim            if (s->session->cipher->algorithm_enc == SSL_eNULL)
444280304Sjkim                s->s3->need_empty_fragments = 0;
445280304Sjkim
446109998Smarkm#ifndef OPENSSL_NO_RC4
447280304Sjkim            if (s->session->cipher->algorithm_enc == SSL_RC4)
448280304Sjkim                s->s3->need_empty_fragments = 0;
449100928Snectar#endif
450280304Sjkim        }
451280304Sjkim    }
452109998Smarkm
453280304Sjkim    return ret;
45455714Skris
455280304Sjkim err:
456280304Sjkim    SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE);
457280304Sjkim    return (0);
458280304Sjkim}
459280304Sjkim
46055714Skrisvoid ssl3_cleanup_key_block(SSL *s)
461280304Sjkim{
462280304Sjkim    if (s->s3->tmp.key_block != NULL) {
463280304Sjkim        OPENSSL_cleanse(s->s3->tmp.key_block, s->s3->tmp.key_block_length);
464280304Sjkim        OPENSSL_free(s->s3->tmp.key_block);
465280304Sjkim        s->s3->tmp.key_block = NULL;
466280304Sjkim    }
467280304Sjkim    s->s3->tmp.key_block_length = 0;
468280304Sjkim}
46955714Skris
470280304Sjkim/*-
471280304Sjkim * ssl3_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively.
472246772Sjkim *
473246772Sjkim * Returns:
474246772Sjkim *   0: (in non-constant time) if the record is publically invalid (i.e. too
475246772Sjkim *       short etc).
476246772Sjkim *   1: if the record's padding is valid / the encryption was successful.
477246772Sjkim *   -1: if the record's padding is invalid or, if sending, an internal error
478246772Sjkim *       occured.
479246772Sjkim */
48055714Skrisint ssl3_enc(SSL *s, int send)
481280304Sjkim{
482280304Sjkim    SSL3_RECORD *rec;
483280304Sjkim    EVP_CIPHER_CTX *ds;
484280304Sjkim    unsigned long l;
485280304Sjkim    int bs, i, mac_size = 0;
486280304Sjkim    const EVP_CIPHER *enc;
48755714Skris
488280304Sjkim    if (send) {
489280304Sjkim        ds = s->enc_write_ctx;
490280304Sjkim        rec = &(s->s3->wrec);
491280304Sjkim        if (s->enc_write_ctx == NULL)
492280304Sjkim            enc = NULL;
493280304Sjkim        else
494280304Sjkim            enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
495280304Sjkim    } else {
496280304Sjkim        ds = s->enc_read_ctx;
497280304Sjkim        rec = &(s->s3->rrec);
498280304Sjkim        if (s->enc_read_ctx == NULL)
499280304Sjkim            enc = NULL;
500280304Sjkim        else
501280304Sjkim            enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
502280304Sjkim    }
50355714Skris
504280304Sjkim    if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) {
505280304Sjkim        memmove(rec->data, rec->input, rec->length);
506280304Sjkim        rec->input = rec->data;
507280304Sjkim    } else {
508280304Sjkim        l = rec->length;
509280304Sjkim        bs = EVP_CIPHER_block_size(ds->cipher);
51055714Skris
511280304Sjkim        /* COMPRESS */
51255714Skris
513280304Sjkim        if ((bs != 1) && send) {
514280304Sjkim            i = bs - ((int)l % bs);
51555714Skris
516280304Sjkim            /* we need to add 'i-1' padding bytes */
517280304Sjkim            l += i;
518280304Sjkim            /*
519280304Sjkim             * the last of these zero bytes will be overwritten with the
520280304Sjkim             * padding length.
521280304Sjkim             */
522280304Sjkim            memset(&rec->input[rec->length], 0, i);
523280304Sjkim            rec->length += i;
524280304Sjkim            rec->input[l - 1] = (i - 1);
525280304Sjkim        }
52655714Skris
527280304Sjkim        if (!send) {
528280304Sjkim            if (l == 0 || l % bs != 0)
529280304Sjkim                return 0;
530280304Sjkim            /* otherwise, rec->length >= bs */
531280304Sjkim        }
53255714Skris
533280304Sjkim        if (EVP_Cipher(ds, rec->data, rec->input, l) < 1)
534280304Sjkim            return -1;
53555714Skris
536280304Sjkim        if (EVP_MD_CTX_md(s->read_hash) != NULL)
537280304Sjkim            mac_size = EVP_MD_CTX_size(s->read_hash);
538280304Sjkim        if ((bs != 1) && !send)
539280304Sjkim            return ssl3_cbc_remove_padding(s, rec, bs, mac_size);
540280304Sjkim    }
541280304Sjkim    return (1);
542280304Sjkim}
543238405Sjkim
544280304Sjkimvoid ssl3_init_finished_mac(SSL *s)
545280304Sjkim{
546280304Sjkim    if (s->s3->handshake_buffer)
547280304Sjkim        BIO_free(s->s3->handshake_buffer);
548280304Sjkim    if (s->s3->handshake_dgst)
549280304Sjkim        ssl3_free_digest_list(s);
550280304Sjkim    s->s3->handshake_buffer = BIO_new(BIO_s_mem());
551280304Sjkim    (void)BIO_set_close(s->s3->handshake_buffer, BIO_CLOSE);
552280304Sjkim}
553238405Sjkim
554280304Sjkimvoid ssl3_free_digest_list(SSL *s)
555280304Sjkim{
556280304Sjkim    int i;
557280304Sjkim    if (!s->s3->handshake_dgst)
558280304Sjkim        return;
559280304Sjkim    for (i = 0; i < SSL_MAX_DIGEST; i++) {
560280304Sjkim        if (s->s3->handshake_dgst[i])
561280304Sjkim            EVP_MD_CTX_destroy(s->s3->handshake_dgst[i]);
562280304Sjkim    }
563280304Sjkim    OPENSSL_free(s->s3->handshake_dgst);
564280304Sjkim    s->s3->handshake_dgst = NULL;
565280304Sjkim}
566238405Sjkim
56755714Skrisvoid ssl3_finish_mac(SSL *s, const unsigned char *buf, int len)
568280304Sjkim{
569280304Sjkim    if (s->s3->handshake_buffer
570280304Sjkim        && !(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) {
571280304Sjkim        BIO_write(s->s3->handshake_buffer, (void *)buf, len);
572280304Sjkim    } else {
573280304Sjkim        int i;
574280304Sjkim        for (i = 0; i < SSL_MAX_DIGEST; i++) {
575280304Sjkim            if (s->s3->handshake_dgst[i] != NULL)
576280304Sjkim                EVP_DigestUpdate(s->s3->handshake_dgst[i], buf, len);
577280304Sjkim        }
578280304Sjkim    }
579280304Sjkim}
58055714Skris
581238405Sjkimint ssl3_digest_cached_records(SSL *s)
582280304Sjkim{
583280304Sjkim    int i;
584280304Sjkim    long mask;
585280304Sjkim    const EVP_MD *md;
586280304Sjkim    long hdatalen;
587280304Sjkim    void *hdata;
588238405Sjkim
589280304Sjkim    /* Allocate handshake_dgst array */
590280304Sjkim    ssl3_free_digest_list(s);
591280304Sjkim    s->s3->handshake_dgst =
592280304Sjkim        OPENSSL_malloc(SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *));
593280304Sjkim    memset(s->s3->handshake_dgst, 0, SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *));
594280304Sjkim    hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
595280304Sjkim    if (hdatalen <= 0) {
596280304Sjkim        SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, SSL_R_BAD_HANDSHAKE_LENGTH);
597280304Sjkim        return 0;
598280304Sjkim    }
599238405Sjkim
600280304Sjkim    /* Loop through bitso of algorithm2 field and create MD_CTX-es */
601280304Sjkim    for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++) {
602280304Sjkim        if ((mask & ssl_get_algorithm2(s)) && md) {
603280304Sjkim            s->s3->handshake_dgst[i] = EVP_MD_CTX_create();
604238405Sjkim#ifdef OPENSSL_FIPS
605280304Sjkim            if (EVP_MD_nid(md) == NID_md5) {
606280304Sjkim                EVP_MD_CTX_set_flags(s->s3->handshake_dgst[i],
607280304Sjkim                                     EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
608280304Sjkim            }
609238405Sjkim#endif
610280304Sjkim            EVP_DigestInit_ex(s->s3->handshake_dgst[i], md, NULL);
611280304Sjkim            EVP_DigestUpdate(s->s3->handshake_dgst[i], hdata, hdatalen);
612280304Sjkim        } else {
613280304Sjkim            s->s3->handshake_dgst[i] = NULL;
614280304Sjkim        }
615280304Sjkim    }
616280304Sjkim    if (!(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) {
617280304Sjkim        /* Free handshake_buffer BIO */
618280304Sjkim        BIO_free(s->s3->handshake_buffer);
619280304Sjkim        s->s3->handshake_buffer = NULL;
620280304Sjkim    }
621238405Sjkim
622280304Sjkim    return 1;
623280304Sjkim}
62455714Skris
625238405Sjkimint ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p)
626280304Sjkim{
627280304Sjkim    return (ssl3_handshake_mac(s, md_nid, NULL, 0, p));
628280304Sjkim}
629269686Sjkim
630280304Sjkimint ssl3_final_finish_mac(SSL *s,
631280304Sjkim                          const char *sender, int len, unsigned char *p)
632280304Sjkim{
633280304Sjkim    int ret, sha1len;
634280304Sjkim    ret = ssl3_handshake_mac(s, NID_md5, sender, len, p);
635280304Sjkim    if (ret == 0)
636280304Sjkim        return 0;
637269686Sjkim
638280304Sjkim    p += ret;
639269686Sjkim
640280304Sjkim    sha1len = ssl3_handshake_mac(s, NID_sha1, sender, len, p);
641280304Sjkim    if (sha1len == 0)
642280304Sjkim        return 0;
643280304Sjkim
644280304Sjkim    ret += sha1len;
645280304Sjkim    return (ret);
646280304Sjkim}
647280304Sjkim
648238405Sjkimstatic int ssl3_handshake_mac(SSL *s, int md_nid,
649280304Sjkim                              const char *sender, int len, unsigned char *p)
650280304Sjkim{
651280304Sjkim    unsigned int ret;
652280304Sjkim    int npad, n;
653280304Sjkim    unsigned int i;
654280304Sjkim    unsigned char md_buf[EVP_MAX_MD_SIZE];
655280304Sjkim    EVP_MD_CTX ctx, *d = NULL;
65655714Skris
657280304Sjkim    if (s->s3->handshake_buffer)
658280304Sjkim        if (!ssl3_digest_cached_records(s))
659280304Sjkim            return 0;
660238405Sjkim
661280304Sjkim    /*
662280304Sjkim     * Search for digest of specified type in the handshake_dgst array
663280304Sjkim     */
664280304Sjkim    for (i = 0; i < SSL_MAX_DIGEST; i++) {
665280304Sjkim        if (s->s3->handshake_dgst[i]
666280304Sjkim            && EVP_MD_CTX_type(s->s3->handshake_dgst[i]) == md_nid) {
667280304Sjkim            d = s->s3->handshake_dgst[i];
668280304Sjkim            break;
669280304Sjkim        }
670280304Sjkim    }
671280304Sjkim    if (!d) {
672280304Sjkim        SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, SSL_R_NO_REQUIRED_DIGEST);
673280304Sjkim        return 0;
674280304Sjkim    }
675280304Sjkim    EVP_MD_CTX_init(&ctx);
676280304Sjkim    EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
677280304Sjkim    EVP_MD_CTX_copy_ex(&ctx, d);
678280304Sjkim    n = EVP_MD_CTX_size(&ctx);
679280304Sjkim    if (n < 0)
680280304Sjkim        return 0;
68155714Skris
682280304Sjkim    npad = (48 / n) * n;
683291721Sjkim    if ((sender != NULL && EVP_DigestUpdate(&ctx, sender, len) <= 0)
684291721Sjkim            || EVP_DigestUpdate(&ctx, s->session->master_key,
685291721Sjkim                                s->session->master_key_length) <= 0
686291721Sjkim            || EVP_DigestUpdate(&ctx, ssl3_pad_1, npad) <= 0
687291721Sjkim            || EVP_DigestFinal_ex(&ctx, md_buf, &i) <= 0
68855714Skris
689291721Sjkim            || EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL) <= 0
690291721Sjkim            || EVP_DigestUpdate(&ctx, s->session->master_key,
691291721Sjkim                                s->session->master_key_length) <= 0
692291721Sjkim            || EVP_DigestUpdate(&ctx, ssl3_pad_2, npad) <= 0
693291721Sjkim            || EVP_DigestUpdate(&ctx, md_buf, i) <= 0
694291721Sjkim            || EVP_DigestFinal_ex(&ctx, p, &ret) <= 0) {
695291721Sjkim        SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, ERR_R_INTERNAL_ERROR);
696291721Sjkim        ret = 0;
697291721Sjkim    }
69855714Skris
699280304Sjkim    EVP_MD_CTX_cleanup(&ctx);
70055714Skris
701280304Sjkim    return ((int)ret);
702280304Sjkim}
70355714Skris
704238405Sjkimint n_ssl3_mac(SSL *ssl, unsigned char *md, int send)
705280304Sjkim{
706280304Sjkim    SSL3_RECORD *rec;
707280304Sjkim    unsigned char *mac_sec, *seq;
708280304Sjkim    EVP_MD_CTX md_ctx;
709280304Sjkim    const EVP_MD_CTX *hash;
710280304Sjkim    unsigned char *p, rec_char;
711280304Sjkim    size_t md_size, orig_len;
712280304Sjkim    int npad;
713280304Sjkim    int t;
71455714Skris
715280304Sjkim    if (send) {
716280304Sjkim        rec = &(ssl->s3->wrec);
717280304Sjkim        mac_sec = &(ssl->s3->write_mac_secret[0]);
718280304Sjkim        seq = &(ssl->s3->write_sequence[0]);
719280304Sjkim        hash = ssl->write_hash;
720280304Sjkim    } else {
721280304Sjkim        rec = &(ssl->s3->rrec);
722280304Sjkim        mac_sec = &(ssl->s3->read_mac_secret[0]);
723280304Sjkim        seq = &(ssl->s3->read_sequence[0]);
724280304Sjkim        hash = ssl->read_hash;
725280304Sjkim    }
72655714Skris
727280304Sjkim    t = EVP_MD_CTX_size(hash);
728280304Sjkim    if (t < 0)
729280304Sjkim        return -1;
730280304Sjkim    md_size = t;
731280304Sjkim    npad = (48 / md_size) * md_size;
73255714Skris
733280304Sjkim    /*
734280304Sjkim     * kludge: ssl3_cbc_remove_padding passes padding length in rec->type
735280304Sjkim     */
736280304Sjkim    orig_len = rec->length + md_size + ((unsigned int)rec->type >> 8);
737280304Sjkim    rec->type &= 0xff;
73855714Skris
739280304Sjkim    if (!send &&
740280304Sjkim        EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
741280304Sjkim        ssl3_cbc_record_digest_supported(hash)) {
742280304Sjkim        /*
743280304Sjkim         * This is a CBC-encrypted record. We must avoid leaking any
744280304Sjkim         * timing-side channel information about how many blocks of data we
745280304Sjkim         * are hashing because that gives an attacker a timing-oracle.
746280304Sjkim         */
74755714Skris
748280304Sjkim        /*-
749280304Sjkim         * npad is, at most, 48 bytes and that's with MD5:
750280304Sjkim         *   16 + 48 + 8 (sequence bytes) + 1 + 2 = 75.
751280304Sjkim         *
752280304Sjkim         * With SHA-1 (the largest hash speced for SSLv3) the hash size
753280304Sjkim         * goes up 4, but npad goes down by 8, resulting in a smaller
754280304Sjkim         * total size.
755280304Sjkim         */
756280304Sjkim        unsigned char header[75];
757280304Sjkim        unsigned j = 0;
758280304Sjkim        memcpy(header + j, mac_sec, md_size);
759280304Sjkim        j += md_size;
760280304Sjkim        memcpy(header + j, ssl3_pad_1, npad);
761280304Sjkim        j += npad;
762280304Sjkim        memcpy(header + j, seq, 8);
763280304Sjkim        j += 8;
764280304Sjkim        header[j++] = rec->type;
765280304Sjkim        header[j++] = rec->length >> 8;
766280304Sjkim        header[j++] = rec->length & 0xff;
76755714Skris
768280304Sjkim        /* Final param == is SSLv3 */
769291721Sjkim        if (ssl3_cbc_digest_record(hash,
770291721Sjkim                                   md, &md_size,
771291721Sjkim                                   header, rec->input,
772291721Sjkim                                   rec->length + md_size, orig_len,
773291721Sjkim                                   mac_sec, md_size, 1) <= 0)
774291721Sjkim            return -1;
775280304Sjkim    } else {
776280304Sjkim        unsigned int md_size_u;
777280304Sjkim        /* Chop the digest off the end :-) */
778280304Sjkim        EVP_MD_CTX_init(&md_ctx);
779109998Smarkm
780280304Sjkim        rec_char = rec->type;
781280304Sjkim        p = md;
782280304Sjkim        s2n(rec->length, p);
783291721Sjkim        if (EVP_MD_CTX_copy_ex(&md_ctx, hash) <= 0
784291721Sjkim                || EVP_DigestUpdate(&md_ctx, mac_sec, md_size) <= 0
785291721Sjkim                || EVP_DigestUpdate(&md_ctx, ssl3_pad_1, npad) <= 0
786291721Sjkim                || EVP_DigestUpdate(&md_ctx, seq, 8) <= 0
787291721Sjkim                || EVP_DigestUpdate(&md_ctx, &rec_char, 1) <= 0
788291721Sjkim                || EVP_DigestUpdate(&md_ctx, md, 2) <= 0
789291721Sjkim                || EVP_DigestUpdate(&md_ctx, rec->input, rec->length) <= 0
790291721Sjkim                || EVP_DigestFinal_ex(&md_ctx, md, NULL) <= 0
791291721Sjkim                || EVP_MD_CTX_copy_ex(&md_ctx, hash) <= 0
792291721Sjkim                || EVP_DigestUpdate(&md_ctx, mac_sec, md_size) <= 0
793291721Sjkim                || EVP_DigestUpdate(&md_ctx, ssl3_pad_2, npad) <= 0
794291721Sjkim                || EVP_DigestUpdate(&md_ctx, md, md_size) <= 0
795291721Sjkim                || EVP_DigestFinal_ex(&md_ctx, md, &md_size_u) <= 0) {
796291721Sjkim            EVP_MD_CTX_cleanup(&md_ctx);
797291721Sjkim            return -1;
798291721Sjkim        }
799280304Sjkim        md_size = md_size_u;
800246772Sjkim
801280304Sjkim        EVP_MD_CTX_cleanup(&md_ctx);
802280304Sjkim    }
803246772Sjkim
804280304Sjkim    ssl3_record_sequence_update(seq);
805280304Sjkim    return (md_size);
806280304Sjkim}
807160814Ssimon
808160814Ssimonvoid ssl3_record_sequence_update(unsigned char *seq)
809280304Sjkim{
810280304Sjkim    int i;
811160814Ssimon
812280304Sjkim    for (i = 7; i >= 0; i--) {
813280304Sjkim        ++seq[i];
814280304Sjkim        if (seq[i] != 0)
815280304Sjkim            break;
816280304Sjkim    }
817280304Sjkim}
81855714Skris
81955714Skrisint ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
820280304Sjkim                                int len)
821280304Sjkim{
822280304Sjkim    static const unsigned char *salt[3] = {
82355714Skris#ifndef CHARSET_EBCDIC
824280304Sjkim        (const unsigned char *)"A",
825280304Sjkim        (const unsigned char *)"BB",
826280304Sjkim        (const unsigned char *)"CCC",
82755714Skris#else
828280304Sjkim        (const unsigned char *)"\x41",
829280304Sjkim        (const unsigned char *)"\x42\x42",
830280304Sjkim        (const unsigned char *)"\x43\x43\x43",
83155714Skris#endif
832280304Sjkim    };
833280304Sjkim    unsigned char buf[EVP_MAX_MD_SIZE];
834280304Sjkim    EVP_MD_CTX ctx;
835280304Sjkim    int i, ret = 0;
836280304Sjkim    unsigned int n;
83755714Skris
838280304Sjkim    EVP_MD_CTX_init(&ctx);
839280304Sjkim    for (i = 0; i < 3; i++) {
840291721Sjkim        if (EVP_DigestInit_ex(&ctx, s->ctx->sha1, NULL) <= 0
841291721Sjkim                || EVP_DigestUpdate(&ctx, salt[i],
842291721Sjkim                                    strlen((const char *)salt[i])) <= 0
843291721Sjkim                || EVP_DigestUpdate(&ctx, p, len) <= 0
844291721Sjkim                || EVP_DigestUpdate(&ctx, &(s->s3->client_random[0]),
845291721Sjkim                                    SSL3_RANDOM_SIZE) <= 0
846291721Sjkim                || EVP_DigestUpdate(&ctx, &(s->s3->server_random[0]),
847291721Sjkim                                    SSL3_RANDOM_SIZE) <= 0
848291721Sjkim                || EVP_DigestFinal_ex(&ctx, buf, &n) <= 0
84955714Skris
850291721Sjkim                || EVP_DigestInit_ex(&ctx, s->ctx->md5, NULL) <= 0
851291721Sjkim                || EVP_DigestUpdate(&ctx, p, len) <= 0
852291721Sjkim                || EVP_DigestUpdate(&ctx, buf, n) <= 0
853291721Sjkim                || EVP_DigestFinal_ex(&ctx, out, &n) <= 0) {
854291721Sjkim            SSLerr(SSL_F_SSL3_GENERATE_MASTER_SECRET, ERR_R_INTERNAL_ERROR);
855291721Sjkim            ret = 0;
856291721Sjkim            break;
857291721Sjkim        }
858280304Sjkim        out += n;
859280304Sjkim        ret += n;
860280304Sjkim    }
861280304Sjkim    EVP_MD_CTX_cleanup(&ctx);
862280304Sjkim    OPENSSL_cleanse(buf, sizeof buf);
863280304Sjkim    return (ret);
864280304Sjkim}
86555714Skris
86655714Skrisint ssl3_alert_code(int code)
867280304Sjkim{
868280304Sjkim    switch (code) {
869280304Sjkim    case SSL_AD_CLOSE_NOTIFY:
870280304Sjkim        return (SSL3_AD_CLOSE_NOTIFY);
871280304Sjkim    case SSL_AD_UNEXPECTED_MESSAGE:
872280304Sjkim        return (SSL3_AD_UNEXPECTED_MESSAGE);
873280304Sjkim    case SSL_AD_BAD_RECORD_MAC:
874280304Sjkim        return (SSL3_AD_BAD_RECORD_MAC);
875280304Sjkim    case SSL_AD_DECRYPTION_FAILED:
876280304Sjkim        return (SSL3_AD_BAD_RECORD_MAC);
877280304Sjkim    case SSL_AD_RECORD_OVERFLOW:
878280304Sjkim        return (SSL3_AD_BAD_RECORD_MAC);
879280304Sjkim    case SSL_AD_DECOMPRESSION_FAILURE:
880280304Sjkim        return (SSL3_AD_DECOMPRESSION_FAILURE);
881280304Sjkim    case SSL_AD_HANDSHAKE_FAILURE:
882280304Sjkim        return (SSL3_AD_HANDSHAKE_FAILURE);
883280304Sjkim    case SSL_AD_NO_CERTIFICATE:
884280304Sjkim        return (SSL3_AD_NO_CERTIFICATE);
885280304Sjkim    case SSL_AD_BAD_CERTIFICATE:
886280304Sjkim        return (SSL3_AD_BAD_CERTIFICATE);
887280304Sjkim    case SSL_AD_UNSUPPORTED_CERTIFICATE:
888280304Sjkim        return (SSL3_AD_UNSUPPORTED_CERTIFICATE);
889280304Sjkim    case SSL_AD_CERTIFICATE_REVOKED:
890280304Sjkim        return (SSL3_AD_CERTIFICATE_REVOKED);
891280304Sjkim    case SSL_AD_CERTIFICATE_EXPIRED:
892280304Sjkim        return (SSL3_AD_CERTIFICATE_EXPIRED);
893280304Sjkim    case SSL_AD_CERTIFICATE_UNKNOWN:
894280304Sjkim        return (SSL3_AD_CERTIFICATE_UNKNOWN);
895280304Sjkim    case SSL_AD_ILLEGAL_PARAMETER:
896280304Sjkim        return (SSL3_AD_ILLEGAL_PARAMETER);
897280304Sjkim    case SSL_AD_UNKNOWN_CA:
898280304Sjkim        return (SSL3_AD_BAD_CERTIFICATE);
899280304Sjkim    case SSL_AD_ACCESS_DENIED:
900280304Sjkim        return (SSL3_AD_HANDSHAKE_FAILURE);
901280304Sjkim    case SSL_AD_DECODE_ERROR:
902280304Sjkim        return (SSL3_AD_HANDSHAKE_FAILURE);
903280304Sjkim    case SSL_AD_DECRYPT_ERROR:
904280304Sjkim        return (SSL3_AD_HANDSHAKE_FAILURE);
905280304Sjkim    case SSL_AD_EXPORT_RESTRICTION:
906280304Sjkim        return (SSL3_AD_HANDSHAKE_FAILURE);
907280304Sjkim    case SSL_AD_PROTOCOL_VERSION:
908280304Sjkim        return (SSL3_AD_HANDSHAKE_FAILURE);
909280304Sjkim    case SSL_AD_INSUFFICIENT_SECURITY:
910280304Sjkim        return (SSL3_AD_HANDSHAKE_FAILURE);
911280304Sjkim    case SSL_AD_INTERNAL_ERROR:
912280304Sjkim        return (SSL3_AD_HANDSHAKE_FAILURE);
913280304Sjkim    case SSL_AD_USER_CANCELLED:
914280304Sjkim        return (SSL3_AD_HANDSHAKE_FAILURE);
915280304Sjkim    case SSL_AD_NO_RENEGOTIATION:
916280304Sjkim        return (-1);            /* Don't send it :-) */
917280304Sjkim    case SSL_AD_UNSUPPORTED_EXTENSION:
918280304Sjkim        return (SSL3_AD_HANDSHAKE_FAILURE);
919280304Sjkim    case SSL_AD_CERTIFICATE_UNOBTAINABLE:
920280304Sjkim        return (SSL3_AD_HANDSHAKE_FAILURE);
921280304Sjkim    case SSL_AD_UNRECOGNIZED_NAME:
922280304Sjkim        return (SSL3_AD_HANDSHAKE_FAILURE);
923280304Sjkim    case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
924280304Sjkim        return (SSL3_AD_HANDSHAKE_FAILURE);
925280304Sjkim    case SSL_AD_BAD_CERTIFICATE_HASH_VALUE:
926280304Sjkim        return (SSL3_AD_HANDSHAKE_FAILURE);
927280304Sjkim    case SSL_AD_UNKNOWN_PSK_IDENTITY:
928280304Sjkim        return (TLS1_AD_UNKNOWN_PSK_IDENTITY);
929280304Sjkim    case SSL_AD_INAPPROPRIATE_FALLBACK:
930280304Sjkim        return (TLS1_AD_INAPPROPRIATE_FALLBACK);
931280304Sjkim    default:
932280304Sjkim        return (-1);
933280304Sjkim    }
934280304Sjkim}
935