2 * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
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.
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.
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.
19 FILE_LICENCE ( GPL2_OR_LATER
);
24 * Transport Layer Security Protocol
33 #include <gpxe/hmac.h>
35 #include <gpxe/sha1.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>
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
);
50 /******************************************************************************
54 ******************************************************************************
58 * Extract 24-bit field value
60 * @v field24 24-bit field
61 * @ret value Field value
63 * TLS uses 24-bit integers in several places, which are awkward to
66 static unsigned long tls_uint24 ( uint8_t field24
[3] ) {
67 return ( ( field24
[0] << 16 ) + ( field24
[1] << 8 ) + field24
[2] );
70 /******************************************************************************
74 ******************************************************************************
80 * @v refcnt Reference counter
82 static void free_tls ( struct refcnt
*refcnt
) {
83 struct tls_session
*tls
=
84 container_of ( refcnt
, struct tls_session
, refcnt
);
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
);
94 /* Free TLS structure itself */
99 * Finish with TLS session
104 static void tls_close ( struct tls_session
*tls
, int rc
) {
107 process_del ( &tls
->process
);
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
);
116 /******************************************************************************
118 * Random number generation
120 ******************************************************************************
124 * Generate random data
126 * @v data Buffer to fill
127 * @v len Length of buffer
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
);
135 * Update HMAC with a list of ( data, len ) pairs
137 * @v digest Hash function to use
138 * @v digest_ctx Digest context
139 * @v args ( data, len ) pairs of data, terminated by NULL
141 static void tls_hmac_update_va ( struct digest_algorithm
*digest
,
142 void *digest_ctx
, va_list args
) {
146 while ( ( data
= va_arg ( args
, void * ) ) ) {
147 len
= va_arg ( args
, size_t );
148 hmac_update ( digest
, digest_ctx
, data
, len
);
153 * Generate secure pseudo-random data using a single hash function
156 * @v digest Hash function to use
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
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
,
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
;
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
);
183 hmac_init ( digest
, digest_ctx
, secret
, &secret_len
);
184 va_copy ( tmp
, seeds
);
185 tls_hmac_update_va ( digest
, digest_ctx
, 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
) );
191 /* Generate as much data as required */
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
);
200 hmac_final ( digest
, digest_ctx
,
201 secret
, &secret_len
, out_tmp
);
204 if ( 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
);
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
) );
222 * Generate secure pseudo-random data
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
231 static void tls_prf ( struct tls_session
*tls
, void *secret
, size_t secret_len
,
232 void *out
, size_t out_len
, ... ) {
235 size_t subsecret_len
;
238 uint8_t out_md5
[out_len
];
239 uint8_t out_sha1
[out_len
];
242 va_start ( seeds
, out_len
);
244 /* Split secret into two, with an overlap of up to one byte */
245 subsecret_len
= ( ( secret_len
+ 1 ) / 2 );
247 sha1_secret
= ( secret
+ secret_len
- subsecret_len
);
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
);
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
);
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
] );
270 * Generate secure pseudo-random data
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
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 )
283 /******************************************************************************
287 ******************************************************************************
291 * Generate master secret
295 * The pre-master secret and the client and server random values must
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
) );
307 tls_prf_label ( tls
, &tls
->pre_master_secret
,
308 sizeof ( tls
->pre_master_secret
),
309 &tls
->master_secret
, sizeof ( tls
->master_secret
),
311 &tls
->client_random
, sizeof ( tls
->client_random
),
312 &tls
->server_random
, sizeof ( tls
->server_random
) );
314 DBGC ( tls
, "TLS %p generated master secret:\n", tls
);
315 DBGC_HD ( tls
, &tls
->master_secret
, sizeof ( tls
->master_secret
) );
319 * Generate key material
323 * The master secret must already be known.
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
];
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
) );
342 /* Split key block into portions */
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
);
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
);
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
) );
365 DBGC ( tls
, "TLS %p TX key:\n", tls
);
366 DBGC_HD ( tls
, key
, key_size
);
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
) );
377 DBGC ( tls
, "TLS %p RX key:\n", tls
);
378 DBGC_HD ( tls
, key
, key_size
);
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
);
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
);
393 assert ( ( key_block
+ total
) == key
);
398 /******************************************************************************
400 * Cipher suite management
402 ******************************************************************************
408 * @v cipherspec TLS cipher specification
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
;
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
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
,
439 /* Clear out old cipher contents, if any */
440 tls_clear_cipher ( tls
, cipherspec
);
442 /* Allocate dynamic storage */
443 total
= ( pubkey
->ctxsize
+ 2 * cipher
->ctxsize
+ digest
->digestsize
);
444 dynamic
= malloc ( total
);
446 DBGC ( tls
, "TLS %p could not allocate %zd bytes for crypto "
447 "context\n", tls
, total
);
450 memset ( dynamic
, 0, total
);
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
);
460 /* Store parameters */
461 cipherspec
->pubkey
= pubkey
;
462 cipherspec
->cipher
= cipher
;
463 cipherspec
->digest
= digest
;
464 cipherspec
->key_len
= key_len
;
470 * Select next cipher suite
473 * @v cipher_suite Cipher suite specification
474 * @ret rc Return status code
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;
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
;
490 case htons ( TLS_RSA_WITH_AES_256_CBC_SHA
):
491 key_len
= ( 256 / 8 );
492 cipher
= &aes_cbc_algorithm
;
493 digest
= &sha1_algorithm
;
496 DBGC ( tls
, "TLS %p does not support cipher %04x\n",
497 tls
, ntohs ( cipher_suite
) );
502 if ( ( rc
= tls_set_cipher ( tls
, &tls
->tx_cipherspec_pending
, pubkey
,
503 cipher
, digest
, key_len
) ) != 0 )
505 if ( ( rc
= tls_set_cipher ( tls
, &tls
->rx_cipherspec_pending
, pubkey
,
506 cipher
, digest
, key_len
) ) != 0 )
509 DBGC ( tls
, "TLS %p selected %s-%s-%d-%s\n", tls
,
510 pubkey
->name
, cipher
->name
, ( key_len
* 8 ), digest
->name
);
516 * Activate next cipher suite
519 * @v pending Pending cipher specification
520 * @v active Active cipher specification to replace
521 * @ret rc Return status code
523 static int tls_change_cipher ( struct tls_session
*tls
,
524 struct tls_cipherspec
*pending
,
525 struct tls_cipherspec
*active
) {
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
);
536 tls_clear_cipher ( tls
, active
);
537 memswap ( active
, pending
, sizeof ( *active
) );
541 /******************************************************************************
543 * Handshake verification
545 ******************************************************************************
549 * Add handshake record to verification hash
552 * @v data Handshake record
553 * @v len Length of handshake record
555 static void tls_add_handshake ( struct tls_session
*tls
,
556 const void *data
, size_t len
) {
558 digest_update ( &md5_algorithm
, tls
->handshake_md5_ctx
, data
, len
);
559 digest_update ( &sha1_algorithm
, tls
->handshake_sha1_ctx
, data
, len
);
563 * Calculate handshake verification hash
566 * @v out Output buffer
568 * Calculates the MD5+SHA1 digest over all handshake messages seen so
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
);
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
);
585 /******************************************************************************
589 ******************************************************************************
593 * Transmit Handshake record
596 * @v data Plaintext record
597 * @v len Length of plaintext record
598 * @ret rc Return status code
600 static int tls_send_handshake ( struct tls_session
*tls
,
601 void *data
, size_t len
) {
603 /* Add to handshake digest */
604 tls_add_handshake ( tls
, data
, len
);
607 return tls_send_plaintext ( tls
, TLS_TYPE_HANDSHAKE
, data
, len
);
611 * Transmit Client Hello record
614 * @ret rc Return status code
616 static int tls_send_client_hello ( struct tls_session
*tls
) {
618 uint32_t type_length
;
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
;
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
);
639 return tls_send_handshake ( tls
, &hello
, sizeof ( hello
) );
643 * Transmit Client Key Exchange record
646 * @ret rc Return status code
648 static int tls_send_client_key_exchange ( struct tls_session
*tls
) {
649 /* FIXME: Hack alert */
651 RSA_pub_key_new ( &rsa_ctx
, tls
->rsa
.modulus
, tls
->rsa
.modulus_len
,
652 tls
->rsa
.exponent
, tls
->rsa
.exponent_len
);
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
;
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
) );
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
);
681 return tls_send_handshake ( tls
, &key_xchg
, sizeof ( key_xchg
) );
685 * Transmit Change Cipher record
688 * @ret rc Return status code
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
) );
697 * Transmit Finished record
700 * @ret rc Return status code
702 static int tls_send_finished ( struct tls_session
*tls
) {
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
];
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
) );
718 return tls_send_handshake ( tls
, &finished
, sizeof ( finished
) );
722 * Receive new Change Cipher record
725 * @v data Plaintext record
726 * @v len Length of plaintext record
727 * @ret rc Return status code
729 static int tls_new_change_cipher ( struct tls_session
*tls
,
730 void *data
, size_t len
) {
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
);
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
) );
745 tls
->rx_seq
= ~( ( uint64_t ) 0 );
751 * Receive new Alert record
754 * @v data Plaintext record
755 * @v len Length of plaintext record
756 * @ret rc Return status code
758 static int tls_new_alert ( struct tls_session
*tls
, void *data
, size_t len
) {
763 } __attribute__ (( packed
)) *alert
= data
;
764 void *end
= alert
->next
;
767 if ( end
!= ( data
+ len
) ) {
768 DBGC ( tls
, "TLS %p received overlength Alert\n", tls
);
769 DBGC_HD ( tls
, data
, len
);
773 switch ( alert
->level
) {
774 case TLS_ALERT_WARNING
:
775 DBGC ( tls
, "TLS %p received warning alert %d\n",
776 tls
, alert
->description
);
778 case TLS_ALERT_FATAL
:
779 DBGC ( tls
, "TLS %p received fatal alert %d\n",
780 tls
, alert
->description
);
783 DBGC ( tls
, "TLS %p received unknown alert level %d"
784 "(alert %d)\n", tls
, alert
->level
, alert
->description
);
790 * Receive new Server Hello handshake record
793 * @v data Plaintext handshake record
794 * @v len Length of plaintext handshake record
795 * @ret rc Return status code
797 static int tls_new_server_hello ( struct tls_session
*tls
,
798 void *data
, size_t len
) {
802 uint8_t session_id_len
;
804 } __attribute__ (( packed
)) *hello_a
= data
;
806 uint8_t session_id
[hello_a
->session_id_len
];
807 uint16_t cipher_suite
;
808 uint8_t compression_method
;
810 } __attribute__ (( packed
)) *hello_b
= ( void * ) &hello_a
->next
;
811 void *end
= hello_b
->next
;
815 if ( end
!= ( data
+ len
) ) {
816 DBGC ( tls
, "TLS %p received overlength Server Hello\n", tls
);
817 DBGC_HD ( tls
, data
, len
);
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 ) );
829 /* Copy out server random bytes */
830 memcpy ( &tls
->server_random
, &hello_a
->random
,
831 sizeof ( tls
->server_random
) );
833 /* Select cipher suite */
834 if ( ( rc
= tls_select_cipher ( tls
, hello_b
->cipher_suite
) ) != 0 )
837 /* Generate secrets */
838 tls_generate_master_secret ( tls
);
839 if ( ( rc
= tls_generate_keys ( tls
) ) != 0 )
846 * Receive new Certificate handshake record
849 * @v data Plaintext handshake record
850 * @v len Length of plaintext handshake record
851 * @ret rc Return status code
853 static int tls_new_certificate ( struct tls_session
*tls
,
854 void *data
, size_t len
) {
857 uint8_t certificates
[0];
858 } __attribute__ (( packed
)) *certificate
= data
;
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
;
870 if ( end
!= ( data
+ len
) ) {
871 DBGC ( tls
, "TLS %p received overlength Server Certificate\n",
873 DBGC_HD ( tls
, data
, len
);
877 /* Traverse certificate chain */
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
);
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
) );
897 element
= ( cursor
.data
+ cursor
.len
);
898 } while ( element
!= end
);
904 * Receive new Server Hello Done handshake record
907 * @v data Plaintext handshake record
908 * @v len Length of plaintext handshake record
909 * @ret rc Return status code
911 static int tls_new_server_hello_done ( struct tls_session
*tls
,
912 void *data
, size_t len
) {
915 } __attribute__ (( packed
)) *hello_done
= data
;
916 void *end
= hello_done
->next
;
919 if ( end
!= ( data
+ len
) ) {
920 DBGC ( tls
, "TLS %p received overlength Server Hello Done\n",
922 DBGC_HD ( tls
, data
, len
);
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
);
933 /* Start sending the Client Key Exchange */
934 tls
->tx_state
= TLS_TX_CLIENT_KEY_EXCHANGE
;
940 * Receive new Finished handshake record
943 * @v data Plaintext handshake record
944 * @v len Length of plaintext handshake record
945 * @ret rc Return status code
947 static int tls_new_finished ( struct tls_session
*tls
,
948 void *data
, size_t len
) {
950 /* FIXME: Handle this properly */
951 tls
->tx_state
= TLS_TX_DATA
;
958 * Receive new Handshake record
961 * @v data Plaintext record
962 * @v len Length of plaintext record
963 * @ret rc Return status code
965 static int tls_new_handshake ( struct tls_session
*tls
,
966 void *data
, size_t len
) {
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
);
978 if ( end
!= ( data
+ len
) ) {
979 DBGC ( tls
, "TLS %p received overlength Handshake\n", tls
);
980 DBGC_HD ( tls
, data
, len
);
984 switch ( handshake
->type
) {
985 case TLS_SERVER_HELLO
:
986 rc
= tls_new_server_hello ( tls
, payload
, payload_len
);
988 case TLS_CERTIFICATE
:
989 rc
= tls_new_certificate ( tls
, payload
, payload_len
);
991 case TLS_SERVER_HELLO_DONE
:
992 rc
= tls_new_server_hello_done ( tls
, payload
, payload_len
);
995 rc
= tls_new_finished ( tls
, payload
, payload_len
);
998 DBGC ( tls
, "TLS %p ignoring handshake type %d\n",
999 tls
, handshake
->type
);
1004 /* Add to handshake digest (except for Hello Requests, which
1005 * are explicitly excluded).
1007 if ( handshake
->type
!= TLS_HELLO_REQUEST
)
1008 tls_add_handshake ( tls
, data
, len
);
1014 * Receive new record
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
1022 static int tls_new_record ( struct tls_session
*tls
,
1023 unsigned int type
, void *data
, size_t len
) {
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
);
1033 return xfer_deliver_raw ( &tls
->plainstream
.xfer
, data
, len
);
1035 /* RFC4346 says that we should just ignore unknown
1038 DBGC ( tls
, "TLS %p ignoring record type %d\n", tls
, type
);
1043 /******************************************************************************
1045 * Record encryption/decryption
1047 ******************************************************************************
1053 * @v tls TLS session
1054 * @v cipherspec Cipher specification
1055 * @v seq Sequence number
1056 * @v tlshdr TLS header
1058 * @v len Length of data
1059 * @v mac HMAC to fill in
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
];
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
);
1079 * Allocate and assemble stream-ciphered record from data and MAC portions
1081 * @v tls TLS session
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
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
;
1096 /* Calculate stream-ciphered struct length */
1097 *plaintext_len
= ( len
+ mac_len
);
1099 /* Allocate stream-ciphered struct */
1100 plaintext
= malloc ( *plaintext_len
);
1103 content
= plaintext
;
1104 mac
= ( content
+ len
);
1106 /* Fill in stream-ciphered struct */
1107 memcpy ( content
, data
, len
);
1108 memcpy ( mac
, digest
, mac_len
);
1114 * Allocate and assemble block-ciphered record from data and MAC portions
1116 * @v tls TLS session
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
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
;
1136 /* FIXME: TLSv1.1 has an explicit IV */
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 );
1143 /* Allocate block-ciphered struct */
1144 plaintext
= malloc ( *plaintext_len
);
1148 content
= ( iv
+ iv_len
);
1149 mac
= ( content
+ len
);
1150 padding
= ( mac
+ mac_len
);
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 ) );
1162 * Send plaintext record
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
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
];
1183 /* Construct header */
1184 plaintext_tlshdr
.type
= type
;
1185 plaintext_tlshdr
.version
= htons ( TLS_VERSION_TLS_1_0
);
1186 plaintext_tlshdr
.length
= htons ( len
);
1189 tls_hmac ( tls
, cipherspec
, tls
->tx_seq
, &plaintext_tlshdr
,
1192 /* Allocate and assemble plaintext struct */
1193 if ( is_stream_cipher ( cipherspec
->cipher
) ) {
1194 plaintext
= tls_assemble_stream ( tls
, data
, len
, mac
,
1197 plaintext
= tls_assemble_block ( tls
, data
, len
, mac
,
1200 if ( ! plaintext
) {
1201 DBGC ( tls
, "TLS %p could not allocate %zd bytes for "
1202 "plaintext\n", tls
, plaintext_len
);
1207 DBGC2 ( tls
, "Sending plaintext data:\n" );
1208 DBGC2_HD ( tls
, plaintext
, plaintext_len
);
1210 /* Allocate ciphertext */
1211 ciphertext_len
= ( sizeof ( *tlshdr
) + plaintext_len
);
1212 ciphertext
= xfer_alloc_iob ( &tls
->cipherstream
.xfer
,
1214 if ( ! ciphertext
) {
1215 DBGC ( tls
, "TLS %p could not allocate %zd bytes for "
1216 "ciphertext\n", tls
, ciphertext_len
);
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
),
1232 /* Free plaintext as soon as possible to conserve memory */
1236 /* Send ciphertext */
1237 rc
= xfer_deliver_iob ( &tls
->cipherstream
.xfer
, ciphertext
);
1240 DBGC ( tls
, "TLS %p could not deliver ciphertext: %s\n",
1241 tls
, strerror ( rc
) );
1245 /* Update TX state machine to next record */
1247 memcpy ( tls
->tx_cipherspec
.cipher_ctx
,
1248 tls
->tx_cipherspec
.cipher_next_ctx
,
1249 tls
->tx_cipherspec
.cipher
->ctxsize
);
1253 free_iob ( ciphertext
);
1258 * Split stream-ciphered record into data and MAC portions
1260 * @v tls TLS session
1261 * @v plaintext Plaintext record
1262 * @v plaintext_len Length of record
1264 * @ret len Length of data
1265 * @ret digest MAC digest
1266 * @ret rc Return status code
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
) {
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
);
1283 content_len
= ( plaintext_len
- mac_len
);
1284 content
= plaintext
;
1285 mac
= ( content
+ content_len
);
1287 /* Fill in return values */
1296 * Split block-ciphered record into data and MAC portions
1298 * @v tls TLS session
1299 * @v plaintext Plaintext record
1300 * @v plaintext_len Length of record
1302 * @ret len Length of data
1303 * @ret digest MAC digest
1304 * @ret rc Return status code
1306 static int tls_split_block ( struct tls_session
*tls
,
1307 void *plaintext
, size_t plaintext_len
,
1308 void **data
, size_t *len
,
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
);
1326 iv_len
= tls
->rx_cipherspec
.cipher
->blocksize
;
1328 /* FIXME: TLSv1.1 uses an explicit IV */
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
);
1338 content_len
= ( plaintext_len
- iv_len
- mac_len
- padding_len
- 1 );
1340 content
= ( iv
+ iv_len
);
1341 mac
= ( content
+ content_len
);
1342 padding
= ( mac
+ mac_len
);
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
);
1353 /* Fill in return values */
1362 * Receive new ciphertext record
1364 * @v tls TLS session
1365 * @v tlshdr Record header
1366 * @v ciphertext Ciphertext record
1367 * @ret rc Return status code
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
;
1378 size_t mac_len
= cipherspec
->digest
->digestsize
;
1379 uint8_t verify_mac
[mac_len
];
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
);
1391 /* Decrypt the record */
1392 cipher_decrypt ( cipherspec
->cipher
, cipherspec
->cipher_ctx
,
1393 ciphertext
, plaintext
, record_len
);
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 )
1401 if ( ( rc
= tls_split_block ( tls
, plaintext
, record_len
,
1402 &data
, &len
, &mac
) ) != 0 )
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
);
1418 DBGC2 ( tls
, "Received plaintext data:\n" );
1419 DBGC2_HD ( tls
, data
, len
);
1421 /* Process plaintext record */
1422 if ( ( rc
= tls_new_record ( tls
, tlshdr
->type
, data
, len
) ) != 0 )
1431 /******************************************************************************
1433 * Plaintext stream operations
1435 ******************************************************************************
1441 * @v xfer Plainstream data transfer interface
1442 * @v rc Reason for close
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
);
1448 tls_close ( tls
, rc
);
1452 * Check flow control window
1454 * @v xfer Plainstream data transfer interface
1455 * @ret len Length of window
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
);
1461 /* Block window unless we are ready to accept data */
1462 if ( tls
->tx_state
!= TLS_TX_DATA
)
1465 return filter_window ( xfer
);
1469 * Deliver datagram as raw data
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
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
);
1481 /* Refuse unless we are ready to accept data */
1482 if ( tls
->tx_state
!= TLS_TX_DATA
)
1485 return tls_send_plaintext ( tls
, TLS_TYPE_DATA
, data
, len
);
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
,
1498 /******************************************************************************
1500 * Ciphertext stream operations
1502 ******************************************************************************
1508 * @v xfer Plainstream data transfer interface
1509 * @v rc Reason for close
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
);
1515 tls_close ( tls
, rc
);
1519 * Handle received TLS header
1521 * @v tls TLS session
1522 * @ret rc Returned status code
1524 static int tls_newdata_process_header ( struct tls_session
*tls
) {
1525 size_t data_len
= ntohs ( tls
->rx_header
.length
);
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
);
1536 /* Move to data state */
1537 tls
->rx_state
= TLS_RX_DATA
;
1543 * Handle received TLS data payload
1545 * @v tls TLS session
1546 * @ret rc Returned status code
1548 static int tls_newdata_process_data ( struct tls_session
*tls
) {
1551 /* Process record */
1552 if ( ( rc
= tls_new_ciphertext ( tls
, &tls
->rx_header
,
1553 tls
->rx_data
) ) != 0 )
1556 /* Increment RX sequence number */
1559 /* Free data buffer */
1560 free ( tls
->rx_data
);
1561 tls
->rx_data
= NULL
;
1563 /* Return to header state */
1564 tls
->rx_state
= TLS_RX_HEADER
;
1570 * Receive new ciphertext
1572 * @v app Stream application
1573 * @v data Data received
1574 * @v len Length of received data
1575 * @ret rc Return status code
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
);
1584 int ( * process
) ( struct tls_session
*tls
);
1588 /* Select buffer according to current state */
1589 switch ( tls
->rx_state
) {
1591 buf
= &tls
->rx_header
;
1592 buf_len
= sizeof ( tls
->rx_header
);
1593 process
= tls_newdata_process_header
;
1597 buf_len
= ntohs ( tls
->rx_header
.length
);
1598 process
= tls_newdata_process_data
;
1605 /* Copy data portion to buffer */
1606 frag_len
= ( buf_len
- tls
->rx_rcvd
);
1607 if ( frag_len
> len
)
1609 memcpy ( ( buf
+ tls
->rx_rcvd
), data
, frag_len
);
1610 tls
->rx_rcvd
+= frag_len
;
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
);
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
,
1637 /******************************************************************************
1639 * Controlling process
1641 ******************************************************************************
1645 * TLS TX state machine
1647 * @v process TLS process
1649 static void tls_step ( struct process
*process
) {
1650 struct tls_session
*tls
=
1651 container_of ( process
, struct tls_session
, process
);
1654 /* Wait for cipherstream to become ready */
1655 if ( ! xfer_window ( &tls
->cipherstream
.xfer
) )
1658 switch ( tls
->tx_state
) {
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
) );
1669 tls
->tx_state
= TLS_TX_NONE
;
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
) );
1678 tls
->tx_state
= TLS_TX_CHANGE_CIPHER
;
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
) );
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
) );
1695 tls
->tx_state
= TLS_TX_FINISHED
;
1697 case TLS_TX_FINISHED
:
1699 if ( ( rc
= tls_send_finished ( tls
) ) != 0 ) {
1700 DBGC ( tls
, "TLS %p could not send Finished: %s\n",
1701 tls
, strerror ( rc
) );
1704 tls
->tx_state
= TLS_TX_NONE
;
1716 tls_close ( tls
, rc
);
1719 /******************************************************************************
1723 ******************************************************************************
1726 int add_tls ( struct xfer_interface
*xfer
, struct xfer_interface
**next
) {
1727 struct tls_session
*tls
;
1729 /* Allocate and initialise TLS structure */
1730 tls
= malloc ( sizeof ( *tls
) );
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
,
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
);
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
);