xref: /minix3/crypto/external/bsd/openssl/dist/ssl/s3_enc.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1ebfedea0SLionel Sambuc /* ssl/s3_enc.c */
2ebfedea0SLionel Sambuc /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3ebfedea0SLionel Sambuc  * All rights reserved.
4ebfedea0SLionel Sambuc  *
5ebfedea0SLionel Sambuc  * This package is an SSL implementation written
6ebfedea0SLionel Sambuc  * by Eric Young (eay@cryptsoft.com).
7ebfedea0SLionel Sambuc  * The implementation was written so as to conform with Netscapes SSL.
8ebfedea0SLionel Sambuc  *
9ebfedea0SLionel Sambuc  * This library is free for commercial and non-commercial use as long as
10ebfedea0SLionel Sambuc  * the following conditions are aheared to.  The following conditions
11ebfedea0SLionel Sambuc  * apply to all code found in this distribution, be it the RC4, RSA,
12ebfedea0SLionel Sambuc  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13ebfedea0SLionel Sambuc  * included with this distribution is covered by the same copyright terms
14ebfedea0SLionel Sambuc  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15ebfedea0SLionel Sambuc  *
16ebfedea0SLionel Sambuc  * Copyright remains Eric Young's, and as such any Copyright notices in
17ebfedea0SLionel Sambuc  * the code are not to be removed.
18ebfedea0SLionel Sambuc  * If this package is used in a product, Eric Young should be given attribution
19ebfedea0SLionel Sambuc  * as the author of the parts of the library used.
20ebfedea0SLionel Sambuc  * This can be in the form of a textual message at program startup or
21ebfedea0SLionel Sambuc  * in documentation (online or textual) provided with the package.
22ebfedea0SLionel Sambuc  *
23ebfedea0SLionel Sambuc  * Redistribution and use in source and binary forms, with or without
24ebfedea0SLionel Sambuc  * modification, are permitted provided that the following conditions
25ebfedea0SLionel Sambuc  * are met:
26ebfedea0SLionel Sambuc  * 1. Redistributions of source code must retain the copyright
27ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
28ebfedea0SLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
29ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
30ebfedea0SLionel Sambuc  *    documentation and/or other materials provided with the distribution.
31ebfedea0SLionel Sambuc  * 3. All advertising materials mentioning features or use of this software
32ebfedea0SLionel Sambuc  *    must display the following acknowledgement:
33ebfedea0SLionel Sambuc  *    "This product includes cryptographic software written by
34ebfedea0SLionel Sambuc  *     Eric Young (eay@cryptsoft.com)"
35ebfedea0SLionel Sambuc  *    The word 'cryptographic' can be left out if the rouines from the library
36ebfedea0SLionel Sambuc  *    being used are not cryptographic related :-).
37ebfedea0SLionel Sambuc  * 4. If you include any Windows specific code (or a derivative thereof) from
38ebfedea0SLionel Sambuc  *    the apps directory (application code) you must include an acknowledgement:
39ebfedea0SLionel Sambuc  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40ebfedea0SLionel Sambuc  *
41ebfedea0SLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42ebfedea0SLionel Sambuc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43ebfedea0SLionel Sambuc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44ebfedea0SLionel Sambuc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45ebfedea0SLionel Sambuc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46ebfedea0SLionel Sambuc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47ebfedea0SLionel Sambuc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48ebfedea0SLionel Sambuc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49ebfedea0SLionel Sambuc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50ebfedea0SLionel Sambuc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51ebfedea0SLionel Sambuc  * SUCH DAMAGE.
52ebfedea0SLionel Sambuc  *
53ebfedea0SLionel Sambuc  * The licence and distribution terms for any publically available version or
54ebfedea0SLionel Sambuc  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55ebfedea0SLionel Sambuc  * copied and put under another distribution licence
56ebfedea0SLionel Sambuc  * [including the GNU Public Licence.]
57ebfedea0SLionel Sambuc  */
58ebfedea0SLionel Sambuc /* ====================================================================
59ebfedea0SLionel Sambuc  * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
60ebfedea0SLionel Sambuc  *
61ebfedea0SLionel Sambuc  * Redistribution and use in source and binary forms, with or without
62ebfedea0SLionel Sambuc  * modification, are permitted provided that the following conditions
63ebfedea0SLionel Sambuc  * are met:
64ebfedea0SLionel Sambuc  *
65ebfedea0SLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
66ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
67ebfedea0SLionel Sambuc  *
68ebfedea0SLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
69ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer in
70ebfedea0SLionel Sambuc  *    the documentation and/or other materials provided with the
71ebfedea0SLionel Sambuc  *    distribution.
72ebfedea0SLionel Sambuc  *
73ebfedea0SLionel Sambuc  * 3. All advertising materials mentioning features or use of this
74ebfedea0SLionel Sambuc  *    software must display the following acknowledgment:
75ebfedea0SLionel Sambuc  *    "This product includes software developed by the OpenSSL Project
76ebfedea0SLionel Sambuc  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77ebfedea0SLionel Sambuc  *
78ebfedea0SLionel Sambuc  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79ebfedea0SLionel Sambuc  *    endorse or promote products derived from this software without
80ebfedea0SLionel Sambuc  *    prior written permission. For written permission, please contact
81ebfedea0SLionel Sambuc  *    openssl-core@openssl.org.
82ebfedea0SLionel Sambuc  *
83ebfedea0SLionel Sambuc  * 5. Products derived from this software may not be called "OpenSSL"
84ebfedea0SLionel Sambuc  *    nor may "OpenSSL" appear in their names without prior written
85ebfedea0SLionel Sambuc  *    permission of the OpenSSL Project.
86ebfedea0SLionel Sambuc  *
87ebfedea0SLionel Sambuc  * 6. Redistributions of any form whatsoever must retain the following
88ebfedea0SLionel Sambuc  *    acknowledgment:
89ebfedea0SLionel Sambuc  *    "This product includes software developed by the OpenSSL Project
90ebfedea0SLionel Sambuc  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91ebfedea0SLionel Sambuc  *
92ebfedea0SLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93ebfedea0SLionel Sambuc  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94ebfedea0SLionel Sambuc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95ebfedea0SLionel Sambuc  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96ebfedea0SLionel Sambuc  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97ebfedea0SLionel Sambuc  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98ebfedea0SLionel Sambuc  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99ebfedea0SLionel Sambuc  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100ebfedea0SLionel Sambuc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101ebfedea0SLionel Sambuc  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102ebfedea0SLionel Sambuc  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103ebfedea0SLionel Sambuc  * OF THE POSSIBILITY OF SUCH DAMAGE.
104ebfedea0SLionel Sambuc  * ====================================================================
105ebfedea0SLionel Sambuc  *
106ebfedea0SLionel Sambuc  * This product includes cryptographic software written by Eric Young
107ebfedea0SLionel Sambuc  * (eay@cryptsoft.com).  This product includes software written by Tim
108ebfedea0SLionel Sambuc  * Hudson (tjh@cryptsoft.com).
109ebfedea0SLionel Sambuc  *
110ebfedea0SLionel Sambuc  */
111ebfedea0SLionel Sambuc /* ====================================================================
112ebfedea0SLionel Sambuc  * Copyright 2005 Nokia. All rights reserved.
113ebfedea0SLionel Sambuc  *
114ebfedea0SLionel Sambuc  * The portions of the attached software ("Contribution") is developed by
115ebfedea0SLionel Sambuc  * Nokia Corporation and is licensed pursuant to the OpenSSL open source
116ebfedea0SLionel Sambuc  * license.
117ebfedea0SLionel Sambuc  *
118ebfedea0SLionel Sambuc  * The Contribution, originally written by Mika Kousa and Pasi Eronen of
119ebfedea0SLionel Sambuc  * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
120ebfedea0SLionel Sambuc  * support (see RFC 4279) to OpenSSL.
121ebfedea0SLionel Sambuc  *
122ebfedea0SLionel Sambuc  * No patent licenses or other rights except those expressly stated in
123ebfedea0SLionel Sambuc  * the OpenSSL open source license shall be deemed granted or received
124ebfedea0SLionel Sambuc  * expressly, by implication, estoppel, or otherwise.
125ebfedea0SLionel Sambuc  *
126ebfedea0SLionel Sambuc  * No assurances are provided by Nokia that the Contribution does not
127ebfedea0SLionel Sambuc  * infringe the patent or other intellectual property rights of any third
128ebfedea0SLionel Sambuc  * party or that the license provides you with all the necessary rights
129ebfedea0SLionel Sambuc  * to make use of the Contribution.
130ebfedea0SLionel Sambuc  *
131ebfedea0SLionel Sambuc  * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
132ebfedea0SLionel Sambuc  * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
133ebfedea0SLionel Sambuc  * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
134ebfedea0SLionel Sambuc  * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
135ebfedea0SLionel Sambuc  * OTHERWISE.
136ebfedea0SLionel Sambuc  */
137ebfedea0SLionel Sambuc 
138ebfedea0SLionel Sambuc #include <stdio.h>
139ebfedea0SLionel Sambuc #include "ssl_locl.h"
140ebfedea0SLionel Sambuc #include <openssl/evp.h>
141ebfedea0SLionel Sambuc #include <openssl/md5.h>
142ebfedea0SLionel Sambuc 
143ebfedea0SLionel Sambuc static unsigned char ssl3_pad_1[48] = {
144ebfedea0SLionel Sambuc     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
145ebfedea0SLionel Sambuc     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
146ebfedea0SLionel Sambuc     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
147ebfedea0SLionel Sambuc     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
148ebfedea0SLionel Sambuc     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
149*0a6a1f1dSLionel Sambuc     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
150*0a6a1f1dSLionel Sambuc };
151ebfedea0SLionel Sambuc 
152ebfedea0SLionel Sambuc static unsigned char ssl3_pad_2[48] = {
153ebfedea0SLionel Sambuc     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
154ebfedea0SLionel Sambuc     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
155ebfedea0SLionel Sambuc     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
156ebfedea0SLionel Sambuc     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
157ebfedea0SLionel Sambuc     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
158*0a6a1f1dSLionel Sambuc     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
159*0a6a1f1dSLionel Sambuc };
160*0a6a1f1dSLionel Sambuc 
161ebfedea0SLionel Sambuc static int ssl3_handshake_mac(SSL *s, int md_nid,
162ebfedea0SLionel Sambuc                               const char *sender, int len, unsigned char *p);
ssl3_generate_key_block(SSL * s,unsigned char * km,int num)163ebfedea0SLionel Sambuc static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
164ebfedea0SLionel Sambuc {
165ebfedea0SLionel Sambuc     EVP_MD_CTX m5;
166ebfedea0SLionel Sambuc     EVP_MD_CTX s1;
167ebfedea0SLionel Sambuc     unsigned char buf[16], smd[SHA_DIGEST_LENGTH];
168ebfedea0SLionel Sambuc     unsigned char c = 'A';
169ebfedea0SLionel Sambuc     unsigned int i, j, k;
170ebfedea0SLionel Sambuc 
171ebfedea0SLionel Sambuc #ifdef CHARSET_EBCDIC
172ebfedea0SLionel Sambuc     c = os_toascii[c];          /* 'A' in ASCII */
173ebfedea0SLionel Sambuc #endif
174ebfedea0SLionel Sambuc     k = 0;
175ebfedea0SLionel Sambuc     EVP_MD_CTX_init(&m5);
176ebfedea0SLionel Sambuc     EVP_MD_CTX_set_flags(&m5, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
177ebfedea0SLionel Sambuc     EVP_MD_CTX_init(&s1);
178*0a6a1f1dSLionel Sambuc     for (i = 0; (int)i < num; i += MD5_DIGEST_LENGTH) {
179ebfedea0SLionel Sambuc         k++;
180*0a6a1f1dSLionel Sambuc         if (k > sizeof buf) {
181ebfedea0SLionel Sambuc             /* bug: 'buf' is too small for this ciphersuite */
182ebfedea0SLionel Sambuc             SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR);
183ebfedea0SLionel Sambuc             return 0;
184ebfedea0SLionel Sambuc         }
185ebfedea0SLionel Sambuc 
186ebfedea0SLionel Sambuc         for (j = 0; j < k; j++)
187ebfedea0SLionel Sambuc             buf[j] = c;
188ebfedea0SLionel Sambuc         c++;
189ebfedea0SLionel Sambuc         EVP_DigestInit_ex(&s1, EVP_sha1(), NULL);
190ebfedea0SLionel Sambuc         EVP_DigestUpdate(&s1, buf, k);
191ebfedea0SLionel Sambuc         EVP_DigestUpdate(&s1, s->session->master_key,
192ebfedea0SLionel Sambuc                          s->session->master_key_length);
193ebfedea0SLionel Sambuc         EVP_DigestUpdate(&s1, s->s3->server_random, SSL3_RANDOM_SIZE);
194ebfedea0SLionel Sambuc         EVP_DigestUpdate(&s1, s->s3->client_random, SSL3_RANDOM_SIZE);
195ebfedea0SLionel Sambuc         EVP_DigestFinal_ex(&s1, smd, NULL);
196ebfedea0SLionel Sambuc 
197ebfedea0SLionel Sambuc         EVP_DigestInit_ex(&m5, EVP_md5(), NULL);
198ebfedea0SLionel Sambuc         EVP_DigestUpdate(&m5, s->session->master_key,
199ebfedea0SLionel Sambuc                          s->session->master_key_length);
200ebfedea0SLionel Sambuc         EVP_DigestUpdate(&m5, smd, SHA_DIGEST_LENGTH);
201*0a6a1f1dSLionel Sambuc         if ((int)(i + MD5_DIGEST_LENGTH) > num) {
202ebfedea0SLionel Sambuc             EVP_DigestFinal_ex(&m5, smd, NULL);
203ebfedea0SLionel Sambuc             memcpy(km, smd, (num - i));
204*0a6a1f1dSLionel Sambuc         } else
205ebfedea0SLionel Sambuc             EVP_DigestFinal_ex(&m5, km, NULL);
206ebfedea0SLionel Sambuc 
207ebfedea0SLionel Sambuc         km += MD5_DIGEST_LENGTH;
208ebfedea0SLionel Sambuc     }
209ebfedea0SLionel Sambuc     OPENSSL_cleanse(smd, SHA_DIGEST_LENGTH);
210ebfedea0SLionel Sambuc     EVP_MD_CTX_cleanup(&m5);
211ebfedea0SLionel Sambuc     EVP_MD_CTX_cleanup(&s1);
212ebfedea0SLionel Sambuc     return 1;
213ebfedea0SLionel Sambuc }
214ebfedea0SLionel Sambuc 
ssl3_change_cipher_state(SSL * s,int which)215ebfedea0SLionel Sambuc int ssl3_change_cipher_state(SSL *s, int which)
216ebfedea0SLionel Sambuc {
217ebfedea0SLionel Sambuc     unsigned char *p, *mac_secret;
218ebfedea0SLionel Sambuc     unsigned char exp_key[EVP_MAX_KEY_LENGTH];
219ebfedea0SLionel Sambuc     unsigned char exp_iv[EVP_MAX_IV_LENGTH];
220ebfedea0SLionel Sambuc     unsigned char *ms, *key, *iv, *er1, *er2;
221ebfedea0SLionel Sambuc     EVP_CIPHER_CTX *dd;
222ebfedea0SLionel Sambuc     const EVP_CIPHER *c;
223ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_COMP
224ebfedea0SLionel Sambuc     COMP_METHOD *comp;
225ebfedea0SLionel Sambuc #endif
226ebfedea0SLionel Sambuc     const EVP_MD *m;
227ebfedea0SLionel Sambuc     EVP_MD_CTX md;
228ebfedea0SLionel Sambuc     int is_exp, n, i, j, k, cl;
229ebfedea0SLionel Sambuc     int reuse_dd = 0;
230ebfedea0SLionel Sambuc 
231ebfedea0SLionel Sambuc     is_exp = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
232ebfedea0SLionel Sambuc     c = s->s3->tmp.new_sym_enc;
233ebfedea0SLionel Sambuc     m = s->s3->tmp.new_hash;
234ebfedea0SLionel Sambuc     /* m == NULL will lead to a crash later */
235ebfedea0SLionel Sambuc     OPENSSL_assert(m);
236ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_COMP
237ebfedea0SLionel Sambuc     if (s->s3->tmp.new_compression == NULL)
238ebfedea0SLionel Sambuc         comp = NULL;
239ebfedea0SLionel Sambuc     else
240ebfedea0SLionel Sambuc         comp = s->s3->tmp.new_compression->method;
241ebfedea0SLionel Sambuc #endif
242ebfedea0SLionel Sambuc 
243*0a6a1f1dSLionel Sambuc     if (which & SSL3_CC_READ) {
244ebfedea0SLionel Sambuc         if (s->enc_read_ctx != NULL)
245ebfedea0SLionel Sambuc             reuse_dd = 1;
246*0a6a1f1dSLionel Sambuc         else if ((s->enc_read_ctx =
247*0a6a1f1dSLionel Sambuc                   OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
248ebfedea0SLionel Sambuc             goto err;
249ebfedea0SLionel Sambuc         else
250*0a6a1f1dSLionel Sambuc             /*
251*0a6a1f1dSLionel Sambuc              * make sure it's intialized in case we exit later with an error
252*0a6a1f1dSLionel Sambuc              */
253ebfedea0SLionel Sambuc             EVP_CIPHER_CTX_init(s->enc_read_ctx);
254ebfedea0SLionel Sambuc         dd = s->enc_read_ctx;
255ebfedea0SLionel Sambuc 
256ebfedea0SLionel Sambuc         ssl_replace_hash(&s->read_hash, m);
257ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_COMP
258ebfedea0SLionel Sambuc         /* COMPRESS */
259*0a6a1f1dSLionel Sambuc         if (s->expand != NULL) {
260ebfedea0SLionel Sambuc             COMP_CTX_free(s->expand);
261ebfedea0SLionel Sambuc             s->expand = NULL;
262ebfedea0SLionel Sambuc         }
263*0a6a1f1dSLionel Sambuc         if (comp != NULL) {
264ebfedea0SLionel Sambuc             s->expand = COMP_CTX_new(comp);
265*0a6a1f1dSLionel Sambuc             if (s->expand == NULL) {
266*0a6a1f1dSLionel Sambuc                 SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,
267*0a6a1f1dSLionel Sambuc                        SSL_R_COMPRESSION_LIBRARY_ERROR);
268ebfedea0SLionel Sambuc                 goto err2;
269ebfedea0SLionel Sambuc             }
270ebfedea0SLionel Sambuc             if (s->s3->rrec.comp == NULL)
271ebfedea0SLionel Sambuc                 s->s3->rrec.comp = (unsigned char *)
272ebfedea0SLionel Sambuc                     OPENSSL_malloc(SSL3_RT_MAX_PLAIN_LENGTH);
273ebfedea0SLionel Sambuc             if (s->s3->rrec.comp == NULL)
274ebfedea0SLionel Sambuc                 goto err;
275ebfedea0SLionel Sambuc         }
276ebfedea0SLionel Sambuc #endif
277ebfedea0SLionel Sambuc         memset(&(s->s3->read_sequence[0]), 0, 8);
278ebfedea0SLionel Sambuc         mac_secret = &(s->s3->read_mac_secret[0]);
279*0a6a1f1dSLionel Sambuc     } else {
280ebfedea0SLionel Sambuc         if (s->enc_write_ctx != NULL)
281ebfedea0SLionel Sambuc             reuse_dd = 1;
282*0a6a1f1dSLionel Sambuc         else if ((s->enc_write_ctx =
283*0a6a1f1dSLionel Sambuc                   OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
284ebfedea0SLionel Sambuc             goto err;
285ebfedea0SLionel Sambuc         else
286*0a6a1f1dSLionel Sambuc             /*
287*0a6a1f1dSLionel Sambuc              * make sure it's intialized in case we exit later with an error
288*0a6a1f1dSLionel Sambuc              */
289ebfedea0SLionel Sambuc             EVP_CIPHER_CTX_init(s->enc_write_ctx);
290ebfedea0SLionel Sambuc         dd = s->enc_write_ctx;
291ebfedea0SLionel Sambuc         ssl_replace_hash(&s->write_hash, m);
292ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_COMP
293ebfedea0SLionel Sambuc         /* COMPRESS */
294*0a6a1f1dSLionel Sambuc         if (s->compress != NULL) {
295ebfedea0SLionel Sambuc             COMP_CTX_free(s->compress);
296ebfedea0SLionel Sambuc             s->compress = NULL;
297ebfedea0SLionel Sambuc         }
298*0a6a1f1dSLionel Sambuc         if (comp != NULL) {
299ebfedea0SLionel Sambuc             s->compress = COMP_CTX_new(comp);
300*0a6a1f1dSLionel Sambuc             if (s->compress == NULL) {
301*0a6a1f1dSLionel Sambuc                 SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,
302*0a6a1f1dSLionel Sambuc                        SSL_R_COMPRESSION_LIBRARY_ERROR);
303ebfedea0SLionel Sambuc                 goto err2;
304ebfedea0SLionel Sambuc             }
305ebfedea0SLionel Sambuc         }
306ebfedea0SLionel Sambuc #endif
307ebfedea0SLionel Sambuc         memset(&(s->s3->write_sequence[0]), 0, 8);
308ebfedea0SLionel Sambuc         mac_secret = &(s->s3->write_mac_secret[0]);
309ebfedea0SLionel Sambuc     }
310ebfedea0SLionel Sambuc 
311ebfedea0SLionel Sambuc     if (reuse_dd)
312ebfedea0SLionel Sambuc         EVP_CIPHER_CTX_cleanup(dd);
313ebfedea0SLionel Sambuc 
314ebfedea0SLionel Sambuc     p = s->s3->tmp.key_block;
315ebfedea0SLionel Sambuc     i = EVP_MD_size(m);
316ebfedea0SLionel Sambuc     if (i < 0)
317ebfedea0SLionel Sambuc         goto err2;
318ebfedea0SLionel Sambuc     cl = EVP_CIPHER_key_length(c);
319ebfedea0SLionel Sambuc     j = is_exp ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ?
320ebfedea0SLionel Sambuc                   cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl;
321ebfedea0SLionel Sambuc     /* Was j=(is_exp)?5:EVP_CIPHER_key_length(c); */
322ebfedea0SLionel Sambuc     k = EVP_CIPHER_iv_length(c);
323ebfedea0SLionel Sambuc     if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
324*0a6a1f1dSLionel Sambuc         (which == SSL3_CHANGE_CIPHER_SERVER_READ)) {
325*0a6a1f1dSLionel Sambuc         ms = &(p[0]);
326*0a6a1f1dSLionel Sambuc         n = i + i;
327*0a6a1f1dSLionel Sambuc         key = &(p[n]);
328*0a6a1f1dSLionel Sambuc         n += j + j;
329*0a6a1f1dSLionel Sambuc         iv = &(p[n]);
330*0a6a1f1dSLionel Sambuc         n += k + k;
331ebfedea0SLionel Sambuc         er1 = &(s->s3->client_random[0]);
332ebfedea0SLionel Sambuc         er2 = &(s->s3->server_random[0]);
333*0a6a1f1dSLionel Sambuc     } else {
334ebfedea0SLionel Sambuc         n = i;
335*0a6a1f1dSLionel Sambuc         ms = &(p[n]);
336*0a6a1f1dSLionel Sambuc         n += i + j;
337*0a6a1f1dSLionel Sambuc         key = &(p[n]);
338*0a6a1f1dSLionel Sambuc         n += j + k;
339*0a6a1f1dSLionel Sambuc         iv = &(p[n]);
340*0a6a1f1dSLionel Sambuc         n += k;
341ebfedea0SLionel Sambuc         er1 = &(s->s3->server_random[0]);
342ebfedea0SLionel Sambuc         er2 = &(s->s3->client_random[0]);
343ebfedea0SLionel Sambuc     }
344ebfedea0SLionel Sambuc 
345*0a6a1f1dSLionel Sambuc     if (n > s->s3->tmp.key_block_length) {
346ebfedea0SLionel Sambuc         SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
347ebfedea0SLionel Sambuc         goto err2;
348ebfedea0SLionel Sambuc     }
349ebfedea0SLionel Sambuc 
350ebfedea0SLionel Sambuc     EVP_MD_CTX_init(&md);
351ebfedea0SLionel Sambuc     memcpy(mac_secret, ms, i);
352*0a6a1f1dSLionel Sambuc     if (is_exp) {
353*0a6a1f1dSLionel Sambuc         /*
354*0a6a1f1dSLionel Sambuc          * In here I set both the read and write key/iv to the same value
355*0a6a1f1dSLionel Sambuc          * since only the correct one will be used :-).
356ebfedea0SLionel Sambuc          */
357ebfedea0SLionel Sambuc         EVP_DigestInit_ex(&md, EVP_md5(), NULL);
358ebfedea0SLionel Sambuc         EVP_DigestUpdate(&md, key, j);
359ebfedea0SLionel Sambuc         EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE);
360ebfedea0SLionel Sambuc         EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE);
361ebfedea0SLionel Sambuc         EVP_DigestFinal_ex(&md, &(exp_key[0]), NULL);
362ebfedea0SLionel Sambuc         key = &(exp_key[0]);
363ebfedea0SLionel Sambuc 
364*0a6a1f1dSLionel Sambuc         if (k > 0) {
365ebfedea0SLionel Sambuc             EVP_DigestInit_ex(&md, EVP_md5(), NULL);
366ebfedea0SLionel Sambuc             EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE);
367ebfedea0SLionel Sambuc             EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE);
368ebfedea0SLionel Sambuc             EVP_DigestFinal_ex(&md, &(exp_iv[0]), NULL);
369ebfedea0SLionel Sambuc             iv = &(exp_iv[0]);
370ebfedea0SLionel Sambuc         }
371ebfedea0SLionel Sambuc     }
372ebfedea0SLionel Sambuc 
373ebfedea0SLionel Sambuc     s->session->key_arg_length = 0;
374ebfedea0SLionel Sambuc 
375ebfedea0SLionel Sambuc     EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE));
376ebfedea0SLionel Sambuc 
377ebfedea0SLionel Sambuc     OPENSSL_cleanse(&(exp_key[0]), sizeof(exp_key));
378ebfedea0SLionel Sambuc     OPENSSL_cleanse(&(exp_iv[0]), sizeof(exp_iv));
379ebfedea0SLionel Sambuc     EVP_MD_CTX_cleanup(&md);
380ebfedea0SLionel Sambuc     return (1);
381ebfedea0SLionel Sambuc  err:
382ebfedea0SLionel Sambuc     SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE);
383ebfedea0SLionel Sambuc  err2:
384ebfedea0SLionel Sambuc     return (0);
385ebfedea0SLionel Sambuc }
386ebfedea0SLionel Sambuc 
ssl3_setup_key_block(SSL * s)387ebfedea0SLionel Sambuc int ssl3_setup_key_block(SSL *s)
388ebfedea0SLionel Sambuc {
389ebfedea0SLionel Sambuc     unsigned char *p;
390ebfedea0SLionel Sambuc     const EVP_CIPHER *c;
391ebfedea0SLionel Sambuc     const EVP_MD *hash;
392ebfedea0SLionel Sambuc     int num;
393ebfedea0SLionel Sambuc     int ret = 0;
394ebfedea0SLionel Sambuc     SSL_COMP *comp;
395ebfedea0SLionel Sambuc 
396ebfedea0SLionel Sambuc     if (s->s3->tmp.key_block_length != 0)
397ebfedea0SLionel Sambuc         return (1);
398ebfedea0SLionel Sambuc 
399*0a6a1f1dSLionel Sambuc     if (!ssl_cipher_get_evp(s->session, &c, &hash, NULL, NULL, &comp)) {
400ebfedea0SLionel Sambuc         SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
401ebfedea0SLionel Sambuc         return (0);
402ebfedea0SLionel Sambuc     }
403ebfedea0SLionel Sambuc 
404ebfedea0SLionel Sambuc     s->s3->tmp.new_sym_enc = c;
405ebfedea0SLionel Sambuc     s->s3->tmp.new_hash = hash;
406ebfedea0SLionel Sambuc #ifdef OPENSSL_NO_COMP
407ebfedea0SLionel Sambuc     s->s3->tmp.new_compression = NULL;
408ebfedea0SLionel Sambuc #else
409ebfedea0SLionel Sambuc     s->s3->tmp.new_compression = comp;
410ebfedea0SLionel Sambuc #endif
411ebfedea0SLionel Sambuc 
412ebfedea0SLionel Sambuc     num = EVP_MD_size(hash);
413ebfedea0SLionel Sambuc     if (num < 0)
414ebfedea0SLionel Sambuc         return 0;
415ebfedea0SLionel Sambuc 
416ebfedea0SLionel Sambuc     num = EVP_CIPHER_key_length(c) + num + EVP_CIPHER_iv_length(c);
417ebfedea0SLionel Sambuc     num *= 2;
418ebfedea0SLionel Sambuc 
419ebfedea0SLionel Sambuc     ssl3_cleanup_key_block(s);
420ebfedea0SLionel Sambuc 
421ebfedea0SLionel Sambuc     if ((p = OPENSSL_malloc(num)) == NULL)
422ebfedea0SLionel Sambuc         goto err;
423ebfedea0SLionel Sambuc 
424ebfedea0SLionel Sambuc     s->s3->tmp.key_block_length = num;
425ebfedea0SLionel Sambuc     s->s3->tmp.key_block = p;
426ebfedea0SLionel Sambuc 
427ebfedea0SLionel Sambuc     ret = ssl3_generate_key_block(s, p, num);
428ebfedea0SLionel Sambuc 
429*0a6a1f1dSLionel Sambuc     if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) {
430*0a6a1f1dSLionel Sambuc         /*
431*0a6a1f1dSLionel Sambuc          * enable vulnerability countermeasure for CBC ciphers with known-IV
432*0a6a1f1dSLionel Sambuc          * problem (http://www.openssl.org/~bodo/tls-cbc.txt)
433ebfedea0SLionel Sambuc          */
434ebfedea0SLionel Sambuc         s->s3->need_empty_fragments = 1;
435ebfedea0SLionel Sambuc 
436*0a6a1f1dSLionel Sambuc         if (s->session->cipher != NULL) {
437ebfedea0SLionel Sambuc             if (s->session->cipher->algorithm_enc == SSL_eNULL)
438ebfedea0SLionel Sambuc                 s->s3->need_empty_fragments = 0;
439ebfedea0SLionel Sambuc 
440ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_RC4
441ebfedea0SLionel Sambuc             if (s->session->cipher->algorithm_enc == SSL_RC4)
442ebfedea0SLionel Sambuc                 s->s3->need_empty_fragments = 0;
443ebfedea0SLionel Sambuc #endif
444ebfedea0SLionel Sambuc         }
445ebfedea0SLionel Sambuc     }
446ebfedea0SLionel Sambuc 
447ebfedea0SLionel Sambuc     return ret;
448ebfedea0SLionel Sambuc 
449ebfedea0SLionel Sambuc  err:
450ebfedea0SLionel Sambuc     SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE);
451ebfedea0SLionel Sambuc     return (0);
452ebfedea0SLionel Sambuc }
453ebfedea0SLionel Sambuc 
ssl3_cleanup_key_block(SSL * s)454ebfedea0SLionel Sambuc void ssl3_cleanup_key_block(SSL *s)
455ebfedea0SLionel Sambuc {
456*0a6a1f1dSLionel Sambuc     if (s->s3->tmp.key_block != NULL) {
457*0a6a1f1dSLionel Sambuc         OPENSSL_cleanse(s->s3->tmp.key_block, s->s3->tmp.key_block_length);
458ebfedea0SLionel Sambuc         OPENSSL_free(s->s3->tmp.key_block);
459ebfedea0SLionel Sambuc         s->s3->tmp.key_block = NULL;
460ebfedea0SLionel Sambuc     }
461ebfedea0SLionel Sambuc     s->s3->tmp.key_block_length = 0;
462ebfedea0SLionel Sambuc }
463ebfedea0SLionel Sambuc 
464*0a6a1f1dSLionel Sambuc /*-
465*0a6a1f1dSLionel Sambuc  * ssl3_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively.
466ebfedea0SLionel Sambuc  *
467ebfedea0SLionel Sambuc  * Returns:
468ebfedea0SLionel Sambuc  *   0: (in non-constant time) if the record is publically invalid (i.e. too
469ebfedea0SLionel Sambuc  *       short etc).
470ebfedea0SLionel Sambuc  *   1: if the record's padding is valid / the encryption was successful.
471ebfedea0SLionel Sambuc  *   -1: if the record's padding is invalid or, if sending, an internal error
472ebfedea0SLionel Sambuc  *       occured.
473ebfedea0SLionel Sambuc  */
ssl3_enc(SSL * s,int send)474ebfedea0SLionel Sambuc int ssl3_enc(SSL *s, int send)
475ebfedea0SLionel Sambuc {
476ebfedea0SLionel Sambuc     SSL3_RECORD *rec;
477ebfedea0SLionel Sambuc     EVP_CIPHER_CTX *ds;
478ebfedea0SLionel Sambuc     unsigned long l;
479ebfedea0SLionel Sambuc     int bs, i, mac_size = 0;
480ebfedea0SLionel Sambuc     const EVP_CIPHER *enc;
481ebfedea0SLionel Sambuc 
482*0a6a1f1dSLionel Sambuc     if (send) {
483ebfedea0SLionel Sambuc         ds = s->enc_write_ctx;
484ebfedea0SLionel Sambuc         rec = &(s->s3->wrec);
485ebfedea0SLionel Sambuc         if (s->enc_write_ctx == NULL)
486ebfedea0SLionel Sambuc             enc = NULL;
487ebfedea0SLionel Sambuc         else
488ebfedea0SLionel Sambuc             enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
489*0a6a1f1dSLionel Sambuc     } else {
490ebfedea0SLionel Sambuc         ds = s->enc_read_ctx;
491ebfedea0SLionel Sambuc         rec = &(s->s3->rrec);
492ebfedea0SLionel Sambuc         if (s->enc_read_ctx == NULL)
493ebfedea0SLionel Sambuc             enc = NULL;
494ebfedea0SLionel Sambuc         else
495ebfedea0SLionel Sambuc             enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
496ebfedea0SLionel Sambuc     }
497ebfedea0SLionel Sambuc 
498*0a6a1f1dSLionel Sambuc     if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) {
499ebfedea0SLionel Sambuc         memmove(rec->data, rec->input, rec->length);
500ebfedea0SLionel Sambuc         rec->input = rec->data;
501*0a6a1f1dSLionel Sambuc     } else {
502ebfedea0SLionel Sambuc         l = rec->length;
503ebfedea0SLionel Sambuc         bs = EVP_CIPHER_block_size(ds->cipher);
504ebfedea0SLionel Sambuc 
505ebfedea0SLionel Sambuc         /* COMPRESS */
506ebfedea0SLionel Sambuc 
507*0a6a1f1dSLionel Sambuc         if ((bs != 1) && send) {
508ebfedea0SLionel Sambuc             i = bs - ((int)l % bs);
509ebfedea0SLionel Sambuc 
510ebfedea0SLionel Sambuc             /* we need to add 'i-1' padding bytes */
511ebfedea0SLionel Sambuc             l += i;
512*0a6a1f1dSLionel Sambuc             /*
513*0a6a1f1dSLionel Sambuc              * the last of these zero bytes will be overwritten with the
514*0a6a1f1dSLionel Sambuc              * padding length.
515*0a6a1f1dSLionel Sambuc              */
516ebfedea0SLionel Sambuc             memset(&rec->input[rec->length], 0, i);
517ebfedea0SLionel Sambuc             rec->length += i;
518ebfedea0SLionel Sambuc             rec->input[l - 1] = (i - 1);
519ebfedea0SLionel Sambuc         }
520ebfedea0SLionel Sambuc 
521*0a6a1f1dSLionel Sambuc         if (!send) {
522ebfedea0SLionel Sambuc             if (l == 0 || l % bs != 0)
523ebfedea0SLionel Sambuc                 return 0;
524ebfedea0SLionel Sambuc             /* otherwise, rec->length >= bs */
525ebfedea0SLionel Sambuc         }
526ebfedea0SLionel Sambuc 
527*0a6a1f1dSLionel Sambuc         if (EVP_Cipher(ds, rec->data, rec->input, l) < 1)
528*0a6a1f1dSLionel Sambuc             return -1;
529ebfedea0SLionel Sambuc 
530ebfedea0SLionel Sambuc         if (EVP_MD_CTX_md(s->read_hash) != NULL)
531ebfedea0SLionel Sambuc             mac_size = EVP_MD_CTX_size(s->read_hash);
532ebfedea0SLionel Sambuc         if ((bs != 1) && !send)
533ebfedea0SLionel Sambuc             return ssl3_cbc_remove_padding(s, rec, bs, mac_size);
534ebfedea0SLionel Sambuc     }
535ebfedea0SLionel Sambuc     return (1);
536ebfedea0SLionel Sambuc }
537ebfedea0SLionel Sambuc 
ssl3_init_finished_mac(SSL * s)538ebfedea0SLionel Sambuc void ssl3_init_finished_mac(SSL *s)
539ebfedea0SLionel Sambuc {
540*0a6a1f1dSLionel Sambuc     if (s->s3->handshake_buffer)
541*0a6a1f1dSLionel Sambuc         BIO_free(s->s3->handshake_buffer);
542*0a6a1f1dSLionel Sambuc     if (s->s3->handshake_dgst)
543*0a6a1f1dSLionel Sambuc         ssl3_free_digest_list(s);
544ebfedea0SLionel Sambuc     s->s3->handshake_buffer = BIO_new(BIO_s_mem());
545ebfedea0SLionel Sambuc     (void)BIO_set_close(s->s3->handshake_buffer, BIO_CLOSE);
546ebfedea0SLionel Sambuc }
547ebfedea0SLionel Sambuc 
ssl3_free_digest_list(SSL * s)548ebfedea0SLionel Sambuc void ssl3_free_digest_list(SSL *s)
549ebfedea0SLionel Sambuc {
550ebfedea0SLionel Sambuc     int i;
551*0a6a1f1dSLionel Sambuc     if (!s->s3->handshake_dgst)
552*0a6a1f1dSLionel Sambuc         return;
553*0a6a1f1dSLionel Sambuc     for (i = 0; i < SSL_MAX_DIGEST; i++) {
554ebfedea0SLionel Sambuc         if (s->s3->handshake_dgst[i])
555ebfedea0SLionel Sambuc             EVP_MD_CTX_destroy(s->s3->handshake_dgst[i]);
556ebfedea0SLionel Sambuc     }
557ebfedea0SLionel Sambuc     OPENSSL_free(s->s3->handshake_dgst);
558ebfedea0SLionel Sambuc     s->s3->handshake_dgst = NULL;
559ebfedea0SLionel Sambuc }
560ebfedea0SLionel Sambuc 
ssl3_finish_mac(SSL * s,const unsigned char * buf,int len)561ebfedea0SLionel Sambuc void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len)
562ebfedea0SLionel Sambuc {
563*0a6a1f1dSLionel Sambuc     if (s->s3->handshake_buffer
564*0a6a1f1dSLionel Sambuc         && !(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) {
565ebfedea0SLionel Sambuc         BIO_write(s->s3->handshake_buffer, (void *)buf, len);
566*0a6a1f1dSLionel Sambuc     } else if (s->s3->handshake_dgst != NULL) {
567ebfedea0SLionel Sambuc         int i;
568*0a6a1f1dSLionel Sambuc         for (i = 0; i < SSL_MAX_DIGEST; i++) {
569ebfedea0SLionel Sambuc             if (s->s3->handshake_dgst[i] != NULL)
570ebfedea0SLionel Sambuc                 EVP_DigestUpdate(s->s3->handshake_dgst[i], buf, len);
571ebfedea0SLionel Sambuc         }
572ebfedea0SLionel Sambuc     }
573ebfedea0SLionel Sambuc }
574ebfedea0SLionel Sambuc 
ssl3_digest_cached_records(SSL * s)575ebfedea0SLionel Sambuc int ssl3_digest_cached_records(SSL *s)
576ebfedea0SLionel Sambuc {
577ebfedea0SLionel Sambuc     int i;
578ebfedea0SLionel Sambuc     long mask;
579ebfedea0SLionel Sambuc     const EVP_MD *md;
580ebfedea0SLionel Sambuc     long hdatalen;
581ebfedea0SLionel Sambuc     void *hdata;
582ebfedea0SLionel Sambuc 
583ebfedea0SLionel Sambuc     /* Allocate handshake_dgst array */
584ebfedea0SLionel Sambuc     ssl3_free_digest_list(s);
585*0a6a1f1dSLionel Sambuc     s->s3->handshake_dgst =
586*0a6a1f1dSLionel Sambuc         OPENSSL_malloc(SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *));
587ebfedea0SLionel Sambuc     memset(s->s3->handshake_dgst, 0, SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *));
588ebfedea0SLionel Sambuc     hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
589*0a6a1f1dSLionel Sambuc     if (hdatalen <= 0) {
590ebfedea0SLionel Sambuc         SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, SSL_R_BAD_HANDSHAKE_LENGTH);
591ebfedea0SLionel Sambuc         return 0;
592ebfedea0SLionel Sambuc     }
593ebfedea0SLionel Sambuc 
594ebfedea0SLionel Sambuc     /* Loop through bitso of algorithm2 field and create MD_CTX-es */
595*0a6a1f1dSLionel Sambuc     for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++) {
596*0a6a1f1dSLionel Sambuc         if ((mask & ssl_get_algorithm2(s)) && md) {
597ebfedea0SLionel Sambuc             s->s3->handshake_dgst[i] = EVP_MD_CTX_create();
598ebfedea0SLionel Sambuc #ifdef OPENSSL_FIPS
599*0a6a1f1dSLionel Sambuc             if (EVP_MD_nid(md) == NID_md5) {
600ebfedea0SLionel Sambuc                 EVP_MD_CTX_set_flags(s->s3->handshake_dgst[i],
601ebfedea0SLionel Sambuc                                      EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
602ebfedea0SLionel Sambuc             }
603ebfedea0SLionel Sambuc #endif
604ebfedea0SLionel Sambuc             EVP_DigestInit_ex(s->s3->handshake_dgst[i], md, NULL);
605ebfedea0SLionel Sambuc             EVP_DigestUpdate(s->s3->handshake_dgst[i], hdata, hdatalen);
606*0a6a1f1dSLionel Sambuc         } else {
607ebfedea0SLionel Sambuc             s->s3->handshake_dgst[i] = NULL;
608ebfedea0SLionel Sambuc         }
609ebfedea0SLionel Sambuc     }
610*0a6a1f1dSLionel Sambuc     if (!(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) {
611ebfedea0SLionel Sambuc         /* Free handshake_buffer BIO */
612ebfedea0SLionel Sambuc         BIO_free(s->s3->handshake_buffer);
613ebfedea0SLionel Sambuc         s->s3->handshake_buffer = NULL;
614ebfedea0SLionel Sambuc     }
615ebfedea0SLionel Sambuc 
616ebfedea0SLionel Sambuc     return 1;
617ebfedea0SLionel Sambuc }
618ebfedea0SLionel Sambuc 
ssl3_cert_verify_mac(SSL * s,int md_nid,unsigned char * p)619ebfedea0SLionel Sambuc int ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p)
620ebfedea0SLionel Sambuc {
621ebfedea0SLionel Sambuc     return (ssl3_handshake_mac(s, md_nid, NULL, 0, p));
622ebfedea0SLionel Sambuc }
623*0a6a1f1dSLionel Sambuc 
ssl3_final_finish_mac(SSL * s,const char * sender,int len,unsigned char * p)624ebfedea0SLionel Sambuc int ssl3_final_finish_mac(SSL *s,
625ebfedea0SLionel Sambuc                           const char *sender, int len, unsigned char *p)
626ebfedea0SLionel Sambuc {
627*0a6a1f1dSLionel Sambuc     int ret, sha1len;
628ebfedea0SLionel Sambuc     ret = ssl3_handshake_mac(s, NID_md5, sender, len, p);
629*0a6a1f1dSLionel Sambuc     if (ret == 0)
630*0a6a1f1dSLionel Sambuc         return 0;
631*0a6a1f1dSLionel Sambuc 
632ebfedea0SLionel Sambuc     p += ret;
633*0a6a1f1dSLionel Sambuc 
634*0a6a1f1dSLionel Sambuc     sha1len = ssl3_handshake_mac(s, NID_sha1, sender, len, p);
635*0a6a1f1dSLionel Sambuc     if (sha1len == 0)
636*0a6a1f1dSLionel Sambuc         return 0;
637*0a6a1f1dSLionel Sambuc 
638*0a6a1f1dSLionel Sambuc     ret += sha1len;
639ebfedea0SLionel Sambuc     return (ret);
640ebfedea0SLionel Sambuc }
641*0a6a1f1dSLionel Sambuc 
ssl3_handshake_mac(SSL * s,int md_nid,const char * sender,int len,unsigned char * p)642ebfedea0SLionel Sambuc static int ssl3_handshake_mac(SSL *s, int md_nid,
643ebfedea0SLionel Sambuc                               const char *sender, int len, unsigned char *p)
644ebfedea0SLionel Sambuc {
645ebfedea0SLionel Sambuc     unsigned int ret;
646ebfedea0SLionel Sambuc     int npad, n;
647ebfedea0SLionel Sambuc     unsigned int i;
648ebfedea0SLionel Sambuc     unsigned char md_buf[EVP_MAX_MD_SIZE];
649ebfedea0SLionel Sambuc     EVP_MD_CTX ctx, *d = NULL;
650ebfedea0SLionel Sambuc 
651ebfedea0SLionel Sambuc     if (s->s3->handshake_buffer)
652ebfedea0SLionel Sambuc         if (!ssl3_digest_cached_records(s))
653ebfedea0SLionel Sambuc             return 0;
654ebfedea0SLionel Sambuc 
655*0a6a1f1dSLionel Sambuc     /*
656*0a6a1f1dSLionel Sambuc      * Search for digest of specified type in the handshake_dgst array
657*0a6a1f1dSLionel Sambuc      */
658*0a6a1f1dSLionel Sambuc     for (i = 0; i < SSL_MAX_DIGEST; i++) {
659*0a6a1f1dSLionel Sambuc         if (s->s3->handshake_dgst[i]
660*0a6a1f1dSLionel Sambuc             && EVP_MD_CTX_type(s->s3->handshake_dgst[i]) == md_nid) {
661ebfedea0SLionel Sambuc             d = s->s3->handshake_dgst[i];
662ebfedea0SLionel Sambuc             break;
663ebfedea0SLionel Sambuc         }
664ebfedea0SLionel Sambuc     }
665ebfedea0SLionel Sambuc     if (!d) {
666ebfedea0SLionel Sambuc         SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, SSL_R_NO_REQUIRED_DIGEST);
667ebfedea0SLionel Sambuc         return 0;
668ebfedea0SLionel Sambuc     }
669ebfedea0SLionel Sambuc     EVP_MD_CTX_init(&ctx);
670ebfedea0SLionel Sambuc     EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
671ebfedea0SLionel Sambuc     EVP_MD_CTX_copy_ex(&ctx, d);
672ebfedea0SLionel Sambuc     n = EVP_MD_CTX_size(&ctx);
673ebfedea0SLionel Sambuc     if (n < 0)
674ebfedea0SLionel Sambuc         return 0;
675ebfedea0SLionel Sambuc 
676ebfedea0SLionel Sambuc     npad = (48 / n) * n;
677ebfedea0SLionel Sambuc     if (sender != NULL)
678ebfedea0SLionel Sambuc         EVP_DigestUpdate(&ctx, sender, len);
679ebfedea0SLionel Sambuc     EVP_DigestUpdate(&ctx, s->session->master_key,
680ebfedea0SLionel Sambuc                      s->session->master_key_length);
681ebfedea0SLionel Sambuc     EVP_DigestUpdate(&ctx, ssl3_pad_1, npad);
682ebfedea0SLionel Sambuc     EVP_DigestFinal_ex(&ctx, md_buf, &i);
683ebfedea0SLionel Sambuc 
684ebfedea0SLionel Sambuc     EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL);
685ebfedea0SLionel Sambuc     EVP_DigestUpdate(&ctx, s->session->master_key,
686ebfedea0SLionel Sambuc                      s->session->master_key_length);
687ebfedea0SLionel Sambuc     EVP_DigestUpdate(&ctx, ssl3_pad_2, npad);
688ebfedea0SLionel Sambuc     EVP_DigestUpdate(&ctx, md_buf, i);
689ebfedea0SLionel Sambuc     EVP_DigestFinal_ex(&ctx, p, &ret);
690ebfedea0SLionel Sambuc 
691ebfedea0SLionel Sambuc     EVP_MD_CTX_cleanup(&ctx);
692ebfedea0SLionel Sambuc 
693ebfedea0SLionel Sambuc     return ((int)ret);
694ebfedea0SLionel Sambuc }
695ebfedea0SLionel Sambuc 
n_ssl3_mac(SSL * ssl,unsigned char * md,int send)696ebfedea0SLionel Sambuc int n_ssl3_mac(SSL *ssl, unsigned char *md, int send)
697ebfedea0SLionel Sambuc {
698ebfedea0SLionel Sambuc     SSL3_RECORD *rec;
699ebfedea0SLionel Sambuc     unsigned char *mac_sec, *seq;
700ebfedea0SLionel Sambuc     EVP_MD_CTX md_ctx;
701ebfedea0SLionel Sambuc     const EVP_MD_CTX *hash;
702ebfedea0SLionel Sambuc     unsigned char *p, rec_char;
703ebfedea0SLionel Sambuc     size_t md_size, orig_len;
704ebfedea0SLionel Sambuc     int npad;
705ebfedea0SLionel Sambuc     int t;
706ebfedea0SLionel Sambuc 
707*0a6a1f1dSLionel Sambuc     if (send) {
708ebfedea0SLionel Sambuc         rec = &(ssl->s3->wrec);
709ebfedea0SLionel Sambuc         mac_sec = &(ssl->s3->write_mac_secret[0]);
710ebfedea0SLionel Sambuc         seq = &(ssl->s3->write_sequence[0]);
711ebfedea0SLionel Sambuc         hash = ssl->write_hash;
712*0a6a1f1dSLionel Sambuc     } else {
713ebfedea0SLionel Sambuc         rec = &(ssl->s3->rrec);
714ebfedea0SLionel Sambuc         mac_sec = &(ssl->s3->read_mac_secret[0]);
715ebfedea0SLionel Sambuc         seq = &(ssl->s3->read_sequence[0]);
716ebfedea0SLionel Sambuc         hash = ssl->read_hash;
717ebfedea0SLionel Sambuc     }
718ebfedea0SLionel Sambuc 
719ebfedea0SLionel Sambuc     t = EVP_MD_CTX_size(hash);
720ebfedea0SLionel Sambuc     if (t < 0)
721ebfedea0SLionel Sambuc         return -1;
722ebfedea0SLionel Sambuc     md_size = t;
723ebfedea0SLionel Sambuc     npad = (48 / md_size) * md_size;
724ebfedea0SLionel Sambuc 
725*0a6a1f1dSLionel Sambuc     /*
726*0a6a1f1dSLionel Sambuc      * kludge: ssl3_cbc_remove_padding passes padding length in rec->type
727*0a6a1f1dSLionel Sambuc      */
728ebfedea0SLionel Sambuc     orig_len = rec->length + md_size + ((unsigned int)rec->type >> 8);
729ebfedea0SLionel Sambuc     rec->type &= 0xff;
730ebfedea0SLionel Sambuc 
731ebfedea0SLionel Sambuc     if (!send &&
732ebfedea0SLionel Sambuc         EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
733*0a6a1f1dSLionel Sambuc         ssl3_cbc_record_digest_supported(hash)) {
734*0a6a1f1dSLionel Sambuc         /*
735*0a6a1f1dSLionel Sambuc          * This is a CBC-encrypted record. We must avoid leaking any
736*0a6a1f1dSLionel Sambuc          * timing-side channel information about how many blocks of data we
737*0a6a1f1dSLionel Sambuc          * are hashing because that gives an attacker a timing-oracle.
738*0a6a1f1dSLionel Sambuc          */
739ebfedea0SLionel Sambuc 
740*0a6a1f1dSLionel Sambuc         /*-
741*0a6a1f1dSLionel Sambuc          * npad is, at most, 48 bytes and that's with MD5:
742ebfedea0SLionel Sambuc          *   16 + 48 + 8 (sequence bytes) + 1 + 2 = 75.
743ebfedea0SLionel Sambuc          *
744ebfedea0SLionel Sambuc          * With SHA-1 (the largest hash speced for SSLv3) the hash size
745ebfedea0SLionel Sambuc          * goes up 4, but npad goes down by 8, resulting in a smaller
746*0a6a1f1dSLionel Sambuc          * total size.
747*0a6a1f1dSLionel Sambuc          */
748ebfedea0SLionel Sambuc         unsigned char header[75];
749ebfedea0SLionel Sambuc         unsigned j = 0;
750ebfedea0SLionel Sambuc         memcpy(header + j, mac_sec, md_size);
751ebfedea0SLionel Sambuc         j += md_size;
752ebfedea0SLionel Sambuc         memcpy(header + j, ssl3_pad_1, npad);
753ebfedea0SLionel Sambuc         j += npad;
754ebfedea0SLionel Sambuc         memcpy(header + j, seq, 8);
755ebfedea0SLionel Sambuc         j += 8;
756ebfedea0SLionel Sambuc         header[j++] = rec->type;
757ebfedea0SLionel Sambuc         header[j++] = rec->length >> 8;
758ebfedea0SLionel Sambuc         header[j++] = rec->length & 0xff;
759ebfedea0SLionel Sambuc 
760*0a6a1f1dSLionel Sambuc         /* Final param == is SSLv3 */
761*0a6a1f1dSLionel Sambuc         ssl3_cbc_digest_record(hash,
762ebfedea0SLionel Sambuc                                md, &md_size,
763ebfedea0SLionel Sambuc                                header, rec->input,
764ebfedea0SLionel Sambuc                                rec->length + md_size, orig_len,
765*0a6a1f1dSLionel Sambuc                                mac_sec, md_size, 1);
766*0a6a1f1dSLionel Sambuc     } else {
767ebfedea0SLionel Sambuc         unsigned int md_size_u;
768ebfedea0SLionel Sambuc         /* Chop the digest off the end :-) */
769ebfedea0SLionel Sambuc         EVP_MD_CTX_init(&md_ctx);
770ebfedea0SLionel Sambuc 
771ebfedea0SLionel Sambuc         EVP_MD_CTX_copy_ex(&md_ctx, hash);
772ebfedea0SLionel Sambuc         EVP_DigestUpdate(&md_ctx, mac_sec, md_size);
773ebfedea0SLionel Sambuc         EVP_DigestUpdate(&md_ctx, ssl3_pad_1, npad);
774ebfedea0SLionel Sambuc         EVP_DigestUpdate(&md_ctx, seq, 8);
775ebfedea0SLionel Sambuc         rec_char = rec->type;
776ebfedea0SLionel Sambuc         EVP_DigestUpdate(&md_ctx, &rec_char, 1);
777ebfedea0SLionel Sambuc         p = md;
778ebfedea0SLionel Sambuc         s2n(rec->length, p);
779ebfedea0SLionel Sambuc         EVP_DigestUpdate(&md_ctx, md, 2);
780ebfedea0SLionel Sambuc         EVP_DigestUpdate(&md_ctx, rec->input, rec->length);
781ebfedea0SLionel Sambuc         EVP_DigestFinal_ex(&md_ctx, md, NULL);
782ebfedea0SLionel Sambuc 
783ebfedea0SLionel Sambuc         EVP_MD_CTX_copy_ex(&md_ctx, hash);
784ebfedea0SLionel Sambuc         EVP_DigestUpdate(&md_ctx, mac_sec, md_size);
785ebfedea0SLionel Sambuc         EVP_DigestUpdate(&md_ctx, ssl3_pad_2, npad);
786ebfedea0SLionel Sambuc         EVP_DigestUpdate(&md_ctx, md, md_size);
787ebfedea0SLionel Sambuc         EVP_DigestFinal_ex(&md_ctx, md, &md_size_u);
788ebfedea0SLionel Sambuc         md_size = md_size_u;
789ebfedea0SLionel Sambuc 
790ebfedea0SLionel Sambuc         EVP_MD_CTX_cleanup(&md_ctx);
791ebfedea0SLionel Sambuc     }
792ebfedea0SLionel Sambuc 
793ebfedea0SLionel Sambuc     ssl3_record_sequence_update(seq);
794ebfedea0SLionel Sambuc     return (md_size);
795ebfedea0SLionel Sambuc }
796ebfedea0SLionel Sambuc 
ssl3_record_sequence_update(unsigned char * seq)797ebfedea0SLionel Sambuc void ssl3_record_sequence_update(unsigned char *seq)
798ebfedea0SLionel Sambuc {
799ebfedea0SLionel Sambuc     int i;
800ebfedea0SLionel Sambuc 
801*0a6a1f1dSLionel Sambuc     for (i = 7; i >= 0; i--) {
802ebfedea0SLionel Sambuc         ++seq[i];
803*0a6a1f1dSLionel Sambuc         if (seq[i] != 0)
804*0a6a1f1dSLionel Sambuc             break;
805ebfedea0SLionel Sambuc     }
806ebfedea0SLionel Sambuc }
807ebfedea0SLionel Sambuc 
ssl3_generate_master_secret(SSL * s,unsigned char * out,unsigned char * p,int len)808ebfedea0SLionel Sambuc int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
809ebfedea0SLionel Sambuc                                 int len)
810ebfedea0SLionel Sambuc {
811ebfedea0SLionel Sambuc     static const unsigned char *salt[3] = {
812ebfedea0SLionel Sambuc #ifndef CHARSET_EBCDIC
813ebfedea0SLionel Sambuc         (const unsigned char *)"A",
814ebfedea0SLionel Sambuc         (const unsigned char *)"BB",
815ebfedea0SLionel Sambuc         (const unsigned char *)"CCC",
816ebfedea0SLionel Sambuc #else
817ebfedea0SLionel Sambuc         (const unsigned char *)"\x41",
818ebfedea0SLionel Sambuc         (const unsigned char *)"\x42\x42",
819ebfedea0SLionel Sambuc         (const unsigned char *)"\x43\x43\x43",
820ebfedea0SLionel Sambuc #endif
821ebfedea0SLionel Sambuc     };
822ebfedea0SLionel Sambuc     unsigned char buf[EVP_MAX_MD_SIZE];
823ebfedea0SLionel Sambuc     EVP_MD_CTX ctx;
824ebfedea0SLionel Sambuc     int i, ret = 0;
825ebfedea0SLionel Sambuc     unsigned int n;
826ebfedea0SLionel Sambuc 
827ebfedea0SLionel Sambuc     EVP_MD_CTX_init(&ctx);
828*0a6a1f1dSLionel Sambuc     for (i = 0; i < 3; i++) {
829ebfedea0SLionel Sambuc         EVP_DigestInit_ex(&ctx, s->ctx->sha1, NULL);
830ebfedea0SLionel Sambuc         EVP_DigestUpdate(&ctx, salt[i], strlen((const char *)salt[i]));
831ebfedea0SLionel Sambuc         EVP_DigestUpdate(&ctx, p, len);
832*0a6a1f1dSLionel Sambuc         EVP_DigestUpdate(&ctx, &(s->s3->client_random[0]), SSL3_RANDOM_SIZE);
833*0a6a1f1dSLionel Sambuc         EVP_DigestUpdate(&ctx, &(s->s3->server_random[0]), SSL3_RANDOM_SIZE);
834ebfedea0SLionel Sambuc         EVP_DigestFinal_ex(&ctx, buf, &n);
835ebfedea0SLionel Sambuc 
836ebfedea0SLionel Sambuc         EVP_DigestInit_ex(&ctx, s->ctx->md5, NULL);
837ebfedea0SLionel Sambuc         EVP_DigestUpdate(&ctx, p, len);
838ebfedea0SLionel Sambuc         EVP_DigestUpdate(&ctx, buf, n);
839ebfedea0SLionel Sambuc         EVP_DigestFinal_ex(&ctx, out, &n);
840ebfedea0SLionel Sambuc         out += n;
841ebfedea0SLionel Sambuc         ret += n;
842ebfedea0SLionel Sambuc     }
843ebfedea0SLionel Sambuc     EVP_MD_CTX_cleanup(&ctx);
844*0a6a1f1dSLionel Sambuc     OPENSSL_cleanse(buf, sizeof buf);
845ebfedea0SLionel Sambuc     return (ret);
846ebfedea0SLionel Sambuc }
847ebfedea0SLionel Sambuc 
ssl3_alert_code(int code)848ebfedea0SLionel Sambuc int ssl3_alert_code(int code)
849ebfedea0SLionel Sambuc {
850*0a6a1f1dSLionel Sambuc     switch (code) {
851*0a6a1f1dSLionel Sambuc     case SSL_AD_CLOSE_NOTIFY:
852*0a6a1f1dSLionel Sambuc         return (SSL3_AD_CLOSE_NOTIFY);
853*0a6a1f1dSLionel Sambuc     case SSL_AD_UNEXPECTED_MESSAGE:
854*0a6a1f1dSLionel Sambuc         return (SSL3_AD_UNEXPECTED_MESSAGE);
855*0a6a1f1dSLionel Sambuc     case SSL_AD_BAD_RECORD_MAC:
856*0a6a1f1dSLionel Sambuc         return (SSL3_AD_BAD_RECORD_MAC);
857*0a6a1f1dSLionel Sambuc     case SSL_AD_DECRYPTION_FAILED:
858*0a6a1f1dSLionel Sambuc         return (SSL3_AD_BAD_RECORD_MAC);
859*0a6a1f1dSLionel Sambuc     case SSL_AD_RECORD_OVERFLOW:
860*0a6a1f1dSLionel Sambuc         return (SSL3_AD_BAD_RECORD_MAC);
861*0a6a1f1dSLionel Sambuc     case SSL_AD_DECOMPRESSION_FAILURE:
862*0a6a1f1dSLionel Sambuc         return (SSL3_AD_DECOMPRESSION_FAILURE);
863*0a6a1f1dSLionel Sambuc     case SSL_AD_HANDSHAKE_FAILURE:
864*0a6a1f1dSLionel Sambuc         return (SSL3_AD_HANDSHAKE_FAILURE);
865*0a6a1f1dSLionel Sambuc     case SSL_AD_NO_CERTIFICATE:
866*0a6a1f1dSLionel Sambuc         return (SSL3_AD_NO_CERTIFICATE);
867*0a6a1f1dSLionel Sambuc     case SSL_AD_BAD_CERTIFICATE:
868*0a6a1f1dSLionel Sambuc         return (SSL3_AD_BAD_CERTIFICATE);
869*0a6a1f1dSLionel Sambuc     case SSL_AD_UNSUPPORTED_CERTIFICATE:
870*0a6a1f1dSLionel Sambuc         return (SSL3_AD_UNSUPPORTED_CERTIFICATE);
871*0a6a1f1dSLionel Sambuc     case SSL_AD_CERTIFICATE_REVOKED:
872*0a6a1f1dSLionel Sambuc         return (SSL3_AD_CERTIFICATE_REVOKED);
873*0a6a1f1dSLionel Sambuc     case SSL_AD_CERTIFICATE_EXPIRED:
874*0a6a1f1dSLionel Sambuc         return (SSL3_AD_CERTIFICATE_EXPIRED);
875*0a6a1f1dSLionel Sambuc     case SSL_AD_CERTIFICATE_UNKNOWN:
876*0a6a1f1dSLionel Sambuc         return (SSL3_AD_CERTIFICATE_UNKNOWN);
877*0a6a1f1dSLionel Sambuc     case SSL_AD_ILLEGAL_PARAMETER:
878*0a6a1f1dSLionel Sambuc         return (SSL3_AD_ILLEGAL_PARAMETER);
879*0a6a1f1dSLionel Sambuc     case SSL_AD_UNKNOWN_CA:
880*0a6a1f1dSLionel Sambuc         return (SSL3_AD_BAD_CERTIFICATE);
881*0a6a1f1dSLionel Sambuc     case SSL_AD_ACCESS_DENIED:
882*0a6a1f1dSLionel Sambuc         return (SSL3_AD_HANDSHAKE_FAILURE);
883*0a6a1f1dSLionel Sambuc     case SSL_AD_DECODE_ERROR:
884*0a6a1f1dSLionel Sambuc         return (SSL3_AD_HANDSHAKE_FAILURE);
885*0a6a1f1dSLionel Sambuc     case SSL_AD_DECRYPT_ERROR:
886*0a6a1f1dSLionel Sambuc         return (SSL3_AD_HANDSHAKE_FAILURE);
887*0a6a1f1dSLionel Sambuc     case SSL_AD_EXPORT_RESTRICTION:
888*0a6a1f1dSLionel Sambuc         return (SSL3_AD_HANDSHAKE_FAILURE);
889*0a6a1f1dSLionel Sambuc     case SSL_AD_PROTOCOL_VERSION:
890*0a6a1f1dSLionel Sambuc         return (SSL3_AD_HANDSHAKE_FAILURE);
891*0a6a1f1dSLionel Sambuc     case SSL_AD_INSUFFICIENT_SECURITY:
892*0a6a1f1dSLionel Sambuc         return (SSL3_AD_HANDSHAKE_FAILURE);
893*0a6a1f1dSLionel Sambuc     case SSL_AD_INTERNAL_ERROR:
894*0a6a1f1dSLionel Sambuc         return (SSL3_AD_HANDSHAKE_FAILURE);
895*0a6a1f1dSLionel Sambuc     case SSL_AD_USER_CANCELLED:
896*0a6a1f1dSLionel Sambuc         return (SSL3_AD_HANDSHAKE_FAILURE);
897*0a6a1f1dSLionel Sambuc     case SSL_AD_NO_RENEGOTIATION:
898*0a6a1f1dSLionel Sambuc         return (-1);            /* Don't send it :-) */
899*0a6a1f1dSLionel Sambuc     case SSL_AD_UNSUPPORTED_EXTENSION:
900*0a6a1f1dSLionel Sambuc         return (SSL3_AD_HANDSHAKE_FAILURE);
901*0a6a1f1dSLionel Sambuc     case SSL_AD_CERTIFICATE_UNOBTAINABLE:
902*0a6a1f1dSLionel Sambuc         return (SSL3_AD_HANDSHAKE_FAILURE);
903*0a6a1f1dSLionel Sambuc     case SSL_AD_UNRECOGNIZED_NAME:
904*0a6a1f1dSLionel Sambuc         return (SSL3_AD_HANDSHAKE_FAILURE);
905*0a6a1f1dSLionel Sambuc     case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
906*0a6a1f1dSLionel Sambuc         return (SSL3_AD_HANDSHAKE_FAILURE);
907*0a6a1f1dSLionel Sambuc     case SSL_AD_BAD_CERTIFICATE_HASH_VALUE:
908*0a6a1f1dSLionel Sambuc         return (SSL3_AD_HANDSHAKE_FAILURE);
909*0a6a1f1dSLionel Sambuc     case SSL_AD_UNKNOWN_PSK_IDENTITY:
910*0a6a1f1dSLionel Sambuc         return (TLS1_AD_UNKNOWN_PSK_IDENTITY);
911*0a6a1f1dSLionel Sambuc     case SSL_AD_INAPPROPRIATE_FALLBACK:
912*0a6a1f1dSLionel Sambuc         return (TLS1_AD_INAPPROPRIATE_FALLBACK);
913*0a6a1f1dSLionel Sambuc     default:
914*0a6a1f1dSLionel Sambuc         return (-1);
915ebfedea0SLionel Sambuc     }
916ebfedea0SLionel Sambuc }
917