1 /*
2  * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18 
19 FILE_LICENCE ( GPL2_OR_LATER );
20 
21 /**
22  * @file
23  *
24  * Transport Layer Security Protocol
25  */
26 
27 #include <stdint.h>
28 #include <stdlib.h>
29 #include <stdarg.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <byteswap.h>
33 #include <gpxe/hmac.h>
34 #include <gpxe/md5.h>
35 #include <gpxe/sha1.h>
36 #include <gpxe/aes.h>
37 #include <gpxe/rsa.h>
38 #include <gpxe/xfer.h>
39 #include <gpxe/open.h>
40 #include <gpxe/filter.h>
41 #include <gpxe/asn1.h>
42 #include <gpxe/x509.h>
43 #include <gpxe/tls.h>
44 
45 static int tls_send_plaintext ( struct tls_session *tls, unsigned int type,
46 				const void *data, size_t len );
47 static void tls_clear_cipher ( struct tls_session *tls,
48 			       struct tls_cipherspec *cipherspec );
49 
50 /******************************************************************************
51  *
52  * Utility functions
53  *
54  ******************************************************************************
55  */
56 
57 /**
58  * Extract 24-bit field value
59  *
60  * @v field24		24-bit field
61  * @ret value		Field value
62  *
63  * TLS uses 24-bit integers in several places, which are awkward to
64  * parse in C.
65  */
tls_uint24(uint8_t field24[3])66 static unsigned long tls_uint24 ( uint8_t field24[3] ) {
67 	return ( ( field24[0] << 16 ) + ( field24[1] << 8 ) + field24[2] );
68 }
69 
70 /******************************************************************************
71  *
72  * Cleanup functions
73  *
74  ******************************************************************************
75  */
76 
77 /**
78  * Free TLS session
79  *
80  * @v refcnt		Reference counter
81  */
free_tls(struct refcnt * refcnt)82 static void free_tls ( struct refcnt *refcnt ) {
83 	struct tls_session *tls =
84 		container_of ( refcnt, struct tls_session, refcnt );
85 
86 	/* Free dynamically-allocated resources */
87 	tls_clear_cipher ( tls, &tls->tx_cipherspec );
88 	tls_clear_cipher ( tls, &tls->tx_cipherspec_pending );
89 	tls_clear_cipher ( tls, &tls->rx_cipherspec );
90 	tls_clear_cipher ( tls, &tls->rx_cipherspec_pending );
91 	x509_free_rsa_public_key ( &tls->rsa );
92 	free ( tls->rx_data );
93 
94 	/* Free TLS structure itself */
95 	free ( tls );
96 }
97 
98 /**
99  * Finish with TLS session
100  *
101  * @v tls		TLS session
102  * @v rc		Status code
103  */
tls_close(struct tls_session * tls,int rc)104 static void tls_close ( struct tls_session *tls, int rc ) {
105 
106 	/* Remove process */
107 	process_del ( &tls->process );
108 
109 	/* Close ciphertext and plaintext streams */
110 	xfer_nullify ( &tls->cipherstream.xfer );
111 	xfer_close ( &tls->cipherstream.xfer, rc );
112 	xfer_nullify ( &tls->plainstream.xfer );
113 	xfer_close ( &tls->plainstream.xfer, rc );
114 }
115 
116 /******************************************************************************
117  *
118  * Random number generation
119  *
120  ******************************************************************************
121  */
122 
123 /**
124  * Generate random data
125  *
126  * @v data		Buffer to fill
127  * @v len		Length of buffer
128  */
tls_generate_random(void * data,size_t len)129 static void tls_generate_random ( void *data, size_t len ) {
130 	/* FIXME: Some real random data source would be nice... */
131 	memset ( data, 0x01, len );
132 }
133 
134 /**
135  * Update HMAC with a list of ( data, len ) pairs
136  *
137  * @v digest		Hash function to use
138  * @v digest_ctx	Digest context
139  * @v args		( data, len ) pairs of data, terminated by NULL
140  */
tls_hmac_update_va(struct digest_algorithm * digest,void * digest_ctx,va_list args)141 static void tls_hmac_update_va ( struct digest_algorithm *digest,
142 				 void *digest_ctx, va_list args ) {
143 	void *data;
144 	size_t len;
145 
146 	while ( ( data = va_arg ( args, void * ) ) ) {
147 		len = va_arg ( args, size_t );
148 		hmac_update ( digest, digest_ctx, data, len );
149 	}
150 }
151 
152 /**
153  * Generate secure pseudo-random data using a single hash function
154  *
155  * @v tls		TLS session
156  * @v digest		Hash function to use
157  * @v secret		Secret
158  * @v secret_len	Length of secret
159  * @v out		Output buffer
160  * @v out_len		Length of output buffer
161  * @v seeds		( data, len ) pairs of seed data, terminated by NULL
162  */
tls_p_hash_va(struct tls_session * tls,struct digest_algorithm * digest,void * secret,size_t secret_len,void * out,size_t out_len,va_list seeds)163 static void tls_p_hash_va ( struct tls_session *tls,
164 			    struct digest_algorithm *digest,
165 			    void *secret, size_t secret_len,
166 			    void *out, size_t out_len,
167 			    va_list seeds ) {
168 	uint8_t secret_copy[secret_len];
169 	uint8_t digest_ctx[digest->ctxsize];
170 	uint8_t digest_ctx_partial[digest->ctxsize];
171 	uint8_t a[digest->digestsize];
172 	uint8_t out_tmp[digest->digestsize];
173 	size_t frag_len = digest->digestsize;
174 	va_list tmp;
175 
176 	/* Copy the secret, in case HMAC modifies it */
177 	memcpy ( secret_copy, secret, secret_len );
178 	secret = secret_copy;
179 	DBGC2 ( tls, "TLS %p %s secret:\n", tls, digest->name );
180 	DBGC2_HD ( tls, secret, secret_len );
181 
182 	/* Calculate A(1) */
183 	hmac_init ( digest, digest_ctx, secret, &secret_len );
184 	va_copy ( tmp, seeds );
185 	tls_hmac_update_va ( digest, digest_ctx, tmp );
186 	va_end ( tmp );
187 	hmac_final ( digest, digest_ctx, secret, &secret_len, a );
188 	DBGC2 ( tls, "TLS %p %s A(1):\n", tls, digest->name );
189 	DBGC2_HD ( tls, &a, sizeof ( a ) );
190 
191 	/* Generate as much data as required */
192 	while ( out_len ) {
193 		/* Calculate output portion */
194 		hmac_init ( digest, digest_ctx, secret, &secret_len );
195 		hmac_update ( digest, digest_ctx, a, sizeof ( a ) );
196 		memcpy ( digest_ctx_partial, digest_ctx, digest->ctxsize );
197 		va_copy ( tmp, seeds );
198 		tls_hmac_update_va ( digest, digest_ctx, tmp );
199 		va_end ( tmp );
200 		hmac_final ( digest, digest_ctx,
201 			     secret, &secret_len, out_tmp );
202 
203 		/* Copy output */
204 		if ( frag_len > out_len )
205 			frag_len = out_len;
206 		memcpy ( out, out_tmp, frag_len );
207 		DBGC2 ( tls, "TLS %p %s output:\n", tls, digest->name );
208 		DBGC2_HD ( tls, out, frag_len );
209 
210 		/* Calculate A(i) */
211 		hmac_final ( digest, digest_ctx_partial,
212 			     secret, &secret_len, a );
213 		DBGC2 ( tls, "TLS %p %s A(n):\n", tls, digest->name );
214 		DBGC2_HD ( tls, &a, sizeof ( a ) );
215 
216 		out += frag_len;
217 		out_len -= frag_len;
218 	}
219 }
220 
221 /**
222  * Generate secure pseudo-random data
223  *
224  * @v tls		TLS session
225  * @v secret		Secret
226  * @v secret_len	Length of secret
227  * @v out		Output buffer
228  * @v out_len		Length of output buffer
229  * @v ...		( data, len ) pairs of seed data, terminated by NULL
230  */
tls_prf(struct tls_session * tls,void * secret,size_t secret_len,void * out,size_t out_len,...)231 static void tls_prf ( struct tls_session *tls, void *secret, size_t secret_len,
232 		      void *out, size_t out_len, ... ) {
233 	va_list seeds;
234 	va_list tmp;
235 	size_t subsecret_len;
236 	void *md5_secret;
237 	void *sha1_secret;
238 	uint8_t out_md5[out_len];
239 	uint8_t out_sha1[out_len];
240 	unsigned int i;
241 
242 	va_start ( seeds, out_len );
243 
244 	/* Split secret into two, with an overlap of up to one byte */
245 	subsecret_len = ( ( secret_len + 1 ) / 2 );
246 	md5_secret = secret;
247 	sha1_secret = ( secret + secret_len - subsecret_len );
248 
249 	/* Calculate MD5 portion */
250 	va_copy ( tmp, seeds );
251 	tls_p_hash_va ( tls, &md5_algorithm, md5_secret, subsecret_len,
252 			out_md5, out_len, seeds );
253 	va_end ( tmp );
254 
255 	/* Calculate SHA1 portion */
256 	va_copy ( tmp, seeds );
257 	tls_p_hash_va ( tls, &sha1_algorithm, sha1_secret, subsecret_len,
258 			out_sha1, out_len, seeds );
259 	va_end ( tmp );
260 
261 	/* XOR the two portions together into the final output buffer */
262 	for ( i = 0 ; i < out_len ; i++ ) {
263 		*( ( uint8_t * ) out + i ) = ( out_md5[i] ^ out_sha1[i] );
264 	}
265 
266 	va_end ( seeds );
267 }
268 
269 /**
270  * Generate secure pseudo-random data
271  *
272  * @v secret		Secret
273  * @v secret_len	Length of secret
274  * @v out		Output buffer
275  * @v out_len		Length of output buffer
276  * @v label		String literal label
277  * @v ...		( data, len ) pairs of seed data
278  */
279 #define tls_prf_label( tls, secret, secret_len, out, out_len, label, ... ) \
280 	tls_prf ( (tls), (secret), (secret_len), (out), (out_len),	   \
281 		  label, ( sizeof ( label ) - 1 ), __VA_ARGS__, NULL )
282 
283 /******************************************************************************
284  *
285  * Secret management
286  *
287  ******************************************************************************
288  */
289 
290 /**
291  * Generate master secret
292  *
293  * @v tls		TLS session
294  *
295  * The pre-master secret and the client and server random values must
296  * already be known.
297  */
tls_generate_master_secret(struct tls_session * tls)298 static void tls_generate_master_secret ( struct tls_session *tls ) {
299 	DBGC ( tls, "TLS %p pre-master-secret:\n", tls );
300 	DBGC_HD ( tls, &tls->pre_master_secret,
301 		  sizeof ( tls->pre_master_secret ) );
302 	DBGC ( tls, "TLS %p client random bytes:\n", tls );
303 	DBGC_HD ( tls, &tls->client_random, sizeof ( tls->client_random ) );
304 	DBGC ( tls, "TLS %p server random bytes:\n", tls );
305 	DBGC_HD ( tls, &tls->server_random, sizeof ( tls->server_random ) );
306 
307 	tls_prf_label ( tls, &tls->pre_master_secret,
308 			sizeof ( tls->pre_master_secret ),
309 			&tls->master_secret, sizeof ( tls->master_secret ),
310 			"master secret",
311 			&tls->client_random, sizeof ( tls->client_random ),
312 			&tls->server_random, sizeof ( tls->server_random ) );
313 
314 	DBGC ( tls, "TLS %p generated master secret:\n", tls );
315 	DBGC_HD ( tls, &tls->master_secret, sizeof ( tls->master_secret ) );
316 }
317 
318 /**
319  * Generate key material
320  *
321  * @v tls		TLS session
322  *
323  * The master secret must already be known.
324  */
tls_generate_keys(struct tls_session * tls)325 static int tls_generate_keys ( struct tls_session *tls ) {
326 	struct tls_cipherspec *tx_cipherspec = &tls->tx_cipherspec_pending;
327 	struct tls_cipherspec *rx_cipherspec = &tls->rx_cipherspec_pending;
328 	size_t hash_size = tx_cipherspec->digest->digestsize;
329 	size_t key_size = tx_cipherspec->key_len;
330 	size_t iv_size = tx_cipherspec->cipher->blocksize;
331 	size_t total = ( 2 * ( hash_size + key_size + iv_size ) );
332 	uint8_t key_block[total];
333 	uint8_t *key;
334 	int rc;
335 
336 	/* Generate key block */
337 	tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
338 			key_block, sizeof ( key_block ), "key expansion",
339 			&tls->server_random, sizeof ( tls->server_random ),
340 			&tls->client_random, sizeof ( tls->client_random ) );
341 
342 	/* Split key block into portions */
343 	key = key_block;
344 
345 	/* TX MAC secret */
346 	memcpy ( tx_cipherspec->mac_secret, key, hash_size );
347 	DBGC ( tls, "TLS %p TX MAC secret:\n", tls );
348 	DBGC_HD ( tls, key, hash_size );
349 	key += hash_size;
350 
351 	/* RX MAC secret */
352 	memcpy ( rx_cipherspec->mac_secret, key, hash_size );
353 	DBGC ( tls, "TLS %p RX MAC secret:\n", tls );
354 	DBGC_HD ( tls, key, hash_size );
355 	key += hash_size;
356 
357 	/* TX key */
358 	if ( ( rc = cipher_setkey ( tx_cipherspec->cipher,
359 				    tx_cipherspec->cipher_ctx,
360 				    key, key_size ) ) != 0 ) {
361 		DBGC ( tls, "TLS %p could not set TX key: %s\n",
362 		       tls, strerror ( rc ) );
363 		return rc;
364 	}
365 	DBGC ( tls, "TLS %p TX key:\n", tls );
366 	DBGC_HD ( tls, key, key_size );
367 	key += key_size;
368 
369 	/* RX key */
370 	if ( ( rc = cipher_setkey ( rx_cipherspec->cipher,
371 				    rx_cipherspec->cipher_ctx,
372 				    key, key_size ) ) != 0 ) {
373 		DBGC ( tls, "TLS %p could not set TX key: %s\n",
374 		       tls, strerror ( rc ) );
375 		return rc;
376 	}
377 	DBGC ( tls, "TLS %p RX key:\n", tls );
378 	DBGC_HD ( tls, key, key_size );
379 	key += key_size;
380 
381 	/* TX initialisation vector */
382 	cipher_setiv ( tx_cipherspec->cipher, tx_cipherspec->cipher_ctx, key );
383 	DBGC ( tls, "TLS %p TX IV:\n", tls );
384 	DBGC_HD ( tls, key, iv_size );
385 	key += iv_size;
386 
387 	/* RX initialisation vector */
388 	cipher_setiv ( rx_cipherspec->cipher, rx_cipherspec->cipher_ctx, key );
389 	DBGC ( tls, "TLS %p RX IV:\n", tls );
390 	DBGC_HD ( tls, key, iv_size );
391 	key += iv_size;
392 
393 	assert ( ( key_block + total ) == key );
394 
395 	return 0;
396 }
397 
398 /******************************************************************************
399  *
400  * Cipher suite management
401  *
402  ******************************************************************************
403  */
404 
405 /**
406  * Clear cipher suite
407  *
408  * @v cipherspec	TLS cipher specification
409  */
tls_clear_cipher(struct tls_session * tls __unused,struct tls_cipherspec * cipherspec)410 static void tls_clear_cipher ( struct tls_session *tls __unused,
411 			       struct tls_cipherspec *cipherspec ) {
412 	free ( cipherspec->dynamic );
413 	memset ( cipherspec, 0, sizeof ( cipherspec ) );
414 	cipherspec->pubkey = &pubkey_null;
415 	cipherspec->cipher = &cipher_null;
416 	cipherspec->digest = &digest_null;
417 }
418 
419 /**
420  * Set cipher suite
421  *
422  * @v tls		TLS session
423  * @v cipherspec	TLS cipher specification
424  * @v pubkey		Public-key encryption elgorithm
425  * @v cipher		Bulk encryption cipher algorithm
426  * @v digest		MAC digest algorithm
427  * @v key_len		Key length
428  * @ret rc		Return status code
429  */
tls_set_cipher(struct tls_session * tls,struct tls_cipherspec * cipherspec,struct pubkey_algorithm * pubkey,struct cipher_algorithm * cipher,struct digest_algorithm * digest,size_t key_len)430 static int tls_set_cipher ( struct tls_session *tls,
431 			    struct tls_cipherspec *cipherspec,
432 			    struct pubkey_algorithm *pubkey,
433 			    struct cipher_algorithm *cipher,
434 			    struct digest_algorithm *digest,
435 			    size_t key_len ) {
436 	size_t total;
437 	void *dynamic;
438 
439 	/* Clear out old cipher contents, if any */
440 	tls_clear_cipher ( tls, cipherspec );
441 
442 	/* Allocate dynamic storage */
443 	total = ( pubkey->ctxsize + 2 * cipher->ctxsize + digest->digestsize );
444 	dynamic = malloc ( total );
445 	if ( ! dynamic ) {
446 		DBGC ( tls, "TLS %p could not allocate %zd bytes for crypto "
447 		       "context\n", tls, total );
448 		return -ENOMEM;
449 	}
450 	memset ( dynamic, 0, total );
451 
452 	/* Assign storage */
453 	cipherspec->dynamic = dynamic;
454 	cipherspec->pubkey_ctx = dynamic;	dynamic += pubkey->ctxsize;
455 	cipherspec->cipher_ctx = dynamic;	dynamic += cipher->ctxsize;
456 	cipherspec->cipher_next_ctx = dynamic;	dynamic += cipher->ctxsize;
457 	cipherspec->mac_secret = dynamic;	dynamic += digest->digestsize;
458 	assert ( ( cipherspec->dynamic + total ) == dynamic );
459 
460 	/* Store parameters */
461 	cipherspec->pubkey = pubkey;
462 	cipherspec->cipher = cipher;
463 	cipherspec->digest = digest;
464 	cipherspec->key_len = key_len;
465 
466 	return 0;
467 }
468 
469 /**
470  * Select next cipher suite
471  *
472  * @v tls		TLS session
473  * @v cipher_suite	Cipher suite specification
474  * @ret rc		Return status code
475  */
tls_select_cipher(struct tls_session * tls,unsigned int cipher_suite)476 static int tls_select_cipher ( struct tls_session *tls,
477 			       unsigned int cipher_suite ) {
478 	struct pubkey_algorithm *pubkey = &pubkey_null;
479 	struct cipher_algorithm *cipher = &cipher_null;
480 	struct digest_algorithm *digest = &digest_null;
481 	unsigned int key_len = 0;
482 	int rc;
483 
484 	switch ( cipher_suite ) {
485 	case htons ( TLS_RSA_WITH_AES_128_CBC_SHA ):
486 		key_len = ( 128 / 8 );
487 		cipher = &aes_cbc_algorithm;
488 		digest = &sha1_algorithm;
489 		break;
490 	case htons ( TLS_RSA_WITH_AES_256_CBC_SHA ):
491 		key_len = ( 256 / 8 );
492 		cipher = &aes_cbc_algorithm;
493 		digest = &sha1_algorithm;
494 		break;
495 	default:
496 		DBGC ( tls, "TLS %p does not support cipher %04x\n",
497 		       tls, ntohs ( cipher_suite ) );
498 		return -ENOTSUP;
499 	}
500 
501 	/* Set ciphers */
502 	if ( ( rc = tls_set_cipher ( tls, &tls->tx_cipherspec_pending, pubkey,
503 				     cipher, digest, key_len ) ) != 0 )
504 		return rc;
505 	if ( ( rc = tls_set_cipher ( tls, &tls->rx_cipherspec_pending, pubkey,
506 				     cipher, digest, key_len ) ) != 0 )
507 		return rc;
508 
509 	DBGC ( tls, "TLS %p selected %s-%s-%d-%s\n", tls,
510 	       pubkey->name, cipher->name, ( key_len * 8 ), digest->name );
511 
512 	return 0;
513 }
514 
515 /**
516  * Activate next cipher suite
517  *
518  * @v tls		TLS session
519  * @v pending		Pending cipher specification
520  * @v active		Active cipher specification to replace
521  * @ret rc		Return status code
522  */
tls_change_cipher(struct tls_session * tls,struct tls_cipherspec * pending,struct tls_cipherspec * active)523 static int tls_change_cipher ( struct tls_session *tls,
524 			       struct tls_cipherspec *pending,
525 			       struct tls_cipherspec *active ) {
526 
527 	/* Sanity check */
528 	if ( /* FIXME (when pubkey is not hard-coded to RSA):
529 	      * ( pending->pubkey == &pubkey_null ) || */
530 	     ( pending->cipher == &cipher_null ) ||
531 	     ( pending->digest == &digest_null ) ) {
532 		DBGC ( tls, "TLS %p refusing to use null cipher\n", tls );
533 		return -ENOTSUP;
534 	}
535 
536 	tls_clear_cipher ( tls, active );
537 	memswap ( active, pending, sizeof ( *active ) );
538 	return 0;
539 }
540 
541 /******************************************************************************
542  *
543  * Handshake verification
544  *
545  ******************************************************************************
546  */
547 
548 /**
549  * Add handshake record to verification hash
550  *
551  * @v tls		TLS session
552  * @v data		Handshake record
553  * @v len		Length of handshake record
554  */
tls_add_handshake(struct tls_session * tls,const void * data,size_t len)555 static void tls_add_handshake ( struct tls_session *tls,
556 				const void *data, size_t len ) {
557 
558 	digest_update ( &md5_algorithm, tls->handshake_md5_ctx, data, len );
559 	digest_update ( &sha1_algorithm, tls->handshake_sha1_ctx, data, len );
560 }
561 
562 /**
563  * Calculate handshake verification hash
564  *
565  * @v tls		TLS session
566  * @v out		Output buffer
567  *
568  * Calculates the MD5+SHA1 digest over all handshake messages seen so
569  * far.
570  */
tls_verify_handshake(struct tls_session * tls,void * out)571 static void tls_verify_handshake ( struct tls_session *tls, void *out ) {
572 	struct digest_algorithm *md5 = &md5_algorithm;
573 	struct digest_algorithm *sha1 = &sha1_algorithm;
574 	uint8_t md5_ctx[md5->ctxsize];
575 	uint8_t sha1_ctx[sha1->ctxsize];
576 	void *md5_digest = out;
577 	void *sha1_digest = ( out + md5->digestsize );
578 
579 	memcpy ( md5_ctx, tls->handshake_md5_ctx, sizeof ( md5_ctx ) );
580 	memcpy ( sha1_ctx, tls->handshake_sha1_ctx, sizeof ( sha1_ctx ) );
581 	digest_final ( md5, md5_ctx, md5_digest );
582 	digest_final ( sha1, sha1_ctx, sha1_digest );
583 }
584 
585 /******************************************************************************
586  *
587  * Record handling
588  *
589  ******************************************************************************
590  */
591 
592 /**
593  * Transmit Handshake record
594  *
595  * @v tls		TLS session
596  * @v data		Plaintext record
597  * @v len		Length of plaintext record
598  * @ret rc		Return status code
599  */
tls_send_handshake(struct tls_session * tls,void * data,size_t len)600 static int tls_send_handshake ( struct tls_session *tls,
601 				void *data, size_t len ) {
602 
603 	/* Add to handshake digest */
604 	tls_add_handshake ( tls, data, len );
605 
606 	/* Send record */
607 	return tls_send_plaintext ( tls, TLS_TYPE_HANDSHAKE, data, len );
608 }
609 
610 /**
611  * Transmit Client Hello record
612  *
613  * @v tls		TLS session
614  * @ret rc		Return status code
615  */
tls_send_client_hello(struct tls_session * tls)616 static int tls_send_client_hello ( struct tls_session *tls ) {
617 	struct {
618 		uint32_t type_length;
619 		uint16_t version;
620 		uint8_t random[32];
621 		uint8_t session_id_len;
622 		uint16_t cipher_suite_len;
623 		uint16_t cipher_suites[2];
624 		uint8_t compression_methods_len;
625 		uint8_t compression_methods[1];
626 	} __attribute__ (( packed )) hello;
627 
628 	memset ( &hello, 0, sizeof ( hello ) );
629 	hello.type_length = ( cpu_to_le32 ( TLS_CLIENT_HELLO ) |
630 			      htonl ( sizeof ( hello ) -
631 				      sizeof ( hello.type_length ) ) );
632 	hello.version = htons ( TLS_VERSION_TLS_1_0 );
633 	memcpy ( &hello.random, &tls->client_random, sizeof ( hello.random ) );
634 	hello.cipher_suite_len = htons ( sizeof ( hello.cipher_suites ) );
635 	hello.cipher_suites[0] = htons ( TLS_RSA_WITH_AES_128_CBC_SHA );
636 	hello.cipher_suites[1] = htons ( TLS_RSA_WITH_AES_256_CBC_SHA );
637 	hello.compression_methods_len = sizeof ( hello.compression_methods );
638 
639 	return tls_send_handshake ( tls, &hello, sizeof ( hello ) );
640 }
641 
642 /**
643  * Transmit Client Key Exchange record
644  *
645  * @v tls		TLS session
646  * @ret rc		Return status code
647  */
tls_send_client_key_exchange(struct tls_session * tls)648 static int tls_send_client_key_exchange ( struct tls_session *tls ) {
649 	/* FIXME: Hack alert */
650 	RSA_CTX *rsa_ctx;
651 	RSA_pub_key_new ( &rsa_ctx, tls->rsa.modulus, tls->rsa.modulus_len,
652 			  tls->rsa.exponent, tls->rsa.exponent_len );
653 	struct {
654 		uint32_t type_length;
655 		uint16_t encrypted_pre_master_secret_len;
656 		uint8_t encrypted_pre_master_secret[rsa_ctx->num_octets];
657 	} __attribute__ (( packed )) key_xchg;
658 
659 	memset ( &key_xchg, 0, sizeof ( key_xchg ) );
660 	key_xchg.type_length = ( cpu_to_le32 ( TLS_CLIENT_KEY_EXCHANGE ) |
661 				 htonl ( sizeof ( key_xchg ) -
662 					 sizeof ( key_xchg.type_length ) ) );
663 	key_xchg.encrypted_pre_master_secret_len
664 		= htons ( sizeof ( key_xchg.encrypted_pre_master_secret ) );
665 
666 	/* FIXME: Hack alert */
667 	DBGC ( tls, "RSA encrypting plaintext, modulus, exponent:\n" );
668 	DBGC_HD ( tls, &tls->pre_master_secret,
669 		  sizeof ( tls->pre_master_secret ) );
670 	DBGC_HD ( tls, tls->rsa.modulus, tls->rsa.modulus_len );
671 	DBGC_HD ( tls, tls->rsa.exponent, tls->rsa.exponent_len );
672 	RSA_encrypt ( rsa_ctx, ( const uint8_t * ) &tls->pre_master_secret,
673 		      sizeof ( tls->pre_master_secret ),
674 		      key_xchg.encrypted_pre_master_secret, 0 );
675 	DBGC ( tls, "RSA encrypt done.  Ciphertext:\n" );
676 	DBGC_HD ( tls, &key_xchg.encrypted_pre_master_secret,
677 		  sizeof ( key_xchg.encrypted_pre_master_secret ) );
678 	RSA_free ( rsa_ctx );
679 
680 
681 	return tls_send_handshake ( tls, &key_xchg, sizeof ( key_xchg ) );
682 }
683 
684 /**
685  * Transmit Change Cipher record
686  *
687  * @v tls		TLS session
688  * @ret rc		Return status code
689  */
tls_send_change_cipher(struct tls_session * tls)690 static int tls_send_change_cipher ( struct tls_session *tls ) {
691 	static const uint8_t change_cipher[1] = { 1 };
692 	return tls_send_plaintext ( tls, TLS_TYPE_CHANGE_CIPHER,
693 				    change_cipher, sizeof ( change_cipher ) );
694 }
695 
696 /**
697  * Transmit Finished record
698  *
699  * @v tls		TLS session
700  * @ret rc		Return status code
701  */
tls_send_finished(struct tls_session * tls)702 static int tls_send_finished ( struct tls_session *tls ) {
703 	struct {
704 		uint32_t type_length;
705 		uint8_t verify_data[12];
706 	} __attribute__ (( packed )) finished;
707 	uint8_t digest[MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE];
708 
709 	memset ( &finished, 0, sizeof ( finished ) );
710 	finished.type_length = ( cpu_to_le32 ( TLS_FINISHED ) |
711 				 htonl ( sizeof ( finished ) -
712 					 sizeof ( finished.type_length ) ) );
713 	tls_verify_handshake ( tls, digest );
714 	tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
715 			finished.verify_data, sizeof ( finished.verify_data ),
716 			"client finished", digest, sizeof ( digest ) );
717 
718 	return tls_send_handshake ( tls, &finished, sizeof ( finished ) );
719 }
720 
721 /**
722  * Receive new Change Cipher record
723  *
724  * @v tls		TLS session
725  * @v data		Plaintext record
726  * @v len		Length of plaintext record
727  * @ret rc		Return status code
728  */
tls_new_change_cipher(struct tls_session * tls,void * data,size_t len)729 static int tls_new_change_cipher ( struct tls_session *tls,
730 				   void *data, size_t len ) {
731 	int rc;
732 
733 	if ( ( len != 1 ) || ( *( ( uint8_t * ) data ) != 1 ) ) {
734 		DBGC ( tls, "TLS %p received invalid Change Cipher\n", tls );
735 		DBGC_HD ( tls, data, len );
736 		return -EINVAL;
737 	}
738 
739 	if ( ( rc = tls_change_cipher ( tls, &tls->rx_cipherspec_pending,
740 					&tls->rx_cipherspec ) ) != 0 ) {
741 		DBGC ( tls, "TLS %p could not activate RX cipher: %s\n",
742 		       tls, strerror ( rc ) );
743 		return rc;
744 	}
745 	tls->rx_seq = ~( ( uint64_t ) 0 );
746 
747 	return 0;
748 }
749 
750 /**
751  * Receive new Alert record
752  *
753  * @v tls		TLS session
754  * @v data		Plaintext record
755  * @v len		Length of plaintext record
756  * @ret rc		Return status code
757  */
tls_new_alert(struct tls_session * tls,void * data,size_t len)758 static int tls_new_alert ( struct tls_session *tls, void *data, size_t len ) {
759 	struct {
760 		uint8_t level;
761 		uint8_t description;
762 		char next[0];
763 	} __attribute__ (( packed )) *alert = data;
764 	void *end = alert->next;
765 
766 	/* Sanity check */
767 	if ( end != ( data + len ) ) {
768 		DBGC ( tls, "TLS %p received overlength Alert\n", tls );
769 		DBGC_HD ( tls, data, len );
770 		return -EINVAL;
771 	}
772 
773 	switch ( alert->level ) {
774 	case TLS_ALERT_WARNING:
775 		DBGC ( tls, "TLS %p received warning alert %d\n",
776 		       tls, alert->description );
777 		return 0;
778 	case TLS_ALERT_FATAL:
779 		DBGC ( tls, "TLS %p received fatal alert %d\n",
780 		       tls, alert->description );
781 		return -EPERM;
782 	default:
783 		DBGC ( tls, "TLS %p received unknown alert level %d"
784 		       "(alert %d)\n", tls, alert->level, alert->description );
785 		return -EIO;
786 	}
787 }
788 
789 /**
790  * Receive new Server Hello handshake record
791  *
792  * @v tls		TLS session
793  * @v data		Plaintext handshake record
794  * @v len		Length of plaintext handshake record
795  * @ret rc		Return status code
796  */
tls_new_server_hello(struct tls_session * tls,void * data,size_t len)797 static int tls_new_server_hello ( struct tls_session *tls,
798 				  void *data, size_t len ) {
799 	struct {
800 		uint16_t version;
801 		uint8_t random[32];
802 		uint8_t session_id_len;
803 		char next[0];
804 	} __attribute__ (( packed )) *hello_a = data;
805 	struct {
806 		uint8_t session_id[hello_a->session_id_len];
807 		uint16_t cipher_suite;
808 		uint8_t compression_method;
809 		char next[0];
810 	} __attribute__ (( packed )) *hello_b = ( void * ) &hello_a->next;
811 	void *end = hello_b->next;
812 	int rc;
813 
814 	/* Sanity check */
815 	if ( end != ( data + len ) ) {
816 		DBGC ( tls, "TLS %p received overlength Server Hello\n", tls );
817 		DBGC_HD ( tls, data, len );
818 		return -EINVAL;
819 	}
820 
821 	/* Check protocol version */
822 	if ( ntohs ( hello_a->version ) < TLS_VERSION_TLS_1_0 ) {
823 		DBGC ( tls, "TLS %p does not support protocol version %d.%d\n",
824 		       tls, ( ntohs ( hello_a->version ) >> 8 ),
825 		       ( ntohs ( hello_a->version ) & 0xff ) );
826 		return -ENOTSUP;
827 	}
828 
829 	/* Copy out server random bytes */
830 	memcpy ( &tls->server_random, &hello_a->random,
831 		 sizeof ( tls->server_random ) );
832 
833 	/* Select cipher suite */
834 	if ( ( rc = tls_select_cipher ( tls, hello_b->cipher_suite ) ) != 0 )
835 		return rc;
836 
837 	/* Generate secrets */
838 	tls_generate_master_secret ( tls );
839 	if ( ( rc = tls_generate_keys ( tls ) ) != 0 )
840 		return rc;
841 
842 	return 0;
843 }
844 
845 /**
846  * Receive new Certificate handshake record
847  *
848  * @v tls		TLS session
849  * @v data		Plaintext handshake record
850  * @v len		Length of plaintext handshake record
851  * @ret rc		Return status code
852  */
tls_new_certificate(struct tls_session * tls,void * data,size_t len)853 static int tls_new_certificate ( struct tls_session *tls,
854 				 void *data, size_t len ) {
855 	struct {
856 		uint8_t length[3];
857 		uint8_t certificates[0];
858 	} __attribute__ (( packed )) *certificate = data;
859 	struct {
860 		uint8_t length[3];
861 		uint8_t certificate[0];
862 	} __attribute__ (( packed )) *element =
863 		  ( ( void * ) certificate->certificates );
864 	size_t elements_len = tls_uint24 ( certificate->length );
865 	void *end = ( certificate->certificates + elements_len );
866 	struct asn1_cursor cursor;
867 	int rc;
868 
869 	/* Sanity check */
870 	if ( end != ( data + len ) ) {
871 		DBGC ( tls, "TLS %p received overlength Server Certificate\n",
872 		       tls );
873 		DBGC_HD ( tls, data, len );
874 		return -EINVAL;
875 	}
876 
877 	/* Traverse certificate chain */
878 	do {
879 		cursor.data = element->certificate;
880 		cursor.len = tls_uint24 ( element->length );
881 		if ( ( cursor.data + cursor.len ) > end ) {
882 			DBGC ( tls, "TLS %p received corrupt Server "
883 			       "Certificate\n", tls );
884 			DBGC_HD ( tls, data, len );
885 			return -EINVAL;
886 		}
887 
888 		// HACK
889 		if ( ( rc = x509_rsa_public_key ( &cursor,
890 						  &tls->rsa ) ) != 0 ) {
891 			DBGC ( tls, "TLS %p cannot determine RSA public key: "
892 			       "%s\n", tls, strerror ( rc ) );
893 			return rc;
894 		}
895 		return 0;
896 
897 		element = ( cursor.data + cursor.len );
898 	} while ( element != end );
899 
900 	return -EINVAL;
901 }
902 
903 /**
904  * Receive new Server Hello Done handshake record
905  *
906  * @v tls		TLS session
907  * @v data		Plaintext handshake record
908  * @v len		Length of plaintext handshake record
909  * @ret rc		Return status code
910  */
tls_new_server_hello_done(struct tls_session * tls,void * data,size_t len)911 static int tls_new_server_hello_done ( struct tls_session *tls,
912 				       void *data, size_t len ) {
913 	struct {
914 		char next[0];
915 	} __attribute__ (( packed )) *hello_done = data;
916 	void *end = hello_done->next;
917 
918 	/* Sanity check */
919 	if ( end != ( data + len ) ) {
920 		DBGC ( tls, "TLS %p received overlength Server Hello Done\n",
921 		       tls );
922 		DBGC_HD ( tls, data, len );
923 		return -EINVAL;
924 	}
925 
926 	/* Check that we are ready to send the Client Key Exchange */
927 	if ( tls->tx_state != TLS_TX_NONE ) {
928 		DBGC ( tls, "TLS %p received Server Hello Done while in "
929 		       "TX state %d\n", tls, tls->tx_state );
930 		return -EIO;
931 	}
932 
933 	/* Start sending the Client Key Exchange */
934 	tls->tx_state = TLS_TX_CLIENT_KEY_EXCHANGE;
935 
936 	return 0;
937 }
938 
939 /**
940  * Receive new Finished handshake record
941  *
942  * @v tls		TLS session
943  * @v data		Plaintext handshake record
944  * @v len		Length of plaintext handshake record
945  * @ret rc		Return status code
946  */
tls_new_finished(struct tls_session * tls,void * data,size_t len)947 static int tls_new_finished ( struct tls_session *tls,
948 			      void *data, size_t len ) {
949 
950 	/* FIXME: Handle this properly */
951 	tls->tx_state = TLS_TX_DATA;
952 	( void ) data;
953 	( void ) len;
954 	return 0;
955 }
956 
957 /**
958  * Receive new Handshake record
959  *
960  * @v tls		TLS session
961  * @v data		Plaintext record
962  * @v len		Length of plaintext record
963  * @ret rc		Return status code
964  */
tls_new_handshake(struct tls_session * tls,void * data,size_t len)965 static int tls_new_handshake ( struct tls_session *tls,
966 			       void *data, size_t len ) {
967 	struct {
968 		uint8_t type;
969 		uint8_t length[3];
970 		uint8_t payload[0];
971 	} __attribute__ (( packed )) *handshake = data;
972 	void *payload = &handshake->payload;
973 	size_t payload_len = tls_uint24 ( handshake->length );
974 	void *end = ( payload + payload_len );
975 	int rc;
976 
977 	/* Sanity check */
978 	if ( end != ( data + len ) ) {
979 		DBGC ( tls, "TLS %p received overlength Handshake\n", tls );
980 		DBGC_HD ( tls, data, len );
981 		return -EINVAL;
982 	}
983 
984 	switch ( handshake->type ) {
985 	case TLS_SERVER_HELLO:
986 		rc = tls_new_server_hello ( tls, payload, payload_len );
987 		break;
988 	case TLS_CERTIFICATE:
989 		rc = tls_new_certificate ( tls, payload, payload_len );
990 		break;
991 	case TLS_SERVER_HELLO_DONE:
992 		rc = tls_new_server_hello_done ( tls, payload, payload_len );
993 		break;
994 	case TLS_FINISHED:
995 		rc = tls_new_finished ( tls, payload, payload_len );
996 		break;
997 	default:
998 		DBGC ( tls, "TLS %p ignoring handshake type %d\n",
999 		       tls, handshake->type );
1000 		rc = 0;
1001 		break;
1002 	}
1003 
1004 	/* Add to handshake digest (except for Hello Requests, which
1005 	 * are explicitly excluded).
1006 	 */
1007 	if ( handshake->type != TLS_HELLO_REQUEST )
1008 		tls_add_handshake ( tls, data, len );
1009 
1010 	return rc;
1011 }
1012 
1013 /**
1014  * Receive new record
1015  *
1016  * @v tls		TLS session
1017  * @v type		Record type
1018  * @v data		Plaintext record
1019  * @v len		Length of plaintext record
1020  * @ret rc		Return status code
1021  */
tls_new_record(struct tls_session * tls,unsigned int type,void * data,size_t len)1022 static int tls_new_record ( struct tls_session *tls,
1023 			    unsigned int type, void *data, size_t len ) {
1024 
1025 	switch ( type ) {
1026 	case TLS_TYPE_CHANGE_CIPHER:
1027 		return tls_new_change_cipher ( tls, data, len );
1028 	case TLS_TYPE_ALERT:
1029 		return tls_new_alert ( tls, data, len );
1030 	case TLS_TYPE_HANDSHAKE:
1031 		return tls_new_handshake ( tls, data, len );
1032 	case TLS_TYPE_DATA:
1033 		return xfer_deliver_raw ( &tls->plainstream.xfer, data, len );
1034 	default:
1035 		/* RFC4346 says that we should just ignore unknown
1036 		 * record types.
1037 		 */
1038 		DBGC ( tls, "TLS %p ignoring record type %d\n", tls, type );
1039 		return 0;
1040 	}
1041 }
1042 
1043 /******************************************************************************
1044  *
1045  * Record encryption/decryption
1046  *
1047  ******************************************************************************
1048  */
1049 
1050 /**
1051  * Calculate HMAC
1052  *
1053  * @v tls		TLS session
1054  * @v cipherspec	Cipher specification
1055  * @v seq		Sequence number
1056  * @v tlshdr		TLS header
1057  * @v data		Data
1058  * @v len		Length of data
1059  * @v mac		HMAC to fill in
1060  */
tls_hmac(struct tls_session * tls __unused,struct tls_cipherspec * cipherspec,uint64_t seq,struct tls_header * tlshdr,const void * data,size_t len,void * hmac)1061 static void tls_hmac ( struct tls_session *tls __unused,
1062 		       struct tls_cipherspec *cipherspec,
1063 		       uint64_t seq, struct tls_header *tlshdr,
1064 		       const void *data, size_t len, void *hmac ) {
1065 	struct digest_algorithm *digest = cipherspec->digest;
1066 	uint8_t digest_ctx[digest->ctxsize];
1067 
1068 	hmac_init ( digest, digest_ctx, cipherspec->mac_secret,
1069 		    &digest->digestsize );
1070 	seq = cpu_to_be64 ( seq );
1071 	hmac_update ( digest, digest_ctx, &seq, sizeof ( seq ) );
1072 	hmac_update ( digest, digest_ctx, tlshdr, sizeof ( *tlshdr ) );
1073 	hmac_update ( digest, digest_ctx, data, len );
1074 	hmac_final ( digest, digest_ctx, cipherspec->mac_secret,
1075 		     &digest->digestsize, hmac );
1076 }
1077 
1078 /**
1079  * Allocate and assemble stream-ciphered record from data and MAC portions
1080  *
1081  * @v tls		TLS session
1082  * @ret data		Data
1083  * @ret len		Length of data
1084  * @ret digest		MAC digest
1085  * @ret plaintext_len	Length of plaintext record
1086  * @ret plaintext	Allocated plaintext record
1087  */
tls_assemble_stream(struct tls_session * tls,const void * data,size_t len,void * digest,size_t * plaintext_len)1088 static void * __malloc tls_assemble_stream ( struct tls_session *tls,
1089 				    const void *data, size_t len,
1090 				    void *digest, size_t *plaintext_len ) {
1091 	size_t mac_len = tls->tx_cipherspec.digest->digestsize;
1092 	void *plaintext;
1093 	void *content;
1094 	void *mac;
1095 
1096 	/* Calculate stream-ciphered struct length */
1097 	*plaintext_len = ( len + mac_len );
1098 
1099 	/* Allocate stream-ciphered struct */
1100 	plaintext = malloc ( *plaintext_len );
1101 	if ( ! plaintext )
1102 		return NULL;
1103 	content = plaintext;
1104 	mac = ( content + len );
1105 
1106 	/* Fill in stream-ciphered struct */
1107 	memcpy ( content, data, len );
1108 	memcpy ( mac, digest, mac_len );
1109 
1110 	return plaintext;
1111 }
1112 
1113 /**
1114  * Allocate and assemble block-ciphered record from data and MAC portions
1115  *
1116  * @v tls		TLS session
1117  * @ret data		Data
1118  * @ret len		Length of data
1119  * @ret digest		MAC digest
1120  * @ret plaintext_len	Length of plaintext record
1121  * @ret plaintext	Allocated plaintext record
1122  */
tls_assemble_block(struct tls_session * tls,const void * data,size_t len,void * digest,size_t * plaintext_len)1123 static void * tls_assemble_block ( struct tls_session *tls,
1124 				   const void *data, size_t len,
1125 				   void *digest, size_t *plaintext_len ) {
1126 	size_t blocksize = tls->tx_cipherspec.cipher->blocksize;
1127 	size_t iv_len = blocksize;
1128 	size_t mac_len = tls->tx_cipherspec.digest->digestsize;
1129 	size_t padding_len;
1130 	void *plaintext;
1131 	void *iv;
1132 	void *content;
1133 	void *mac;
1134 	void *padding;
1135 
1136 	/* FIXME: TLSv1.1 has an explicit IV */
1137 	iv_len = 0;
1138 
1139 	/* Calculate block-ciphered struct length */
1140 	padding_len = ( ( blocksize - 1 ) & -( iv_len + len + mac_len + 1 ) );
1141 	*plaintext_len = ( iv_len + len + mac_len + padding_len + 1 );
1142 
1143 	/* Allocate block-ciphered struct */
1144 	plaintext = malloc ( *plaintext_len );
1145 	if ( ! plaintext )
1146 		return NULL;
1147 	iv = plaintext;
1148 	content = ( iv + iv_len );
1149 	mac = ( content + len );
1150 	padding = ( mac + mac_len );
1151 
1152 	/* Fill in block-ciphered struct */
1153 	memset ( iv, 0, iv_len );
1154 	memcpy ( content, data, len );
1155 	memcpy ( mac, digest, mac_len );
1156 	memset ( padding, padding_len, ( padding_len + 1 ) );
1157 
1158 	return plaintext;
1159 }
1160 
1161 /**
1162  * Send plaintext record
1163  *
1164  * @v tls		TLS session
1165  * @v type		Record type
1166  * @v data		Plaintext record
1167  * @v len		Length of plaintext record
1168  * @ret rc		Return status code
1169  */
tls_send_plaintext(struct tls_session * tls,unsigned int type,const void * data,size_t len)1170 static int tls_send_plaintext ( struct tls_session *tls, unsigned int type,
1171 				const void *data, size_t len ) {
1172 	struct tls_header plaintext_tlshdr;
1173 	struct tls_header *tlshdr;
1174 	struct tls_cipherspec *cipherspec = &tls->tx_cipherspec;
1175 	void *plaintext = NULL;
1176 	size_t plaintext_len;
1177 	struct io_buffer *ciphertext = NULL;
1178 	size_t ciphertext_len;
1179 	size_t mac_len = cipherspec->digest->digestsize;
1180 	uint8_t mac[mac_len];
1181 	int rc;
1182 
1183 	/* Construct header */
1184 	plaintext_tlshdr.type = type;
1185 	plaintext_tlshdr.version = htons ( TLS_VERSION_TLS_1_0 );
1186 	plaintext_tlshdr.length = htons ( len );
1187 
1188 	/* Calculate MAC */
1189 	tls_hmac ( tls, cipherspec, tls->tx_seq, &plaintext_tlshdr,
1190 		   data, len, mac );
1191 
1192 	/* Allocate and assemble plaintext struct */
1193 	if ( is_stream_cipher ( cipherspec->cipher ) ) {
1194 		plaintext = tls_assemble_stream ( tls, data, len, mac,
1195 						  &plaintext_len );
1196 	} else {
1197 		plaintext = tls_assemble_block ( tls, data, len, mac,
1198 						 &plaintext_len );
1199 	}
1200 	if ( ! plaintext ) {
1201 		DBGC ( tls, "TLS %p could not allocate %zd bytes for "
1202 		       "plaintext\n", tls, plaintext_len );
1203 		rc = -ENOMEM;
1204 		goto done;
1205 	}
1206 
1207 	DBGC2 ( tls, "Sending plaintext data:\n" );
1208 	DBGC2_HD ( tls, plaintext, plaintext_len );
1209 
1210 	/* Allocate ciphertext */
1211 	ciphertext_len = ( sizeof ( *tlshdr ) + plaintext_len );
1212 	ciphertext = xfer_alloc_iob ( &tls->cipherstream.xfer,
1213 				      ciphertext_len );
1214 	if ( ! ciphertext ) {
1215 		DBGC ( tls, "TLS %p could not allocate %zd bytes for "
1216 		       "ciphertext\n", tls, ciphertext_len );
1217 		rc = -ENOMEM;
1218 		goto done;
1219 	}
1220 
1221 	/* Assemble ciphertext */
1222 	tlshdr = iob_put ( ciphertext, sizeof ( *tlshdr ) );
1223 	tlshdr->type = type;
1224 	tlshdr->version = htons ( TLS_VERSION_TLS_1_0 );
1225 	tlshdr->length = htons ( plaintext_len );
1226 	memcpy ( cipherspec->cipher_next_ctx, cipherspec->cipher_ctx,
1227 		 cipherspec->cipher->ctxsize );
1228 	cipher_encrypt ( cipherspec->cipher, cipherspec->cipher_next_ctx,
1229 			 plaintext, iob_put ( ciphertext, plaintext_len ),
1230 			 plaintext_len );
1231 
1232 	/* Free plaintext as soon as possible to conserve memory */
1233 	free ( plaintext );
1234 	plaintext = NULL;
1235 
1236 	/* Send ciphertext */
1237 	rc = xfer_deliver_iob ( &tls->cipherstream.xfer, ciphertext );
1238 	ciphertext = NULL;
1239 	if ( rc != 0 ) {
1240 		DBGC ( tls, "TLS %p could not deliver ciphertext: %s\n",
1241 		       tls, strerror ( rc ) );
1242 		goto done;
1243 	}
1244 
1245 	/* Update TX state machine to next record */
1246 	tls->tx_seq += 1;
1247 	memcpy ( tls->tx_cipherspec.cipher_ctx,
1248 		 tls->tx_cipherspec.cipher_next_ctx,
1249 		 tls->tx_cipherspec.cipher->ctxsize );
1250 
1251  done:
1252 	free ( plaintext );
1253 	free_iob ( ciphertext );
1254 	return rc;
1255 }
1256 
1257 /**
1258  * Split stream-ciphered record into data and MAC portions
1259  *
1260  * @v tls		TLS session
1261  * @v plaintext		Plaintext record
1262  * @v plaintext_len	Length of record
1263  * @ret data		Data
1264  * @ret len		Length of data
1265  * @ret digest		MAC digest
1266  * @ret rc		Return status code
1267  */
tls_split_stream(struct tls_session * tls,void * plaintext,size_t plaintext_len,void ** data,size_t * len,void ** digest)1268 static int tls_split_stream ( struct tls_session *tls,
1269 			      void *plaintext, size_t plaintext_len,
1270 			      void **data, size_t *len, void **digest ) {
1271 	void *content;
1272 	size_t content_len;
1273 	void *mac;
1274 	size_t mac_len;
1275 
1276 	/* Decompose stream-ciphered data */
1277 	mac_len = tls->rx_cipherspec.digest->digestsize;
1278 	if ( plaintext_len < mac_len ) {
1279 		DBGC ( tls, "TLS %p received underlength record\n", tls );
1280 		DBGC_HD ( tls, plaintext, plaintext_len );
1281 		return -EINVAL;
1282 	}
1283 	content_len = ( plaintext_len - mac_len );
1284 	content = plaintext;
1285 	mac = ( content + content_len );
1286 
1287 	/* Fill in return values */
1288 	*data = content;
1289 	*len = content_len;
1290 	*digest = mac;
1291 
1292 	return 0;
1293 }
1294 
1295 /**
1296  * Split block-ciphered record into data and MAC portions
1297  *
1298  * @v tls		TLS session
1299  * @v plaintext		Plaintext record
1300  * @v plaintext_len	Length of record
1301  * @ret data		Data
1302  * @ret len		Length of data
1303  * @ret digest		MAC digest
1304  * @ret rc		Return status code
1305  */
tls_split_block(struct tls_session * tls,void * plaintext,size_t plaintext_len,void ** data,size_t * len,void ** digest)1306 static int tls_split_block ( struct tls_session *tls,
1307 			     void *plaintext, size_t plaintext_len,
1308 			     void **data, size_t *len,
1309 			     void **digest ) {
1310 	void *iv;
1311 	size_t iv_len;
1312 	void *content;
1313 	size_t content_len;
1314 	void *mac;
1315 	size_t mac_len;
1316 	void *padding;
1317 	size_t padding_len;
1318 	unsigned int i;
1319 
1320 	/* Decompose block-ciphered data */
1321 	if ( plaintext_len < 1 ) {
1322 		DBGC ( tls, "TLS %p received underlength record\n", tls );
1323 		DBGC_HD ( tls, plaintext, plaintext_len );
1324 		return -EINVAL;
1325 	}
1326 	iv_len = tls->rx_cipherspec.cipher->blocksize;
1327 
1328 	/* FIXME: TLSv1.1 uses an explicit IV */
1329 	iv_len = 0;
1330 
1331 	mac_len = tls->rx_cipherspec.digest->digestsize;
1332 	padding_len = *( ( uint8_t * ) ( plaintext + plaintext_len - 1 ) );
1333 	if ( plaintext_len < ( iv_len + mac_len + padding_len + 1 ) ) {
1334 		DBGC ( tls, "TLS %p received underlength record\n", tls );
1335 		DBGC_HD ( tls, plaintext, plaintext_len );
1336 		return -EINVAL;
1337 	}
1338 	content_len = ( plaintext_len - iv_len - mac_len - padding_len - 1 );
1339 	iv = plaintext;
1340 	content = ( iv + iv_len );
1341 	mac = ( content + content_len );
1342 	padding = ( mac + mac_len );
1343 
1344 	/* Verify padding bytes */
1345 	for ( i = 0 ; i < padding_len ; i++ ) {
1346 		if ( *( ( uint8_t * ) ( padding + i ) ) != padding_len ) {
1347 			DBGC ( tls, "TLS %p received bad padding\n", tls );
1348 			DBGC_HD ( tls, plaintext, plaintext_len );
1349 			return -EINVAL;
1350 		}
1351 	}
1352 
1353 	/* Fill in return values */
1354 	*data = content;
1355 	*len = content_len;
1356 	*digest = mac;
1357 
1358 	return 0;
1359 }
1360 
1361 /**
1362  * Receive new ciphertext record
1363  *
1364  * @v tls		TLS session
1365  * @v tlshdr		Record header
1366  * @v ciphertext	Ciphertext record
1367  * @ret rc		Return status code
1368  */
tls_new_ciphertext(struct tls_session * tls,struct tls_header * tlshdr,void * ciphertext)1369 static int tls_new_ciphertext ( struct tls_session *tls,
1370 				struct tls_header *tlshdr, void *ciphertext ) {
1371 	struct tls_header plaintext_tlshdr;
1372 	struct tls_cipherspec *cipherspec = &tls->rx_cipherspec;
1373 	size_t record_len = ntohs ( tlshdr->length );
1374 	void *plaintext = NULL;
1375 	void *data;
1376 	size_t len;
1377 	void *mac;
1378 	size_t mac_len = cipherspec->digest->digestsize;
1379 	uint8_t verify_mac[mac_len];
1380 	int rc;
1381 
1382 	/* Allocate buffer for plaintext */
1383 	plaintext = malloc ( record_len );
1384 	if ( ! plaintext ) {
1385 		DBGC ( tls, "TLS %p could not allocate %zd bytes for "
1386 		       "decryption buffer\n", tls, record_len );
1387 		rc = -ENOMEM;
1388 		goto done;
1389 	}
1390 
1391 	/* Decrypt the record */
1392 	cipher_decrypt ( cipherspec->cipher, cipherspec->cipher_ctx,
1393 			 ciphertext, plaintext, record_len );
1394 
1395 	/* Split record into content and MAC */
1396 	if ( is_stream_cipher ( cipherspec->cipher ) ) {
1397 		if ( ( rc = tls_split_stream ( tls, plaintext, record_len,
1398 					       &data, &len, &mac ) ) != 0 )
1399 			goto done;
1400 	} else {
1401 		if ( ( rc = tls_split_block ( tls, plaintext, record_len,
1402 					      &data, &len, &mac ) ) != 0 )
1403 			goto done;
1404 	}
1405 
1406 	/* Verify MAC */
1407 	plaintext_tlshdr.type = tlshdr->type;
1408 	plaintext_tlshdr.version = tlshdr->version;
1409 	plaintext_tlshdr.length = htons ( len );
1410 	tls_hmac ( tls, cipherspec, tls->rx_seq, &plaintext_tlshdr,
1411 		   data, len, verify_mac);
1412 	if ( memcmp ( mac, verify_mac, mac_len ) != 0 ) {
1413 		DBGC ( tls, "TLS %p failed MAC verification\n", tls );
1414 		DBGC_HD ( tls, plaintext, record_len );
1415 		goto done;
1416 	}
1417 
1418 	DBGC2 ( tls, "Received plaintext data:\n" );
1419 	DBGC2_HD ( tls, data, len );
1420 
1421 	/* Process plaintext record */
1422 	if ( ( rc = tls_new_record ( tls, tlshdr->type, data, len ) ) != 0 )
1423 		goto done;
1424 
1425 	rc = 0;
1426  done:
1427 	free ( plaintext );
1428 	return rc;
1429 }
1430 
1431 /******************************************************************************
1432  *
1433  * Plaintext stream operations
1434  *
1435  ******************************************************************************
1436  */
1437 
1438 /**
1439  * Close interface
1440  *
1441  * @v xfer		Plainstream data transfer interface
1442  * @v rc		Reason for close
1443  */
tls_plainstream_close(struct xfer_interface * xfer,int rc)1444 static void tls_plainstream_close ( struct xfer_interface *xfer, int rc ) {
1445 	struct tls_session *tls =
1446 		container_of ( xfer, struct tls_session, plainstream.xfer );
1447 
1448 	tls_close ( tls, rc );
1449 }
1450 
1451 /**
1452  * Check flow control window
1453  *
1454  * @v xfer		Plainstream data transfer interface
1455  * @ret len		Length of window
1456  */
tls_plainstream_window(struct xfer_interface * xfer)1457 static size_t tls_plainstream_window ( struct xfer_interface *xfer ) {
1458 	struct tls_session *tls =
1459 		container_of ( xfer, struct tls_session, plainstream.xfer );
1460 
1461 	/* Block window unless we are ready to accept data */
1462 	if ( tls->tx_state != TLS_TX_DATA )
1463 		return 0;
1464 
1465 	return filter_window ( xfer );
1466 }
1467 
1468 /**
1469  * Deliver datagram as raw data
1470  *
1471  * @v xfer		Plainstream data transfer interface
1472  * @v data		Data buffer
1473  * @v len		Length of data buffer
1474  * @ret rc		Return status code
1475  */
tls_plainstream_deliver_raw(struct xfer_interface * xfer,const void * data,size_t len)1476 static int tls_plainstream_deliver_raw ( struct xfer_interface *xfer,
1477 					 const void *data, size_t len ) {
1478 	struct tls_session *tls =
1479 		container_of ( xfer, struct tls_session, plainstream.xfer );
1480 
1481 	/* Refuse unless we are ready to accept data */
1482 	if ( tls->tx_state != TLS_TX_DATA )
1483 		return -ENOTCONN;
1484 
1485 	return tls_send_plaintext ( tls, TLS_TYPE_DATA, data, len );
1486 }
1487 
1488 /** TLS plaintext stream operations */
1489 static struct xfer_interface_operations tls_plainstream_operations = {
1490 	.close		= tls_plainstream_close,
1491 	.vredirect	= ignore_xfer_vredirect,
1492 	.window		= tls_plainstream_window,
1493 	.alloc_iob	= default_xfer_alloc_iob,
1494 	.deliver_iob	= xfer_deliver_as_raw,
1495 	.deliver_raw	= tls_plainstream_deliver_raw,
1496 };
1497 
1498 /******************************************************************************
1499  *
1500  * Ciphertext stream operations
1501  *
1502  ******************************************************************************
1503  */
1504 
1505 /**
1506  * Close interface
1507  *
1508  * @v xfer		Plainstream data transfer interface
1509  * @v rc		Reason for close
1510  */
tls_cipherstream_close(struct xfer_interface * xfer,int rc)1511 static void tls_cipherstream_close ( struct xfer_interface *xfer, int rc ) {
1512 	struct tls_session *tls =
1513 		container_of ( xfer, struct tls_session, cipherstream.xfer );
1514 
1515 	tls_close ( tls, rc );
1516 }
1517 
1518 /**
1519  * Handle received TLS header
1520  *
1521  * @v tls		TLS session
1522  * @ret rc		Returned status code
1523  */
tls_newdata_process_header(struct tls_session * tls)1524 static int tls_newdata_process_header ( struct tls_session *tls ) {
1525 	size_t data_len = ntohs ( tls->rx_header.length );
1526 
1527 	/* Allocate data buffer now that we know the length */
1528 	assert ( tls->rx_data == NULL );
1529 	tls->rx_data = malloc ( data_len );
1530 	if ( ! tls->rx_data ) {
1531 		DBGC ( tls, "TLS %p could not allocate %zd bytes "
1532 		       "for receive buffer\n", tls, data_len );
1533 		return -ENOMEM;
1534 	}
1535 
1536 	/* Move to data state */
1537 	tls->rx_state = TLS_RX_DATA;
1538 
1539 	return 0;
1540 }
1541 
1542 /**
1543  * Handle received TLS data payload
1544  *
1545  * @v tls		TLS session
1546  * @ret rc		Returned status code
1547  */
tls_newdata_process_data(struct tls_session * tls)1548 static int tls_newdata_process_data ( struct tls_session *tls ) {
1549 	int rc;
1550 
1551 	/* Process record */
1552 	if ( ( rc = tls_new_ciphertext ( tls, &tls->rx_header,
1553 					 tls->rx_data ) ) != 0 )
1554 		return rc;
1555 
1556 	/* Increment RX sequence number */
1557 	tls->rx_seq += 1;
1558 
1559 	/* Free data buffer */
1560 	free ( tls->rx_data );
1561 	tls->rx_data = NULL;
1562 
1563 	/* Return to header state */
1564 	tls->rx_state = TLS_RX_HEADER;
1565 
1566 	return 0;
1567 }
1568 
1569 /**
1570  * Receive new ciphertext
1571  *
1572  * @v app		Stream application
1573  * @v data		Data received
1574  * @v len		Length of received data
1575  * @ret rc		Return status code
1576  */
tls_cipherstream_deliver_raw(struct xfer_interface * xfer,const void * data,size_t len)1577 static int tls_cipherstream_deliver_raw ( struct xfer_interface *xfer,
1578 					  const void *data, size_t len ) {
1579 	struct tls_session *tls =
1580 		container_of ( xfer, struct tls_session, cipherstream.xfer );
1581 	size_t frag_len;
1582 	void *buf;
1583 	size_t buf_len;
1584 	int ( * process ) ( struct tls_session *tls );
1585 	int rc;
1586 
1587 	while ( len ) {
1588 		/* Select buffer according to current state */
1589 		switch ( tls->rx_state ) {
1590 		case TLS_RX_HEADER:
1591 			buf = &tls->rx_header;
1592 			buf_len = sizeof ( tls->rx_header );
1593 			process = tls_newdata_process_header;
1594 			break;
1595 		case TLS_RX_DATA:
1596 			buf = tls->rx_data;
1597 			buf_len = ntohs ( tls->rx_header.length );
1598 			process = tls_newdata_process_data;
1599 			break;
1600 		default:
1601 			assert ( 0 );
1602 			return -EINVAL;
1603 		}
1604 
1605 		/* Copy data portion to buffer */
1606 		frag_len = ( buf_len - tls->rx_rcvd );
1607 		if ( frag_len > len )
1608 			frag_len = len;
1609 		memcpy ( ( buf + tls->rx_rcvd ), data, frag_len );
1610 		tls->rx_rcvd += frag_len;
1611 		data += frag_len;
1612 		len -= frag_len;
1613 
1614 		/* Process data if buffer is now full */
1615 		if ( tls->rx_rcvd == buf_len ) {
1616 			if ( ( rc = process ( tls ) ) != 0 ) {
1617 				tls_close ( tls, rc );
1618 				return rc;
1619 			}
1620 			tls->rx_rcvd = 0;
1621 		}
1622 	}
1623 
1624 	return 0;
1625 }
1626 
1627 /** TLS ciphertext stream operations */
1628 static struct xfer_interface_operations tls_cipherstream_operations = {
1629 	.close		= tls_cipherstream_close,
1630 	.vredirect	= xfer_vreopen,
1631 	.window		= filter_window,
1632 	.alloc_iob	= default_xfer_alloc_iob,
1633 	.deliver_iob	= xfer_deliver_as_raw,
1634 	.deliver_raw	= tls_cipherstream_deliver_raw,
1635 };
1636 
1637 /******************************************************************************
1638  *
1639  * Controlling process
1640  *
1641  ******************************************************************************
1642  */
1643 
1644 /**
1645  * TLS TX state machine
1646  *
1647  * @v process		TLS process
1648  */
tls_step(struct process * process)1649 static void tls_step ( struct process *process ) {
1650 	struct tls_session *tls =
1651 		container_of ( process, struct tls_session, process );
1652 	int rc;
1653 
1654 	/* Wait for cipherstream to become ready */
1655 	if ( ! xfer_window ( &tls->cipherstream.xfer ) )
1656 		return;
1657 
1658 	switch ( tls->tx_state ) {
1659 	case TLS_TX_NONE:
1660 		/* Nothing to do */
1661 		break;
1662 	case TLS_TX_CLIENT_HELLO:
1663 		/* Send Client Hello */
1664 		if ( ( rc = tls_send_client_hello ( tls ) ) != 0 ) {
1665 			DBGC ( tls, "TLS %p could not send Client Hello: %s\n",
1666 			       tls, strerror ( rc ) );
1667 			goto err;
1668 		}
1669 		tls->tx_state = TLS_TX_NONE;
1670 		break;
1671 	case TLS_TX_CLIENT_KEY_EXCHANGE:
1672 		/* Send Client Key Exchange */
1673 		if ( ( rc = tls_send_client_key_exchange ( tls ) ) != 0 ) {
1674 			DBGC ( tls, "TLS %p could send Client Key Exchange: "
1675 			       "%s\n", tls, strerror ( rc ) );
1676 			goto err;
1677 		}
1678 		tls->tx_state = TLS_TX_CHANGE_CIPHER;
1679 		break;
1680 	case TLS_TX_CHANGE_CIPHER:
1681 		/* Send Change Cipher, and then change the cipher in use */
1682 		if ( ( rc = tls_send_change_cipher ( tls ) ) != 0 ) {
1683 			DBGC ( tls, "TLS %p could not send Change Cipher: "
1684 			       "%s\n", tls, strerror ( rc ) );
1685 			goto err;
1686 		}
1687 		if ( ( rc = tls_change_cipher ( tls,
1688 						&tls->tx_cipherspec_pending,
1689 						&tls->tx_cipherspec )) != 0 ){
1690 			DBGC ( tls, "TLS %p could not activate TX cipher: "
1691 			       "%s\n", tls, strerror ( rc ) );
1692 			goto err;
1693 		}
1694 		tls->tx_seq = 0;
1695 		tls->tx_state = TLS_TX_FINISHED;
1696 		break;
1697 	case TLS_TX_FINISHED:
1698 		/* Send Finished */
1699 		if ( ( rc = tls_send_finished ( tls ) ) != 0 ) {
1700 			DBGC ( tls, "TLS %p could not send Finished: %s\n",
1701 			       tls, strerror ( rc ) );
1702 			goto err;
1703 		}
1704 		tls->tx_state = TLS_TX_NONE;
1705 		break;
1706 	case TLS_TX_DATA:
1707 		/* Nothing to do */
1708 		break;
1709 	default:
1710 		assert ( 0 );
1711 	}
1712 
1713 	return;
1714 
1715  err:
1716 	tls_close ( tls, rc );
1717 }
1718 
1719 /******************************************************************************
1720  *
1721  * Instantiator
1722  *
1723  ******************************************************************************
1724  */
1725 
add_tls(struct xfer_interface * xfer,struct xfer_interface ** next)1726 int add_tls ( struct xfer_interface *xfer, struct xfer_interface **next ) {
1727 	struct tls_session *tls;
1728 
1729 	/* Allocate and initialise TLS structure */
1730 	tls = malloc ( sizeof ( *tls ) );
1731 	if ( ! tls )
1732 		return -ENOMEM;
1733 	memset ( tls, 0, sizeof ( *tls ) );
1734 	tls->refcnt.free = free_tls;
1735 	filter_init ( &tls->plainstream, &tls_plainstream_operations,
1736 		      &tls->cipherstream, &tls_cipherstream_operations,
1737 		      &tls->refcnt );
1738 	tls_clear_cipher ( tls, &tls->tx_cipherspec );
1739 	tls_clear_cipher ( tls, &tls->tx_cipherspec_pending );
1740 	tls_clear_cipher ( tls, &tls->rx_cipherspec );
1741 	tls_clear_cipher ( tls, &tls->rx_cipherspec_pending );
1742 	tls->client_random.gmt_unix_time = 0;
1743 	tls_generate_random ( &tls->client_random.random,
1744 			      ( sizeof ( tls->client_random.random ) ) );
1745 	tls->pre_master_secret.version = htons ( TLS_VERSION_TLS_1_0 );
1746 	tls_generate_random ( &tls->pre_master_secret.random,
1747 			      ( sizeof ( tls->pre_master_secret.random ) ) );
1748 	digest_init ( &md5_algorithm, tls->handshake_md5_ctx );
1749 	digest_init ( &sha1_algorithm, tls->handshake_sha1_ctx );
1750 	tls->tx_state = TLS_TX_CLIENT_HELLO;
1751 	process_init ( &tls->process, tls_step, &tls->refcnt );
1752 
1753 	/* Attach to parent interface, mortalise self, and return */
1754 	xfer_plug_plug ( &tls->plainstream.xfer, xfer );
1755 	*next = &tls->cipherstream.xfer;
1756 	ref_put ( &tls->refcnt );
1757 	return 0;
1758 }
1759 
1760