1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.]
56 */
57 /* ====================================================================
58 * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved.
59 *
60 * Redistribution and use in source and binary forms, with or without
61 * modification, are permitted provided that the following conditions
62 * are met:
63 *
64 * 1. Redistributions of source code must retain the above copyright
65 * notice, this list of conditions and the following disclaimer.
66 *
67 * 2. Redistributions in binary form must reproduce the above copyright
68 * notice, this list of conditions and the following disclaimer in
69 * the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3. All advertising materials mentioning features or use of this
73 * software must display the following acknowledgment:
74 * "This product includes software developed by the OpenSSL Project
75 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
76 *
77 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
78 * endorse or promote products derived from this software without
79 * prior written permission. For written permission, please contact
80 * openssl-core@openssl.org.
81 *
82 * 5. Products derived from this software may not be called "OpenSSL"
83 * nor may "OpenSSL" appear in their names without prior written
84 * permission of the OpenSSL Project.
85 *
86 * 6. Redistributions of any form whatsoever must retain the following
87 * acknowledgment:
88 * "This product includes software developed by the OpenSSL Project
89 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
90 *
91 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
92 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
95 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
100 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
101 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
102 * OF THE POSSIBILITY OF SUCH DAMAGE.
103 * ====================================================================
104 *
105 * This product includes cryptographic software written by Eric Young
106 * (eay@cryptsoft.com). This product includes software written by Tim
107 * Hudson (tjh@cryptsoft.com).
108 *
109 */
110 /* ====================================================================
111 * Copyright 2005 Nokia. All rights reserved.
112 *
113 * The portions of the attached software ("Contribution") is developed by
114 * Nokia Corporation and is licensed pursuant to the OpenSSL open source
115 * license.
116 *
117 * The Contribution, originally written by Mika Kousa and Pasi Eronen of
118 * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
119 * support (see RFC 4279) to OpenSSL.
120 *
121 * No patent licenses or other rights except those expressly stated in
122 * the OpenSSL open source license shall be deemed granted or received
123 * expressly, by implication, estoppel, or otherwise.
124 *
125 * No assurances are provided by Nokia that the Contribution does not
126 * infringe the patent or other intellectual property rights of any third
127 * party or that the license provides you with all the necessary rights
128 * to make use of the Contribution.
129 *
130 * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
131 * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
132 * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
133 * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
134 * OTHERWISE. */
135
136 #include <openssl/ssl.h>
137
138 #include <assert.h>
139 #include <string.h>
140
141 #include <openssl/buf.h>
142 #include <openssl/digest.h>
143 #include <openssl/err.h>
144 #include <openssl/mem.h>
145 #include <openssl/md5.h>
146 #include <openssl/nid.h>
147 #include <openssl/sha.h>
148
149 #include "../crypto/internal.h"
150 #include "internal.h"
151
152
SSL_TRANSCRIPT_init(SSL_TRANSCRIPT * transcript)153 int SSL_TRANSCRIPT_init(SSL_TRANSCRIPT *transcript) {
154 SSL_TRANSCRIPT_cleanup(transcript);
155 transcript->buffer = BUF_MEM_new();
156 return transcript->buffer != NULL;
157 }
158
159 /* init_digest_with_data calls |EVP_DigestInit_ex| on |ctx| with |md| and then
160 * writes the data in |buf| to it. */
init_digest_with_data(EVP_MD_CTX * ctx,const EVP_MD * md,const BUF_MEM * buf)161 static int init_digest_with_data(EVP_MD_CTX *ctx, const EVP_MD *md,
162 const BUF_MEM *buf) {
163 if (!EVP_DigestInit_ex(ctx, md, NULL)) {
164 return 0;
165 }
166 EVP_DigestUpdate(ctx, buf->data, buf->length);
167 return 1;
168 }
169
SSL_TRANSCRIPT_init_hash(SSL_TRANSCRIPT * transcript,uint16_t version,int algorithm_prf)170 int SSL_TRANSCRIPT_init_hash(SSL_TRANSCRIPT *transcript, uint16_t version,
171 int algorithm_prf) {
172 const EVP_MD *md = ssl_get_handshake_digest(algorithm_prf, version);
173
174 /* To support SSL 3.0's Finished and CertificateVerify constructions,
175 * EVP_md5_sha1() is split into MD5 and SHA-1 halves. When SSL 3.0 is removed,
176 * we can simplify this. */
177 if (md == EVP_md5_sha1()) {
178 if (!init_digest_with_data(&transcript->md5, EVP_md5(),
179 transcript->buffer)) {
180 return 0;
181 }
182 md = EVP_sha1();
183 }
184
185 if (!init_digest_with_data(&transcript->hash, md, transcript->buffer)) {
186 return 0;
187 }
188
189 return 1;
190 }
191
SSL_TRANSCRIPT_cleanup(SSL_TRANSCRIPT * transcript)192 void SSL_TRANSCRIPT_cleanup(SSL_TRANSCRIPT *transcript) {
193 SSL_TRANSCRIPT_free_buffer(transcript);
194 EVP_MD_CTX_cleanup(&transcript->hash);
195 EVP_MD_CTX_cleanup(&transcript->md5);
196 }
197
SSL_TRANSCRIPT_free_buffer(SSL_TRANSCRIPT * transcript)198 void SSL_TRANSCRIPT_free_buffer(SSL_TRANSCRIPT *transcript) {
199 BUF_MEM_free(transcript->buffer);
200 transcript->buffer = NULL;
201 }
202
SSL_TRANSCRIPT_digest_len(const SSL_TRANSCRIPT * transcript)203 size_t SSL_TRANSCRIPT_digest_len(const SSL_TRANSCRIPT *transcript) {
204 return EVP_MD_size(SSL_TRANSCRIPT_md(transcript));
205 }
206
SSL_TRANSCRIPT_md(const SSL_TRANSCRIPT * transcript)207 const EVP_MD *SSL_TRANSCRIPT_md(const SSL_TRANSCRIPT *transcript) {
208 if (EVP_MD_CTX_md(&transcript->md5) != NULL) {
209 return EVP_md5_sha1();
210 }
211 return EVP_MD_CTX_md(&transcript->hash);
212 }
213
SSL_TRANSCRIPT_update(SSL_TRANSCRIPT * transcript,const uint8_t * in,size_t in_len)214 int SSL_TRANSCRIPT_update(SSL_TRANSCRIPT *transcript, const uint8_t *in,
215 size_t in_len) {
216 /* Depending on the state of the handshake, either the handshake buffer may be
217 * active, the rolling hash, or both. */
218 if (transcript->buffer != NULL) {
219 size_t new_len = transcript->buffer->length + in_len;
220 if (new_len < in_len) {
221 OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
222 return 0;
223 }
224 if (!BUF_MEM_grow(transcript->buffer, new_len)) {
225 return 0;
226 }
227 OPENSSL_memcpy(transcript->buffer->data + new_len - in_len, in, in_len);
228 }
229
230 if (EVP_MD_CTX_md(&transcript->hash) != NULL) {
231 EVP_DigestUpdate(&transcript->hash, in, in_len);
232 }
233 if (EVP_MD_CTX_md(&transcript->md5) != NULL) {
234 EVP_DigestUpdate(&transcript->md5, in, in_len);
235 }
236
237 return 1;
238 }
239
SSL_TRANSCRIPT_get_hash(const SSL_TRANSCRIPT * transcript,uint8_t * out,size_t * out_len)240 int SSL_TRANSCRIPT_get_hash(const SSL_TRANSCRIPT *transcript, uint8_t *out,
241 size_t *out_len) {
242 int ret = 0;
243 EVP_MD_CTX ctx;
244 EVP_MD_CTX_init(&ctx);
245 unsigned md5_len = 0;
246 if (EVP_MD_CTX_md(&transcript->md5) != NULL) {
247 if (!EVP_MD_CTX_copy_ex(&ctx, &transcript->md5) ||
248 !EVP_DigestFinal_ex(&ctx, out, &md5_len)) {
249 goto err;
250 }
251 }
252
253 unsigned len;
254 if (!EVP_MD_CTX_copy_ex(&ctx, &transcript->hash) ||
255 !EVP_DigestFinal_ex(&ctx, out + md5_len, &len)) {
256 goto err;
257 }
258
259 *out_len = md5_len + len;
260 ret = 1;
261
262 err:
263 EVP_MD_CTX_cleanup(&ctx);
264 return ret;
265 }
266
ssl3_handshake_mac(SSL_TRANSCRIPT * transcript,const SSL_SESSION * session,const EVP_MD_CTX * ctx_template,const char * sender,size_t sender_len,uint8_t * p,size_t * out_len)267 static int ssl3_handshake_mac(SSL_TRANSCRIPT *transcript,
268 const SSL_SESSION *session,
269 const EVP_MD_CTX *ctx_template,
270 const char *sender, size_t sender_len,
271 uint8_t *p, size_t *out_len) {
272 unsigned int len;
273 size_t npad, n;
274 unsigned int i;
275 uint8_t md_buf[EVP_MAX_MD_SIZE];
276 EVP_MD_CTX ctx;
277
278 EVP_MD_CTX_init(&ctx);
279 if (!EVP_MD_CTX_copy_ex(&ctx, ctx_template)) {
280 EVP_MD_CTX_cleanup(&ctx);
281 OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP);
282 return 0;
283 }
284
285 static const uint8_t kPad1[48] = {
286 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
287 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
288 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
289 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
290 };
291
292 static const uint8_t kPad2[48] = {
293 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
294 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
295 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
296 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
297 };
298
299 n = EVP_MD_CTX_size(&ctx);
300
301 npad = (48 / n) * n;
302 if (sender != NULL) {
303 EVP_DigestUpdate(&ctx, sender, sender_len);
304 }
305 EVP_DigestUpdate(&ctx, session->master_key, session->master_key_length);
306 EVP_DigestUpdate(&ctx, kPad1, npad);
307 EVP_DigestFinal_ex(&ctx, md_buf, &i);
308
309 if (!EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL)) {
310 EVP_MD_CTX_cleanup(&ctx);
311 OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP);
312 return 0;
313 }
314 EVP_DigestUpdate(&ctx, session->master_key, session->master_key_length);
315 EVP_DigestUpdate(&ctx, kPad2, npad);
316 EVP_DigestUpdate(&ctx, md_buf, i);
317 EVP_DigestFinal_ex(&ctx, p, &len);
318
319 EVP_MD_CTX_cleanup(&ctx);
320
321 *out_len = len;
322 return 1;
323 }
324
SSL_TRANSCRIPT_ssl3_cert_verify_hash(SSL_TRANSCRIPT * transcript,uint8_t * out,size_t * out_len,const SSL_SESSION * session,int signature_algorithm)325 int SSL_TRANSCRIPT_ssl3_cert_verify_hash(SSL_TRANSCRIPT *transcript,
326 uint8_t *out, size_t *out_len,
327 const SSL_SESSION *session,
328 int signature_algorithm) {
329 if (SSL_TRANSCRIPT_md(transcript) != EVP_md5_sha1()) {
330 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
331 return 0;
332 }
333
334 if (signature_algorithm == SSL_SIGN_RSA_PKCS1_MD5_SHA1) {
335 size_t md5_len, len;
336 if (!ssl3_handshake_mac(transcript, session, &transcript->md5, NULL, 0, out,
337 &md5_len) ||
338 !ssl3_handshake_mac(transcript, session, &transcript->hash, NULL, 0,
339 out + md5_len, &len)) {
340 return 0;
341 }
342 *out_len = md5_len + len;
343 return 1;
344 }
345
346 if (signature_algorithm == SSL_SIGN_ECDSA_SHA1) {
347 return ssl3_handshake_mac(transcript, session, &transcript->hash, NULL, 0,
348 out, out_len);
349 }
350
351 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
352 return 0;
353 }
354
SSL_TRANSCRIPT_finish_mac(SSL_TRANSCRIPT * transcript,uint8_t * out,size_t * out_len,const SSL_SESSION * session,int from_server,uint16_t version)355 int SSL_TRANSCRIPT_finish_mac(SSL_TRANSCRIPT *transcript, uint8_t *out,
356 size_t *out_len, const SSL_SESSION *session,
357 int from_server, uint16_t version) {
358 if (version == SSL3_VERSION) {
359 if (SSL_TRANSCRIPT_md(transcript) != EVP_md5_sha1()) {
360 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
361 return 0;
362 }
363
364 const char *sender = from_server ? SSL3_MD_SERVER_FINISHED_CONST
365 : SSL3_MD_CLIENT_FINISHED_CONST;
366 const size_t sender_len = 4;
367 size_t md5_len, len;
368 if (!ssl3_handshake_mac(transcript, session, &transcript->md5, sender,
369 sender_len, out, &md5_len) ||
370 !ssl3_handshake_mac(transcript, session, &transcript->hash, sender,
371 sender_len, out + md5_len, &len)) {
372 return 0;
373 }
374
375 *out_len = md5_len + len;
376 return 1;
377 }
378
379 /* At this point, the handshake should have released the handshake buffer on
380 * its own. */
381 assert(transcript->buffer == NULL);
382
383 const char *label = TLS_MD_CLIENT_FINISH_CONST;
384 size_t label_len = TLS_MD_SERVER_FINISH_CONST_SIZE;
385 if (from_server) {
386 label = TLS_MD_SERVER_FINISH_CONST;
387 label_len = TLS_MD_SERVER_FINISH_CONST_SIZE;
388 }
389
390 uint8_t digests[EVP_MAX_MD_SIZE];
391 size_t digests_len;
392 if (!SSL_TRANSCRIPT_get_hash(transcript, digests, &digests_len)) {
393 return 0;
394 }
395
396 static const size_t kFinishedLen = 12;
397 if (!tls1_prf(SSL_TRANSCRIPT_md(transcript), out, kFinishedLen,
398 session->master_key, session->master_key_length, label,
399 label_len, digests, digests_len, NULL, 0)) {
400 return 0;
401 }
402
403 *out_len = kFinishedLen;
404 return 1;
405 }
406