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.
8296341Sdelphij *
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).
15296341Sdelphij *
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.
22296341Sdelphij *
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 :-).
37296341Sdelphij * 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)"
40296341Sdelphij *
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.
52296341Sdelphij *
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
66296341Sdelphij *    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
143296341Sdelphijstatic unsigned char ssl3_pad_1[48] = {
144296341Sdelphij    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
145296341Sdelphij    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
146296341Sdelphij    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
147296341Sdelphij    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
148296341Sdelphij    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
149296341Sdelphij    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
150296341Sdelphij};
15155714Skris
152296341Sdelphijstatic unsigned char ssl3_pad_2[48] = {
153296341Sdelphij    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
154296341Sdelphij    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
155296341Sdelphij    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
156296341Sdelphij    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
157296341Sdelphij    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
158296341Sdelphij    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
159296341Sdelphij};
160296341Sdelphij
161238405Sjkimstatic int ssl3_handshake_mac(SSL *s, int md_nid,
162296341Sdelphij                              const char *sender, int len, unsigned char *p);
163109998Smarkmstatic int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
164296341Sdelphij{
165296341Sdelphij    EVP_MD_CTX m5;
166296341Sdelphij    EVP_MD_CTX s1;
167296341Sdelphij    unsigned char buf[16], smd[SHA_DIGEST_LENGTH];
168296341Sdelphij    unsigned char c = 'A';
169296341Sdelphij    unsigned int i, j, k;
17055714Skris
17155714Skris#ifdef CHARSET_EBCDIC
172296341Sdelphij    c = os_toascii[c];          /* 'A' in ASCII */
17355714Skris#endif
174296341Sdelphij    k = 0;
175296341Sdelphij    EVP_MD_CTX_init(&m5);
176296341Sdelphij    EVP_MD_CTX_set_flags(&m5, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
177296341Sdelphij    EVP_MD_CTX_init(&s1);
178296341Sdelphij    for (i = 0; (int)i < num; i += MD5_DIGEST_LENGTH) {
179296341Sdelphij        k++;
180296341Sdelphij        if (k > sizeof buf) {
181296341Sdelphij            /* bug: 'buf' is too small for this ciphersuite */
182296341Sdelphij            SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR);
183296341Sdelphij            return 0;
184296341Sdelphij        }
18555714Skris
186296341Sdelphij        for (j = 0; j < k; j++)
187296341Sdelphij            buf[j] = c;
188296341Sdelphij        c++;
189296341Sdelphij        EVP_DigestInit_ex(&s1, EVP_sha1(), NULL);
190296341Sdelphij        EVP_DigestUpdate(&s1, buf, k);
191296341Sdelphij        EVP_DigestUpdate(&s1, s->session->master_key,
192296341Sdelphij                         s->session->master_key_length);
193296341Sdelphij        EVP_DigestUpdate(&s1, s->s3->server_random, SSL3_RANDOM_SIZE);
194296341Sdelphij        EVP_DigestUpdate(&s1, s->s3->client_random, SSL3_RANDOM_SIZE);
195296341Sdelphij        EVP_DigestFinal_ex(&s1, smd, NULL);
19655714Skris
197296341Sdelphij        EVP_DigestInit_ex(&m5, EVP_md5(), NULL);
198296341Sdelphij        EVP_DigestUpdate(&m5, s->session->master_key,
199296341Sdelphij                         s->session->master_key_length);
200296341Sdelphij        EVP_DigestUpdate(&m5, smd, SHA_DIGEST_LENGTH);
201296341Sdelphij        if ((int)(i + MD5_DIGEST_LENGTH) > num) {
202296341Sdelphij            EVP_DigestFinal_ex(&m5, smd, NULL);
203296341Sdelphij            memcpy(km, smd, (num - i));
204296341Sdelphij        } else
205296341Sdelphij            EVP_DigestFinal_ex(&m5, km, NULL);
20655714Skris
207296341Sdelphij        km += MD5_DIGEST_LENGTH;
208296341Sdelphij    }
209296341Sdelphij    OPENSSL_cleanse(smd, SHA_DIGEST_LENGTH);
210296341Sdelphij    EVP_MD_CTX_cleanup(&m5);
211296341Sdelphij    EVP_MD_CTX_cleanup(&s1);
212296341Sdelphij    return 1;
213296341Sdelphij}
214296341Sdelphij
21555714Skrisint ssl3_change_cipher_state(SSL *s, int which)
216296341Sdelphij{
217296341Sdelphij    unsigned char *p, *mac_secret;
218296341Sdelphij    unsigned char exp_key[EVP_MAX_KEY_LENGTH];
219296341Sdelphij    unsigned char exp_iv[EVP_MAX_IV_LENGTH];
220296341Sdelphij    unsigned char *ms, *key, *iv, *er1, *er2;
221296341Sdelphij    EVP_CIPHER_CTX *dd;
222296341Sdelphij    const EVP_CIPHER *c;
223160814Ssimon#ifndef OPENSSL_NO_COMP
224296341Sdelphij    COMP_METHOD *comp;
225160814Ssimon#endif
226296341Sdelphij    const EVP_MD *m;
227296341Sdelphij    EVP_MD_CTX md;
228296341Sdelphij    int is_exp, n, i, j, k, cl;
229296341Sdelphij    int reuse_dd = 0;
23055714Skris
231296341Sdelphij    is_exp = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
232296341Sdelphij    c = s->s3->tmp.new_sym_enc;
233296341Sdelphij    m = s->s3->tmp.new_hash;
234296341Sdelphij    /* m == NULL will lead to a crash later */
235296341Sdelphij    OPENSSL_assert(m);
236160814Ssimon#ifndef OPENSSL_NO_COMP
237296341Sdelphij    if (s->s3->tmp.new_compression == NULL)
238296341Sdelphij        comp = NULL;
239296341Sdelphij    else
240296341Sdelphij        comp = s->s3->tmp.new_compression->method;
241160814Ssimon#endif
24255714Skris
243296341Sdelphij    if (which & SSL3_CC_READ) {
244296341Sdelphij        if (s->enc_read_ctx != NULL)
245296341Sdelphij            reuse_dd = 1;
246296341Sdelphij        else if ((s->enc_read_ctx =
247296341Sdelphij                  OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
248296341Sdelphij            goto err;
249296341Sdelphij        else
250296341Sdelphij            /*
251296341Sdelphij             * make sure it's intialized in case we exit later with an error
252296341Sdelphij             */
253296341Sdelphij            EVP_CIPHER_CTX_init(s->enc_read_ctx);
254296341Sdelphij        dd = s->enc_read_ctx;
255238405Sjkim
256296341Sdelphij        ssl_replace_hash(&s->read_hash, m);
257160814Ssimon#ifndef OPENSSL_NO_COMP
258296341Sdelphij        /* COMPRESS */
259296341Sdelphij        if (s->expand != NULL) {
260296341Sdelphij            COMP_CTX_free(s->expand);
261296341Sdelphij            s->expand = NULL;
262296341Sdelphij        }
263296341Sdelphij        if (comp != NULL) {
264296341Sdelphij            s->expand = COMP_CTX_new(comp);
265296341Sdelphij            if (s->expand == NULL) {
266296341Sdelphij                SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,
267296341Sdelphij                       SSL_R_COMPRESSION_LIBRARY_ERROR);
268296341Sdelphij                goto err2;
269296341Sdelphij            }
270296341Sdelphij            if (s->s3->rrec.comp == NULL)
271296341Sdelphij                s->s3->rrec.comp = (unsigned char *)
272296341Sdelphij                    OPENSSL_malloc(SSL3_RT_MAX_PLAIN_LENGTH);
273296341Sdelphij            if (s->s3->rrec.comp == NULL)
274296341Sdelphij                goto err;
275296341Sdelphij        }
276160814Ssimon#endif
277296341Sdelphij        memset(&(s->s3->read_sequence[0]), 0, 8);
278296341Sdelphij        mac_secret = &(s->s3->read_mac_secret[0]);
279296341Sdelphij    } else {
280296341Sdelphij        if (s->enc_write_ctx != NULL)
281296341Sdelphij            reuse_dd = 1;
282296341Sdelphij        else if ((s->enc_write_ctx =
283296341Sdelphij                  OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
284296341Sdelphij            goto err;
285296341Sdelphij        else
286296341Sdelphij            /*
287296341Sdelphij             * make sure it's intialized in case we exit later with an error
288296341Sdelphij             */
289296341Sdelphij            EVP_CIPHER_CTX_init(s->enc_write_ctx);
290296341Sdelphij        dd = s->enc_write_ctx;
291296341Sdelphij        ssl_replace_hash(&s->write_hash, m);
292160814Ssimon#ifndef OPENSSL_NO_COMP
293296341Sdelphij        /* COMPRESS */
294296341Sdelphij        if (s->compress != NULL) {
295296341Sdelphij            COMP_CTX_free(s->compress);
296296341Sdelphij            s->compress = NULL;
297296341Sdelphij        }
298296341Sdelphij        if (comp != NULL) {
299296341Sdelphij            s->compress = COMP_CTX_new(comp);
300296341Sdelphij            if (s->compress == NULL) {
301296341Sdelphij                SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,
302296341Sdelphij                       SSL_R_COMPRESSION_LIBRARY_ERROR);
303296341Sdelphij                goto err2;
304296341Sdelphij            }
305296341Sdelphij        }
306160814Ssimon#endif
307296341Sdelphij        memset(&(s->s3->write_sequence[0]), 0, 8);
308296341Sdelphij        mac_secret = &(s->s3->write_mac_secret[0]);
309296341Sdelphij    }
31055714Skris
311296341Sdelphij    if (reuse_dd)
312296341Sdelphij        EVP_CIPHER_CTX_cleanup(dd);
31355714Skris
314296341Sdelphij    p = s->s3->tmp.key_block;
315296341Sdelphij    i = EVP_MD_size(m);
316296341Sdelphij    if (i < 0)
317296341Sdelphij        goto err2;
318296341Sdelphij    cl = EVP_CIPHER_key_length(c);
319296341Sdelphij    j = is_exp ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ?
320296341Sdelphij                  cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl;
321296341Sdelphij    /* Was j=(is_exp)?5:EVP_CIPHER_key_length(c); */
322296341Sdelphij    k = EVP_CIPHER_iv_length(c);
323296341Sdelphij    if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
324296341Sdelphij        (which == SSL3_CHANGE_CIPHER_SERVER_READ)) {
325296341Sdelphij        ms = &(p[0]);
326296341Sdelphij        n = i + i;
327296341Sdelphij        key = &(p[n]);
328296341Sdelphij        n += j + j;
329296341Sdelphij        iv = &(p[n]);
330296341Sdelphij        n += k + k;
331296341Sdelphij        er1 = &(s->s3->client_random[0]);
332296341Sdelphij        er2 = &(s->s3->server_random[0]);
333296341Sdelphij    } else {
334296341Sdelphij        n = i;
335296341Sdelphij        ms = &(p[n]);
336296341Sdelphij        n += i + j;
337296341Sdelphij        key = &(p[n]);
338296341Sdelphij        n += j + k;
339296341Sdelphij        iv = &(p[n]);
340296341Sdelphij        n += k;
341296341Sdelphij        er1 = &(s->s3->server_random[0]);
342296341Sdelphij        er2 = &(s->s3->client_random[0]);
343296341Sdelphij    }
34455714Skris
345296341Sdelphij    if (n > s->s3->tmp.key_block_length) {
346296341Sdelphij        SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
347296341Sdelphij        goto err2;
348296341Sdelphij    }
34955714Skris
350296341Sdelphij    EVP_MD_CTX_init(&md);
351296341Sdelphij    memcpy(mac_secret, ms, i);
352296341Sdelphij    if (is_exp) {
353296341Sdelphij        /*
354296341Sdelphij         * In here I set both the read and write key/iv to the same value
355296341Sdelphij         * since only the correct one will be used :-).
356296341Sdelphij         */
357296341Sdelphij        EVP_DigestInit_ex(&md, EVP_md5(), NULL);
358296341Sdelphij        EVP_DigestUpdate(&md, key, j);
359296341Sdelphij        EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE);
360296341Sdelphij        EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE);
361296341Sdelphij        EVP_DigestFinal_ex(&md, &(exp_key[0]), NULL);
362296341Sdelphij        key = &(exp_key[0]);
36355714Skris
364296341Sdelphij        if (k > 0) {
365296341Sdelphij            EVP_DigestInit_ex(&md, EVP_md5(), NULL);
366296341Sdelphij            EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE);
367296341Sdelphij            EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE);
368296341Sdelphij            EVP_DigestFinal_ex(&md, &(exp_iv[0]), NULL);
369296341Sdelphij            iv = &(exp_iv[0]);
370296341Sdelphij        }
371296341Sdelphij    }
37255714Skris
373296341Sdelphij    s->session->key_arg_length = 0;
37455714Skris
375296341Sdelphij    EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE));
37655714Skris
377296341Sdelphij    OPENSSL_cleanse(&(exp_key[0]), sizeof(exp_key));
378296341Sdelphij    OPENSSL_cleanse(&(exp_iv[0]), sizeof(exp_iv));
379296341Sdelphij    EVP_MD_CTX_cleanup(&md);
380296341Sdelphij    return (1);
381296341Sdelphij err:
382296341Sdelphij    SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE);
383296341Sdelphij err2:
384296341Sdelphij    return (0);
385296341Sdelphij}
38655714Skris
38755714Skrisint ssl3_setup_key_block(SSL *s)
388296341Sdelphij{
389296341Sdelphij    unsigned char *p;
390296341Sdelphij    const EVP_CIPHER *c;
391296341Sdelphij    const EVP_MD *hash;
392296341Sdelphij    int num;
393296341Sdelphij    int ret = 0;
394296341Sdelphij    SSL_COMP *comp;
39555714Skris
396296341Sdelphij    if (s->s3->tmp.key_block_length != 0)
397296341Sdelphij        return (1);
39855714Skris
399296341Sdelphij    if (!ssl_cipher_get_evp(s->session, &c, &hash, NULL, NULL, &comp)) {
400296341Sdelphij        SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
401296341Sdelphij        return (0);
402296341Sdelphij    }
40355714Skris
404296341Sdelphij    s->s3->tmp.new_sym_enc = c;
405296341Sdelphij    s->s3->tmp.new_hash = hash;
406160814Ssimon#ifdef OPENSSL_NO_COMP
407296341Sdelphij    s->s3->tmp.new_compression = NULL;
408160814Ssimon#else
409296341Sdelphij    s->s3->tmp.new_compression = comp;
410160814Ssimon#endif
41155714Skris
412296341Sdelphij    num = EVP_MD_size(hash);
413296341Sdelphij    if (num < 0)
414296341Sdelphij        return 0;
415238405Sjkim
416296341Sdelphij    num = EVP_CIPHER_key_length(c) + num + EVP_CIPHER_iv_length(c);
417296341Sdelphij    num *= 2;
41855714Skris
419296341Sdelphij    ssl3_cleanup_key_block(s);
42055714Skris
421296341Sdelphij    if ((p = OPENSSL_malloc(num)) == NULL)
422296341Sdelphij        goto err;
42355714Skris
424296341Sdelphij    s->s3->tmp.key_block_length = num;
425296341Sdelphij    s->s3->tmp.key_block = p;
426109998Smarkm
427296341Sdelphij    ret = ssl3_generate_key_block(s, p, num);
428109998Smarkm
429296341Sdelphij    if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) {
430296341Sdelphij        /*
431296341Sdelphij         * enable vulnerability countermeasure for CBC ciphers with known-IV
432296341Sdelphij         * problem (http://www.openssl.org/~bodo/tls-cbc.txt)
433296341Sdelphij         */
434296341Sdelphij        s->s3->need_empty_fragments = 1;
435100936Snectar
436296341Sdelphij        if (s->session->cipher != NULL) {
437296341Sdelphij            if (s->session->cipher->algorithm_enc == SSL_eNULL)
438296341Sdelphij                s->s3->need_empty_fragments = 0;
439296341Sdelphij
440109998Smarkm#ifndef OPENSSL_NO_RC4
441296341Sdelphij            if (s->session->cipher->algorithm_enc == SSL_RC4)
442296341Sdelphij                s->s3->need_empty_fragments = 0;
443100928Snectar#endif
444296341Sdelphij        }
445296341Sdelphij    }
446109998Smarkm
447296341Sdelphij    return ret;
44855714Skris
449296341Sdelphij err:
450296341Sdelphij    SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE);
451296341Sdelphij    return (0);
452296341Sdelphij}
453296341Sdelphij
45455714Skrisvoid ssl3_cleanup_key_block(SSL *s)
455296341Sdelphij{
456296341Sdelphij    if (s->s3->tmp.key_block != NULL) {
457296341Sdelphij        OPENSSL_cleanse(s->s3->tmp.key_block, s->s3->tmp.key_block_length);
458296341Sdelphij        OPENSSL_free(s->s3->tmp.key_block);
459296341Sdelphij        s->s3->tmp.key_block = NULL;
460296341Sdelphij    }
461296341Sdelphij    s->s3->tmp.key_block_length = 0;
462296341Sdelphij}
46355714Skris
464296341Sdelphij/*-
465296341Sdelphij * ssl3_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively.
466246772Sjkim *
467246772Sjkim * Returns:
468246772Sjkim *   0: (in non-constant time) if the record is publically invalid (i.e. too
469246772Sjkim *       short etc).
470246772Sjkim *   1: if the record's padding is valid / the encryption was successful.
471246772Sjkim *   -1: if the record's padding is invalid or, if sending, an internal error
472246772Sjkim *       occured.
473246772Sjkim */
47455714Skrisint ssl3_enc(SSL *s, int send)
475296341Sdelphij{
476296341Sdelphij    SSL3_RECORD *rec;
477296341Sdelphij    EVP_CIPHER_CTX *ds;
478296341Sdelphij    unsigned long l;
479296341Sdelphij    int bs, i, mac_size = 0;
480296341Sdelphij    const EVP_CIPHER *enc;
48155714Skris
482296341Sdelphij    if (send) {
483296341Sdelphij        ds = s->enc_write_ctx;
484296341Sdelphij        rec = &(s->s3->wrec);
485296341Sdelphij        if (s->enc_write_ctx == NULL)
486296341Sdelphij            enc = NULL;
487296341Sdelphij        else
488296341Sdelphij            enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
489296341Sdelphij    } else {
490296341Sdelphij        ds = s->enc_read_ctx;
491296341Sdelphij        rec = &(s->s3->rrec);
492296341Sdelphij        if (s->enc_read_ctx == NULL)
493296341Sdelphij            enc = NULL;
494296341Sdelphij        else
495296341Sdelphij            enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
496296341Sdelphij    }
49755714Skris
498296341Sdelphij    if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) {
499296341Sdelphij        memmove(rec->data, rec->input, rec->length);
500296341Sdelphij        rec->input = rec->data;
501296341Sdelphij    } else {
502296341Sdelphij        l = rec->length;
503296341Sdelphij        bs = EVP_CIPHER_block_size(ds->cipher);
50455714Skris
505296341Sdelphij        /* COMPRESS */
50655714Skris
507296341Sdelphij        if ((bs != 1) && send) {
508296341Sdelphij            i = bs - ((int)l % bs);
50955714Skris
510296341Sdelphij            /* we need to add 'i-1' padding bytes */
511296341Sdelphij            l += i;
512296341Sdelphij            /*
513296341Sdelphij             * the last of these zero bytes will be overwritten with the
514296341Sdelphij             * padding length.
515296341Sdelphij             */
516296341Sdelphij            memset(&rec->input[rec->length], 0, i);
517296341Sdelphij            rec->length += i;
518296341Sdelphij            rec->input[l - 1] = (i - 1);
519296341Sdelphij        }
52055714Skris
521296341Sdelphij        if (!send) {
522296341Sdelphij            if (l == 0 || l % bs != 0)
523296341Sdelphij                return 0;
524296341Sdelphij            /* otherwise, rec->length >= bs */
525296341Sdelphij        }
52655714Skris
527296341Sdelphij        if (EVP_Cipher(ds, rec->data, rec->input, l) < 1)
528296341Sdelphij            return -1;
52955714Skris
530296341Sdelphij        if (EVP_MD_CTX_md(s->read_hash) != NULL)
531296341Sdelphij            mac_size = EVP_MD_CTX_size(s->read_hash);
532296341Sdelphij        if ((bs != 1) && !send)
533296341Sdelphij            return ssl3_cbc_remove_padding(s, rec, bs, mac_size);
534296341Sdelphij    }
535296341Sdelphij    return (1);
536296341Sdelphij}
537238405Sjkim
538296341Sdelphijvoid ssl3_init_finished_mac(SSL *s)
539296341Sdelphij{
540296341Sdelphij    if (s->s3->handshake_buffer)
541296341Sdelphij        BIO_free(s->s3->handshake_buffer);
542296341Sdelphij    if (s->s3->handshake_dgst)
543296341Sdelphij        ssl3_free_digest_list(s);
544296341Sdelphij    s->s3->handshake_buffer = BIO_new(BIO_s_mem());
545296341Sdelphij    (void)BIO_set_close(s->s3->handshake_buffer, BIO_CLOSE);
546296341Sdelphij}
547238405Sjkim
548296341Sdelphijvoid ssl3_free_digest_list(SSL *s)
549296341Sdelphij{
550296341Sdelphij    int i;
551296341Sdelphij    if (!s->s3->handshake_dgst)
552296341Sdelphij        return;
553296341Sdelphij    for (i = 0; i < SSL_MAX_DIGEST; i++) {
554296341Sdelphij        if (s->s3->handshake_dgst[i])
555296341Sdelphij            EVP_MD_CTX_destroy(s->s3->handshake_dgst[i]);
556296341Sdelphij    }
557296341Sdelphij    OPENSSL_free(s->s3->handshake_dgst);
558296341Sdelphij    s->s3->handshake_dgst = NULL;
559296341Sdelphij}
560238405Sjkim
56155714Skrisvoid ssl3_finish_mac(SSL *s, const unsigned char *buf, int len)
562296341Sdelphij{
563296341Sdelphij    if (s->s3->handshake_buffer
564296341Sdelphij        && !(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) {
565296341Sdelphij        BIO_write(s->s3->handshake_buffer, (void *)buf, len);
566296341Sdelphij    } else {
567296341Sdelphij        int i;
568296341Sdelphij        for (i = 0; i < SSL_MAX_DIGEST; i++) {
569296341Sdelphij            if (s->s3->handshake_dgst[i] != NULL)
570296341Sdelphij                EVP_DigestUpdate(s->s3->handshake_dgst[i], buf, len);
571296341Sdelphij        }
572296341Sdelphij    }
573296341Sdelphij}
57455714Skris
575238405Sjkimint ssl3_digest_cached_records(SSL *s)
576296341Sdelphij{
577296341Sdelphij    int i;
578296341Sdelphij    long mask;
579296341Sdelphij    const EVP_MD *md;
580296341Sdelphij    long hdatalen;
581296341Sdelphij    void *hdata;
582238405Sjkim
583296341Sdelphij    /* Allocate handshake_dgst array */
584296341Sdelphij    ssl3_free_digest_list(s);
585296341Sdelphij    s->s3->handshake_dgst =
586296341Sdelphij        OPENSSL_malloc(SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *));
587296341Sdelphij    memset(s->s3->handshake_dgst, 0, SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *));
588296341Sdelphij    hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
589296341Sdelphij    if (hdatalen <= 0) {
590296341Sdelphij        SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, SSL_R_BAD_HANDSHAKE_LENGTH);
591296341Sdelphij        return 0;
592296341Sdelphij    }
593238405Sjkim
594296341Sdelphij    /* Loop through bitso of algorithm2 field and create MD_CTX-es */
595296341Sdelphij    for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++) {
596296341Sdelphij        if ((mask & ssl_get_algorithm2(s)) && md) {
597296341Sdelphij            s->s3->handshake_dgst[i] = EVP_MD_CTX_create();
598238405Sjkim#ifdef OPENSSL_FIPS
599296341Sdelphij            if (EVP_MD_nid(md) == NID_md5) {
600296341Sdelphij                EVP_MD_CTX_set_flags(s->s3->handshake_dgst[i],
601296341Sdelphij                                     EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
602296341Sdelphij            }
603238405Sjkim#endif
604296341Sdelphij            EVP_DigestInit_ex(s->s3->handshake_dgst[i], md, NULL);
605296341Sdelphij            EVP_DigestUpdate(s->s3->handshake_dgst[i], hdata, hdatalen);
606296341Sdelphij        } else {
607296341Sdelphij            s->s3->handshake_dgst[i] = NULL;
608296341Sdelphij        }
609296341Sdelphij    }
610296341Sdelphij    if (!(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) {
611296341Sdelphij        /* Free handshake_buffer BIO */
612296341Sdelphij        BIO_free(s->s3->handshake_buffer);
613296341Sdelphij        s->s3->handshake_buffer = NULL;
614296341Sdelphij    }
615238405Sjkim
616296341Sdelphij    return 1;
617296341Sdelphij}
61855714Skris
619238405Sjkimint ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p)
620296341Sdelphij{
621296341Sdelphij    return (ssl3_handshake_mac(s, md_nid, NULL, 0, p));
622296341Sdelphij}
623269686Sjkim
624296341Sdelphijint ssl3_final_finish_mac(SSL *s,
625296341Sdelphij                          const char *sender, int len, unsigned char *p)
626296341Sdelphij{
627296341Sdelphij    int ret, sha1len;
628296341Sdelphij    ret = ssl3_handshake_mac(s, NID_md5, sender, len, p);
629296341Sdelphij    if (ret == 0)
630296341Sdelphij        return 0;
631269686Sjkim
632296341Sdelphij    p += ret;
633269686Sjkim
634296341Sdelphij    sha1len = ssl3_handshake_mac(s, NID_sha1, sender, len, p);
635296341Sdelphij    if (sha1len == 0)
636296341Sdelphij        return 0;
637296341Sdelphij
638296341Sdelphij    ret += sha1len;
639296341Sdelphij    return (ret);
640296341Sdelphij}
641296341Sdelphij
642238405Sjkimstatic int ssl3_handshake_mac(SSL *s, int md_nid,
643296341Sdelphij                              const char *sender, int len, unsigned char *p)
644296341Sdelphij{
645296341Sdelphij    unsigned int ret;
646296341Sdelphij    int npad, n;
647296341Sdelphij    unsigned int i;
648296341Sdelphij    unsigned char md_buf[EVP_MAX_MD_SIZE];
649296341Sdelphij    EVP_MD_CTX ctx, *d = NULL;
65055714Skris
651296341Sdelphij    if (s->s3->handshake_buffer)
652296341Sdelphij        if (!ssl3_digest_cached_records(s))
653296341Sdelphij            return 0;
654238405Sjkim
655296341Sdelphij    /*
656296341Sdelphij     * Search for digest of specified type in the handshake_dgst array
657296341Sdelphij     */
658296341Sdelphij    for (i = 0; i < SSL_MAX_DIGEST; i++) {
659296341Sdelphij        if (s->s3->handshake_dgst[i]
660296341Sdelphij            && EVP_MD_CTX_type(s->s3->handshake_dgst[i]) == md_nid) {
661296341Sdelphij            d = s->s3->handshake_dgst[i];
662296341Sdelphij            break;
663296341Sdelphij        }
664296341Sdelphij    }
665296341Sdelphij    if (!d) {
666296341Sdelphij        SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, SSL_R_NO_REQUIRED_DIGEST);
667296341Sdelphij        return 0;
668296341Sdelphij    }
669296341Sdelphij    EVP_MD_CTX_init(&ctx);
670296341Sdelphij    EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
671296341Sdelphij    EVP_MD_CTX_copy_ex(&ctx, d);
672296341Sdelphij    n = EVP_MD_CTX_size(&ctx);
673296341Sdelphij    if (n < 0)
674296341Sdelphij        return 0;
67555714Skris
676296341Sdelphij    npad = (48 / n) * n;
677296341Sdelphij    if (sender != NULL)
678296341Sdelphij        EVP_DigestUpdate(&ctx, sender, len);
679296341Sdelphij    EVP_DigestUpdate(&ctx, s->session->master_key,
680296341Sdelphij                     s->session->master_key_length);
681296341Sdelphij    EVP_DigestUpdate(&ctx, ssl3_pad_1, npad);
682296341Sdelphij    EVP_DigestFinal_ex(&ctx, md_buf, &i);
68355714Skris
684296341Sdelphij    EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL);
685296341Sdelphij    EVP_DigestUpdate(&ctx, s->session->master_key,
686296341Sdelphij                     s->session->master_key_length);
687296341Sdelphij    EVP_DigestUpdate(&ctx, ssl3_pad_2, npad);
688296341Sdelphij    EVP_DigestUpdate(&ctx, md_buf, i);
689296341Sdelphij    EVP_DigestFinal_ex(&ctx, p, &ret);
69055714Skris
691296341Sdelphij    EVP_MD_CTX_cleanup(&ctx);
69255714Skris
693296341Sdelphij    return ((int)ret);
694296341Sdelphij}
69555714Skris
696238405Sjkimint n_ssl3_mac(SSL *ssl, unsigned char *md, int send)
697296341Sdelphij{
698296341Sdelphij    SSL3_RECORD *rec;
699296341Sdelphij    unsigned char *mac_sec, *seq;
700296341Sdelphij    EVP_MD_CTX md_ctx;
701296341Sdelphij    const EVP_MD_CTX *hash;
702296341Sdelphij    unsigned char *p, rec_char;
703296341Sdelphij    size_t md_size, orig_len;
704296341Sdelphij    int npad;
705296341Sdelphij    int t;
70655714Skris
707296341Sdelphij    if (send) {
708296341Sdelphij        rec = &(ssl->s3->wrec);
709296341Sdelphij        mac_sec = &(ssl->s3->write_mac_secret[0]);
710296341Sdelphij        seq = &(ssl->s3->write_sequence[0]);
711296341Sdelphij        hash = ssl->write_hash;
712296341Sdelphij    } else {
713296341Sdelphij        rec = &(ssl->s3->rrec);
714296341Sdelphij        mac_sec = &(ssl->s3->read_mac_secret[0]);
715296341Sdelphij        seq = &(ssl->s3->read_sequence[0]);
716296341Sdelphij        hash = ssl->read_hash;
717296341Sdelphij    }
71855714Skris
719296341Sdelphij    t = EVP_MD_CTX_size(hash);
720296341Sdelphij    if (t < 0)
721296341Sdelphij        return -1;
722296341Sdelphij    md_size = t;
723296341Sdelphij    npad = (48 / md_size) * md_size;
72455714Skris
725296341Sdelphij    /*
726296341Sdelphij     * kludge: ssl3_cbc_remove_padding passes padding length in rec->type
727296341Sdelphij     */
728296341Sdelphij    orig_len = rec->length + md_size + ((unsigned int)rec->type >> 8);
729296341Sdelphij    rec->type &= 0xff;
73055714Skris
731296341Sdelphij    if (!send &&
732296341Sdelphij        EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
733296341Sdelphij        ssl3_cbc_record_digest_supported(hash)) {
734296341Sdelphij        /*
735296341Sdelphij         * This is a CBC-encrypted record. We must avoid leaking any
736296341Sdelphij         * timing-side channel information about how many blocks of data we
737296341Sdelphij         * are hashing because that gives an attacker a timing-oracle.
738296341Sdelphij         */
73955714Skris
740296341Sdelphij        /*-
741296341Sdelphij         * npad is, at most, 48 bytes and that's with MD5:
742296341Sdelphij         *   16 + 48 + 8 (sequence bytes) + 1 + 2 = 75.
743296341Sdelphij         *
744296341Sdelphij         * With SHA-1 (the largest hash speced for SSLv3) the hash size
745296341Sdelphij         * goes up 4, but npad goes down by 8, resulting in a smaller
746296341Sdelphij         * total size.
747296341Sdelphij         */
748296341Sdelphij        unsigned char header[75];
749296341Sdelphij        unsigned j = 0;
750296341Sdelphij        memcpy(header + j, mac_sec, md_size);
751296341Sdelphij        j += md_size;
752296341Sdelphij        memcpy(header + j, ssl3_pad_1, npad);
753296341Sdelphij        j += npad;
754296341Sdelphij        memcpy(header + j, seq, 8);
755296341Sdelphij        j += 8;
756296341Sdelphij        header[j++] = rec->type;
757296341Sdelphij        header[j++] = rec->length >> 8;
758296341Sdelphij        header[j++] = rec->length & 0xff;
75955714Skris
760296341Sdelphij        /* Final param == is SSLv3 */
761296341Sdelphij        ssl3_cbc_digest_record(hash,
762296341Sdelphij                               md, &md_size,
763296341Sdelphij                               header, rec->input,
764296341Sdelphij                               rec->length + md_size, orig_len,
765296341Sdelphij                               mac_sec, md_size, 1);
766296341Sdelphij    } else {
767296341Sdelphij        unsigned int md_size_u;
768296341Sdelphij        /* Chop the digest off the end :-) */
769296341Sdelphij        EVP_MD_CTX_init(&md_ctx);
770109998Smarkm
771296341Sdelphij        EVP_MD_CTX_copy_ex(&md_ctx, hash);
772296341Sdelphij        EVP_DigestUpdate(&md_ctx, mac_sec, md_size);
773296341Sdelphij        EVP_DigestUpdate(&md_ctx, ssl3_pad_1, npad);
774296341Sdelphij        EVP_DigestUpdate(&md_ctx, seq, 8);
775296341Sdelphij        rec_char = rec->type;
776296341Sdelphij        EVP_DigestUpdate(&md_ctx, &rec_char, 1);
777296341Sdelphij        p = md;
778296341Sdelphij        s2n(rec->length, p);
779296341Sdelphij        EVP_DigestUpdate(&md_ctx, md, 2);
780296341Sdelphij        EVP_DigestUpdate(&md_ctx, rec->input, rec->length);
781296341Sdelphij        EVP_DigestFinal_ex(&md_ctx, md, NULL);
782246772Sjkim
783296341Sdelphij        EVP_MD_CTX_copy_ex(&md_ctx, hash);
784296341Sdelphij        EVP_DigestUpdate(&md_ctx, mac_sec, md_size);
785296341Sdelphij        EVP_DigestUpdate(&md_ctx, ssl3_pad_2, npad);
786296341Sdelphij        EVP_DigestUpdate(&md_ctx, md, md_size);
787296341Sdelphij        EVP_DigestFinal_ex(&md_ctx, md, &md_size_u);
788296341Sdelphij        md_size = md_size_u;
789246772Sjkim
790296341Sdelphij        EVP_MD_CTX_cleanup(&md_ctx);
791296341Sdelphij    }
792246772Sjkim
793296341Sdelphij    ssl3_record_sequence_update(seq);
794296341Sdelphij    return (md_size);
795296341Sdelphij}
796160814Ssimon
797160814Ssimonvoid ssl3_record_sequence_update(unsigned char *seq)
798296341Sdelphij{
799296341Sdelphij    int i;
800160814Ssimon
801296341Sdelphij    for (i = 7; i >= 0; i--) {
802296341Sdelphij        ++seq[i];
803296341Sdelphij        if (seq[i] != 0)
804296341Sdelphij            break;
805296341Sdelphij    }
806296341Sdelphij}
80755714Skris
80855714Skrisint ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
809296341Sdelphij                                int len)
810296341Sdelphij{
811296341Sdelphij    static const unsigned char *salt[3] = {
81255714Skris#ifndef CHARSET_EBCDIC
813296341Sdelphij        (const unsigned char *)"A",
814296341Sdelphij        (const unsigned char *)"BB",
815296341Sdelphij        (const unsigned char *)"CCC",
81655714Skris#else
817296341Sdelphij        (const unsigned char *)"\x41",
818296341Sdelphij        (const unsigned char *)"\x42\x42",
819296341Sdelphij        (const unsigned char *)"\x43\x43\x43",
82055714Skris#endif
821296341Sdelphij    };
822296341Sdelphij    unsigned char buf[EVP_MAX_MD_SIZE];
823296341Sdelphij    EVP_MD_CTX ctx;
824296341Sdelphij    int i, ret = 0;
825296341Sdelphij    unsigned int n;
82655714Skris
827296341Sdelphij    EVP_MD_CTX_init(&ctx);
828296341Sdelphij    for (i = 0; i < 3; i++) {
829296341Sdelphij        EVP_DigestInit_ex(&ctx, s->ctx->sha1, NULL);
830296341Sdelphij        EVP_DigestUpdate(&ctx, salt[i], strlen((const char *)salt[i]));
831296341Sdelphij        EVP_DigestUpdate(&ctx, p, len);
832296341Sdelphij        EVP_DigestUpdate(&ctx, &(s->s3->client_random[0]), SSL3_RANDOM_SIZE);
833296341Sdelphij        EVP_DigestUpdate(&ctx, &(s->s3->server_random[0]), SSL3_RANDOM_SIZE);
834296341Sdelphij        EVP_DigestFinal_ex(&ctx, buf, &n);
83555714Skris
836296341Sdelphij        EVP_DigestInit_ex(&ctx, s->ctx->md5, NULL);
837296341Sdelphij        EVP_DigestUpdate(&ctx, p, len);
838296341Sdelphij        EVP_DigestUpdate(&ctx, buf, n);
839296341Sdelphij        EVP_DigestFinal_ex(&ctx, out, &n);
840296341Sdelphij        out += n;
841296341Sdelphij        ret += n;
842296341Sdelphij    }
843296341Sdelphij    EVP_MD_CTX_cleanup(&ctx);
844296341Sdelphij    OPENSSL_cleanse(buf, sizeof buf);
845296341Sdelphij    return (ret);
846296341Sdelphij}
84755714Skris
84855714Skrisint ssl3_alert_code(int code)
849296341Sdelphij{
850296341Sdelphij    switch (code) {
851296341Sdelphij    case SSL_AD_CLOSE_NOTIFY:
852296341Sdelphij        return (SSL3_AD_CLOSE_NOTIFY);
853296341Sdelphij    case SSL_AD_UNEXPECTED_MESSAGE:
854296341Sdelphij        return (SSL3_AD_UNEXPECTED_MESSAGE);
855296341Sdelphij    case SSL_AD_BAD_RECORD_MAC:
856296341Sdelphij        return (SSL3_AD_BAD_RECORD_MAC);
857296341Sdelphij    case SSL_AD_DECRYPTION_FAILED:
858296341Sdelphij        return (SSL3_AD_BAD_RECORD_MAC);
859296341Sdelphij    case SSL_AD_RECORD_OVERFLOW:
860296341Sdelphij        return (SSL3_AD_BAD_RECORD_MAC);
861296341Sdelphij    case SSL_AD_DECOMPRESSION_FAILURE:
862296341Sdelphij        return (SSL3_AD_DECOMPRESSION_FAILURE);
863296341Sdelphij    case SSL_AD_HANDSHAKE_FAILURE:
864296341Sdelphij        return (SSL3_AD_HANDSHAKE_FAILURE);
865296341Sdelphij    case SSL_AD_NO_CERTIFICATE:
866296341Sdelphij        return (SSL3_AD_NO_CERTIFICATE);
867296341Sdelphij    case SSL_AD_BAD_CERTIFICATE:
868296341Sdelphij        return (SSL3_AD_BAD_CERTIFICATE);
869296341Sdelphij    case SSL_AD_UNSUPPORTED_CERTIFICATE:
870296341Sdelphij        return (SSL3_AD_UNSUPPORTED_CERTIFICATE);
871296341Sdelphij    case SSL_AD_CERTIFICATE_REVOKED:
872296341Sdelphij        return (SSL3_AD_CERTIFICATE_REVOKED);
873296341Sdelphij    case SSL_AD_CERTIFICATE_EXPIRED:
874296341Sdelphij        return (SSL3_AD_CERTIFICATE_EXPIRED);
875296341Sdelphij    case SSL_AD_CERTIFICATE_UNKNOWN:
876296341Sdelphij        return (SSL3_AD_CERTIFICATE_UNKNOWN);
877296341Sdelphij    case SSL_AD_ILLEGAL_PARAMETER:
878296341Sdelphij        return (SSL3_AD_ILLEGAL_PARAMETER);
879296341Sdelphij    case SSL_AD_UNKNOWN_CA:
880296341Sdelphij        return (SSL3_AD_BAD_CERTIFICATE);
881296341Sdelphij    case SSL_AD_ACCESS_DENIED:
882296341Sdelphij        return (SSL3_AD_HANDSHAKE_FAILURE);
883296341Sdelphij    case SSL_AD_DECODE_ERROR:
884296341Sdelphij        return (SSL3_AD_HANDSHAKE_FAILURE);
885296341Sdelphij    case SSL_AD_DECRYPT_ERROR:
886296341Sdelphij        return (SSL3_AD_HANDSHAKE_FAILURE);
887296341Sdelphij    case SSL_AD_EXPORT_RESTRICTION:
888296341Sdelphij        return (SSL3_AD_HANDSHAKE_FAILURE);
889296341Sdelphij    case SSL_AD_PROTOCOL_VERSION:
890296341Sdelphij        return (SSL3_AD_HANDSHAKE_FAILURE);
891296341Sdelphij    case SSL_AD_INSUFFICIENT_SECURITY:
892296341Sdelphij        return (SSL3_AD_HANDSHAKE_FAILURE);
893296341Sdelphij    case SSL_AD_INTERNAL_ERROR:
894296341Sdelphij        return (SSL3_AD_HANDSHAKE_FAILURE);
895296341Sdelphij    case SSL_AD_USER_CANCELLED:
896296341Sdelphij        return (SSL3_AD_HANDSHAKE_FAILURE);
897296341Sdelphij    case SSL_AD_NO_RENEGOTIATION:
898296341Sdelphij        return (-1);            /* Don't send it :-) */
899296341Sdelphij    case SSL_AD_UNSUPPORTED_EXTENSION:
900296341Sdelphij        return (SSL3_AD_HANDSHAKE_FAILURE);
901296341Sdelphij    case SSL_AD_CERTIFICATE_UNOBTAINABLE:
902296341Sdelphij        return (SSL3_AD_HANDSHAKE_FAILURE);
903296341Sdelphij    case SSL_AD_UNRECOGNIZED_NAME:
904296341Sdelphij        return (SSL3_AD_HANDSHAKE_FAILURE);
905296341Sdelphij    case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
906296341Sdelphij        return (SSL3_AD_HANDSHAKE_FAILURE);
907296341Sdelphij    case SSL_AD_BAD_CERTIFICATE_HASH_VALUE:
908296341Sdelphij        return (SSL3_AD_HANDSHAKE_FAILURE);
909296341Sdelphij    case SSL_AD_UNKNOWN_PSK_IDENTITY:
910296341Sdelphij        return (TLS1_AD_UNKNOWN_PSK_IDENTITY);
911296341Sdelphij    case SSL_AD_INAPPROPRIATE_FALLBACK:
912296341Sdelphij        return (TLS1_AD_INAPPROPRIATE_FALLBACK);
913296341Sdelphij    default:
914296341Sdelphij        return (-1);
915296341Sdelphij    }
916296341Sdelphij}
917