[tls] Handle multiple handshake records
[people/pcmattman/gpxe.git] / src / net / tls.c
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
965 static int tls_new_handshake ( struct tls_session *tls,
966                                void *data, size_t len ) {
967         void *end = ( data + len );
968         int rc;
969
970         while ( data != end ) {
971                 struct {
972                         uint8_t type;
973                         uint8_t length[3];
974                         uint8_t payload[0];
975                 } __attribute__ (( packed )) *handshake = data;
976                 void *payload = &handshake->payload;
977                 size_t payload_len = tls_uint24 ( handshake->length );
978                 void *next = ( payload + payload_len );
979
980                 /* Sanity check */
981                 if ( next > end ) {
982                         DBGC ( tls, "TLS %p received overlength Handshake\n",
983                                tls );
984                         DBGC_HD ( tls, data, len );
985                         return -EINVAL;
986                 }
987
988                 switch ( handshake->type ) {
989                 case TLS_SERVER_HELLO:
990                         rc = tls_new_server_hello ( tls, payload, payload_len );
991                         break;
992                 case TLS_CERTIFICATE:
993                         rc = tls_new_certificate ( tls, payload, payload_len );
994                         break;
995                 case TLS_SERVER_HELLO_DONE:
996                         rc = tls_new_server_hello_done ( tls, payload,
997                                                          payload_len );
998                         break;
999                 case TLS_FINISHED:
1000                         rc = tls_new_finished ( tls, payload, payload_len );
1001                         break;
1002                 default:
1003                         DBGC ( tls, "TLS %p ignoring handshake type %d\n",
1004                                tls, handshake->type );
1005                         rc = 0;
1006                         break;
1007                 }
1008
1009                 /* Add to handshake digest (except for Hello Requests,
1010                  * which are explicitly excluded).
1011                  */
1012                 if ( handshake->type != TLS_HELLO_REQUEST )
1013                         tls_add_handshake ( tls, data,
1014                                             sizeof ( *handshake ) +
1015                                             payload_len );
1016
1017                 /* Abort on failure */
1018                 if ( rc != 0 )
1019                         return rc;
1020
1021                 /* Move to next handshake record */
1022                 data = next;
1023         }
1024
1025         return 0;
1026 }
1027
1028 /**
1029  * Receive new record
1030  *
1031  * @v tls               TLS session
1032  * @v type              Record type
1033  * @v data              Plaintext record
1034  * @v len               Length of plaintext record
1035  * @ret rc              Return status code
1036  */
1037 static int tls_new_record ( struct tls_session *tls,
1038                             unsigned int type, void *data, size_t len ) {
1039
1040         switch ( type ) {
1041         case TLS_TYPE_CHANGE_CIPHER:
1042                 return tls_new_change_cipher ( tls, data, len );
1043         case TLS_TYPE_ALERT:
1044                 return tls_new_alert ( tls, data, len );
1045         case TLS_TYPE_HANDSHAKE:
1046                 return tls_new_handshake ( tls, data, len );
1047         case TLS_TYPE_DATA:
1048                 return xfer_deliver_raw ( &tls->plainstream.xfer, data, len );
1049         default:
1050                 /* RFC4346 says that we should just ignore unknown
1051                  * record types.
1052                  */
1053                 DBGC ( tls, "TLS %p ignoring record type %d\n", tls, type );
1054                 return 0;
1055         }
1056 }
1057
1058 /******************************************************************************
1059  *
1060  * Record encryption/decryption
1061  *
1062  ******************************************************************************
1063  */
1064
1065 /**
1066  * Calculate HMAC
1067  *
1068  * @v tls               TLS session
1069  * @v cipherspec        Cipher specification
1070  * @v seq               Sequence number
1071  * @v tlshdr            TLS header
1072  * @v data              Data
1073  * @v len               Length of data
1074  * @v mac               HMAC to fill in
1075  */
1076 static void tls_hmac ( struct tls_session *tls __unused,
1077                        struct tls_cipherspec *cipherspec,
1078                        uint64_t seq, struct tls_header *tlshdr,
1079                        const void *data, size_t len, void *hmac ) {
1080         struct digest_algorithm *digest = cipherspec->digest;
1081         uint8_t digest_ctx[digest->ctxsize];
1082
1083         hmac_init ( digest, digest_ctx, cipherspec->mac_secret,
1084                     &digest->digestsize );
1085         seq = cpu_to_be64 ( seq );
1086         hmac_update ( digest, digest_ctx, &seq, sizeof ( seq ) );
1087         hmac_update ( digest, digest_ctx, tlshdr, sizeof ( *tlshdr ) );
1088         hmac_update ( digest, digest_ctx, data, len );
1089         hmac_final ( digest, digest_ctx, cipherspec->mac_secret,
1090                      &digest->digestsize, hmac );
1091 }
1092
1093 /**
1094  * Allocate and assemble stream-ciphered record from data and MAC portions
1095  *
1096  * @v tls               TLS session
1097  * @ret data            Data
1098  * @ret len             Length of data
1099  * @ret digest          MAC digest
1100  * @ret plaintext_len   Length of plaintext record
1101  * @ret plaintext       Allocated plaintext record
1102  */
1103 static void * __malloc tls_assemble_stream ( struct tls_session *tls,
1104                                     const void *data, size_t len,
1105                                     void *digest, size_t *plaintext_len ) {
1106         size_t mac_len = tls->tx_cipherspec.digest->digestsize;
1107         void *plaintext;
1108         void *content;
1109         void *mac;
1110
1111         /* Calculate stream-ciphered struct length */
1112         *plaintext_len = ( len + mac_len );
1113
1114         /* Allocate stream-ciphered struct */
1115         plaintext = malloc ( *plaintext_len );
1116         if ( ! plaintext )
1117                 return NULL;
1118         content = plaintext;
1119         mac = ( content + len );
1120
1121         /* Fill in stream-ciphered struct */
1122         memcpy ( content, data, len );
1123         memcpy ( mac, digest, mac_len );
1124
1125         return plaintext;
1126 }
1127
1128 /**
1129  * Allocate and assemble block-ciphered record from data and MAC portions
1130  *
1131  * @v tls               TLS session
1132  * @ret data            Data
1133  * @ret len             Length of data
1134  * @ret digest          MAC digest
1135  * @ret plaintext_len   Length of plaintext record
1136  * @ret plaintext       Allocated plaintext record
1137  */
1138 static void * tls_assemble_block ( struct tls_session *tls,
1139                                    const void *data, size_t len,
1140                                    void *digest, size_t *plaintext_len ) {
1141         size_t blocksize = tls->tx_cipherspec.cipher->blocksize;
1142         size_t iv_len = blocksize;
1143         size_t mac_len = tls->tx_cipherspec.digest->digestsize;
1144         size_t padding_len;
1145         void *plaintext;
1146         void *iv;
1147         void *content;
1148         void *mac;
1149         void *padding;
1150
1151         /* FIXME: TLSv1.1 has an explicit IV */
1152         iv_len = 0;
1153
1154         /* Calculate block-ciphered struct length */
1155         padding_len = ( ( blocksize - 1 ) & -( iv_len + len + mac_len + 1 ) );
1156         *plaintext_len = ( iv_len + len + mac_len + padding_len + 1 );
1157
1158         /* Allocate block-ciphered struct */
1159         plaintext = malloc ( *plaintext_len );
1160         if ( ! plaintext )
1161                 return NULL;
1162         iv = plaintext;
1163         content = ( iv + iv_len );
1164         mac = ( content + len );
1165         padding = ( mac + mac_len );
1166
1167         /* Fill in block-ciphered struct */
1168         memset ( iv, 0, iv_len );
1169         memcpy ( content, data, len );
1170         memcpy ( mac, digest, mac_len );
1171         memset ( padding, padding_len, ( padding_len + 1 ) );
1172
1173         return plaintext;
1174 }
1175
1176 /**
1177  * Send plaintext record
1178  *
1179  * @v tls               TLS session
1180  * @v type              Record type
1181  * @v data              Plaintext record
1182  * @v len               Length of plaintext record
1183  * @ret rc              Return status code
1184  */
1185 static int tls_send_plaintext ( struct tls_session *tls, unsigned int type,
1186                                 const void *data, size_t len ) {
1187         struct tls_header plaintext_tlshdr;
1188         struct tls_header *tlshdr;
1189         struct tls_cipherspec *cipherspec = &tls->tx_cipherspec;
1190         void *plaintext = NULL;
1191         size_t plaintext_len;
1192         struct io_buffer *ciphertext = NULL;
1193         size_t ciphertext_len;
1194         size_t mac_len = cipherspec->digest->digestsize;
1195         uint8_t mac[mac_len];
1196         int rc;
1197
1198         /* Construct header */
1199         plaintext_tlshdr.type = type;
1200         plaintext_tlshdr.version = htons ( TLS_VERSION_TLS_1_0 );
1201         plaintext_tlshdr.length = htons ( len );
1202
1203         /* Calculate MAC */
1204         tls_hmac ( tls, cipherspec, tls->tx_seq, &plaintext_tlshdr,
1205                    data, len, mac );
1206
1207         /* Allocate and assemble plaintext struct */
1208         if ( is_stream_cipher ( cipherspec->cipher ) ) {
1209                 plaintext = tls_assemble_stream ( tls, data, len, mac,
1210                                                   &plaintext_len );
1211         } else {
1212                 plaintext = tls_assemble_block ( tls, data, len, mac,
1213                                                  &plaintext_len );
1214         }
1215         if ( ! plaintext ) {
1216                 DBGC ( tls, "TLS %p could not allocate %zd bytes for "
1217                        "plaintext\n", tls, plaintext_len );
1218                 rc = -ENOMEM;
1219                 goto done;
1220         }
1221
1222         DBGC2 ( tls, "Sending plaintext data:\n" );
1223         DBGC2_HD ( tls, plaintext, plaintext_len );
1224
1225         /* Allocate ciphertext */
1226         ciphertext_len = ( sizeof ( *tlshdr ) + plaintext_len );
1227         ciphertext = xfer_alloc_iob ( &tls->cipherstream.xfer,
1228                                       ciphertext_len );
1229         if ( ! ciphertext ) {
1230                 DBGC ( tls, "TLS %p could not allocate %zd bytes for "
1231                        "ciphertext\n", tls, ciphertext_len );
1232                 rc = -ENOMEM;
1233                 goto done;
1234         }
1235
1236         /* Assemble ciphertext */
1237         tlshdr = iob_put ( ciphertext, sizeof ( *tlshdr ) );
1238         tlshdr->type = type;
1239         tlshdr->version = htons ( TLS_VERSION_TLS_1_0 );
1240         tlshdr->length = htons ( plaintext_len );
1241         memcpy ( cipherspec->cipher_next_ctx, cipherspec->cipher_ctx,
1242                  cipherspec->cipher->ctxsize );
1243         cipher_encrypt ( cipherspec->cipher, cipherspec->cipher_next_ctx,
1244                          plaintext, iob_put ( ciphertext, plaintext_len ),
1245                          plaintext_len );
1246
1247         /* Free plaintext as soon as possible to conserve memory */
1248         free ( plaintext );
1249         plaintext = NULL;
1250
1251         /* Send ciphertext */
1252         rc = xfer_deliver_iob ( &tls->cipherstream.xfer, ciphertext );
1253         ciphertext = NULL;
1254         if ( rc != 0 ) {
1255                 DBGC ( tls, "TLS %p could not deliver ciphertext: %s\n",
1256                        tls, strerror ( rc ) );
1257                 goto done;
1258         }
1259
1260         /* Update TX state machine to next record */
1261         tls->tx_seq += 1;
1262         memcpy ( tls->tx_cipherspec.cipher_ctx,
1263                  tls->tx_cipherspec.cipher_next_ctx,
1264                  tls->tx_cipherspec.cipher->ctxsize );
1265
1266  done:
1267         free ( plaintext );
1268         free_iob ( ciphertext );
1269         return rc;
1270 }
1271
1272 /**
1273  * Split stream-ciphered record into data and MAC portions
1274  *
1275  * @v tls               TLS session
1276  * @v plaintext         Plaintext record
1277  * @v plaintext_len     Length of record
1278  * @ret data            Data
1279  * @ret len             Length of data
1280  * @ret digest          MAC digest
1281  * @ret rc              Return status code
1282  */
1283 static int tls_split_stream ( struct tls_session *tls,
1284                               void *plaintext, size_t plaintext_len,
1285                               void **data, size_t *len, void **digest ) {
1286         void *content;
1287         size_t content_len;
1288         void *mac;
1289         size_t mac_len;
1290
1291         /* Decompose stream-ciphered data */
1292         mac_len = tls->rx_cipherspec.digest->digestsize;
1293         if ( plaintext_len < mac_len ) {
1294                 DBGC ( tls, "TLS %p received underlength record\n", tls );
1295                 DBGC_HD ( tls, plaintext, plaintext_len );
1296                 return -EINVAL;
1297         }
1298         content_len = ( plaintext_len - mac_len );
1299         content = plaintext;
1300         mac = ( content + content_len );
1301
1302         /* Fill in return values */
1303         *data = content;
1304         *len = content_len;
1305         *digest = mac;
1306
1307         return 0;
1308 }
1309
1310 /**
1311  * Split block-ciphered record into data and MAC portions
1312  *
1313  * @v tls               TLS session
1314  * @v plaintext         Plaintext record
1315  * @v plaintext_len     Length of record
1316  * @ret data            Data
1317  * @ret len             Length of data
1318  * @ret digest          MAC digest
1319  * @ret rc              Return status code
1320  */
1321 static int tls_split_block ( struct tls_session *tls,
1322                              void *plaintext, size_t plaintext_len,
1323                              void **data, size_t *len,
1324                              void **digest ) {
1325         void *iv;
1326         size_t iv_len;
1327         void *content;
1328         size_t content_len;
1329         void *mac;
1330         size_t mac_len;
1331         void *padding;
1332         size_t padding_len;
1333         unsigned int i;
1334
1335         /* Decompose block-ciphered data */
1336         if ( plaintext_len < 1 ) {
1337                 DBGC ( tls, "TLS %p received underlength record\n", tls );
1338                 DBGC_HD ( tls, plaintext, plaintext_len );
1339                 return -EINVAL;
1340         }
1341         iv_len = tls->rx_cipherspec.cipher->blocksize;
1342
1343         /* FIXME: TLSv1.1 uses an explicit IV */
1344         iv_len = 0;
1345
1346         mac_len = tls->rx_cipherspec.digest->digestsize;
1347         padding_len = *( ( uint8_t * ) ( plaintext + plaintext_len - 1 ) );
1348         if ( plaintext_len < ( iv_len + mac_len + padding_len + 1 ) ) {
1349                 DBGC ( tls, "TLS %p received underlength record\n", tls );
1350                 DBGC_HD ( tls, plaintext, plaintext_len );
1351                 return -EINVAL;
1352         }
1353         content_len = ( plaintext_len - iv_len - mac_len - padding_len - 1 );
1354         iv = plaintext;
1355         content = ( iv + iv_len );
1356         mac = ( content + content_len );
1357         padding = ( mac + mac_len );
1358
1359         /* Verify padding bytes */
1360         for ( i = 0 ; i < padding_len ; i++ ) {
1361                 if ( *( ( uint8_t * ) ( padding + i ) ) != padding_len ) {
1362                         DBGC ( tls, "TLS %p received bad padding\n", tls );
1363                         DBGC_HD ( tls, plaintext, plaintext_len );
1364                         return -EINVAL;
1365                 }
1366         }
1367
1368         /* Fill in return values */
1369         *data = content;
1370         *len = content_len;
1371         *digest = mac;
1372
1373         return 0;
1374 }
1375
1376 /**
1377  * Receive new ciphertext record
1378  *
1379  * @v tls               TLS session
1380  * @v tlshdr            Record header
1381  * @v ciphertext        Ciphertext record
1382  * @ret rc              Return status code
1383  */
1384 static int tls_new_ciphertext ( struct tls_session *tls,
1385                                 struct tls_header *tlshdr, void *ciphertext ) {
1386         struct tls_header plaintext_tlshdr;
1387         struct tls_cipherspec *cipherspec = &tls->rx_cipherspec;
1388         size_t record_len = ntohs ( tlshdr->length );
1389         void *plaintext = NULL;
1390         void *data;
1391         size_t len;
1392         void *mac;
1393         size_t mac_len = cipherspec->digest->digestsize;
1394         uint8_t verify_mac[mac_len];
1395         int rc;
1396
1397         /* Allocate buffer for plaintext */
1398         plaintext = malloc ( record_len );
1399         if ( ! plaintext ) {
1400                 DBGC ( tls, "TLS %p could not allocate %zd bytes for "
1401                        "decryption buffer\n", tls, record_len );
1402                 rc = -ENOMEM;
1403                 goto done;
1404         }
1405
1406         /* Decrypt the record */
1407         cipher_decrypt ( cipherspec->cipher, cipherspec->cipher_ctx,
1408                          ciphertext, plaintext, record_len );
1409
1410         /* Split record into content and MAC */
1411         if ( is_stream_cipher ( cipherspec->cipher ) ) {
1412                 if ( ( rc = tls_split_stream ( tls, plaintext, record_len,
1413                                                &data, &len, &mac ) ) != 0 )
1414                         goto done;
1415         } else {
1416                 if ( ( rc = tls_split_block ( tls, plaintext, record_len,
1417                                               &data, &len, &mac ) ) != 0 )
1418                         goto done;
1419         }
1420
1421         /* Verify MAC */
1422         plaintext_tlshdr.type = tlshdr->type;
1423         plaintext_tlshdr.version = tlshdr->version;
1424         plaintext_tlshdr.length = htons ( len );
1425         tls_hmac ( tls, cipherspec, tls->rx_seq, &plaintext_tlshdr,
1426                    data, len, verify_mac);
1427         if ( memcmp ( mac, verify_mac, mac_len ) != 0 ) {
1428                 DBGC ( tls, "TLS %p failed MAC verification\n", tls );
1429                 DBGC_HD ( tls, plaintext, record_len );
1430                 goto done;
1431         }
1432
1433         DBGC2 ( tls, "Received plaintext data:\n" );
1434         DBGC2_HD ( tls, data, len );
1435
1436         /* Process plaintext record */
1437         if ( ( rc = tls_new_record ( tls, tlshdr->type, data, len ) ) != 0 )
1438                 goto done;
1439
1440         rc = 0;
1441  done:
1442         free ( plaintext );
1443         return rc;
1444 }
1445
1446 /******************************************************************************
1447  *
1448  * Plaintext stream operations
1449  *
1450  ******************************************************************************
1451  */
1452
1453 /**
1454  * Close interface
1455  *
1456  * @v xfer              Plainstream data transfer interface
1457  * @v rc                Reason for close
1458  */
1459 static void tls_plainstream_close ( struct xfer_interface *xfer, int rc ) {
1460         struct tls_session *tls =
1461                 container_of ( xfer, struct tls_session, plainstream.xfer );
1462
1463         tls_close ( tls, rc );
1464 }
1465
1466 /**
1467  * Check flow control window
1468  *
1469  * @v xfer              Plainstream data transfer interface
1470  * @ret len             Length of window
1471  */
1472 static size_t tls_plainstream_window ( struct xfer_interface *xfer ) {
1473         struct tls_session *tls =
1474                 container_of ( xfer, struct tls_session, plainstream.xfer );
1475
1476         /* Block window unless we are ready to accept data */
1477         if ( tls->tx_state != TLS_TX_DATA )
1478                 return 0;
1479
1480         return filter_window ( xfer );
1481 }
1482
1483 /**
1484  * Deliver datagram as raw data
1485  *
1486  * @v xfer              Plainstream data transfer interface
1487  * @v data              Data buffer
1488  * @v len               Length of data buffer
1489  * @ret rc              Return status code
1490  */
1491 static int tls_plainstream_deliver_raw ( struct xfer_interface *xfer,
1492                                          const void *data, size_t len ) {
1493         struct tls_session *tls =
1494                 container_of ( xfer, struct tls_session, plainstream.xfer );
1495         
1496         /* Refuse unless we are ready to accept data */
1497         if ( tls->tx_state != TLS_TX_DATA )
1498                 return -ENOTCONN;
1499
1500         return tls_send_plaintext ( tls, TLS_TYPE_DATA, data, len );
1501 }
1502
1503 /** TLS plaintext stream operations */
1504 static struct xfer_interface_operations tls_plainstream_operations = {
1505         .close          = tls_plainstream_close,
1506         .vredirect      = ignore_xfer_vredirect,
1507         .window         = tls_plainstream_window,
1508         .alloc_iob      = default_xfer_alloc_iob,
1509         .deliver_iob    = xfer_deliver_as_raw,
1510         .deliver_raw    = tls_plainstream_deliver_raw,
1511 };
1512
1513 /******************************************************************************
1514  *
1515  * Ciphertext stream operations
1516  *
1517  ******************************************************************************
1518  */
1519
1520 /**
1521  * Close interface
1522  *
1523  * @v xfer              Plainstream data transfer interface
1524  * @v rc                Reason for close
1525  */
1526 static void tls_cipherstream_close ( struct xfer_interface *xfer, int rc ) {
1527         struct tls_session *tls =
1528                 container_of ( xfer, struct tls_session, cipherstream.xfer );
1529
1530         tls_close ( tls, rc );
1531 }
1532
1533 /**
1534  * Handle received TLS header
1535  *
1536  * @v tls               TLS session
1537  * @ret rc              Returned status code
1538  */
1539 static int tls_newdata_process_header ( struct tls_session *tls ) {
1540         size_t data_len = ntohs ( tls->rx_header.length );
1541
1542         /* Allocate data buffer now that we know the length */
1543         assert ( tls->rx_data == NULL );
1544         tls->rx_data = malloc ( data_len );
1545         if ( ! tls->rx_data ) {
1546                 DBGC ( tls, "TLS %p could not allocate %zd bytes "
1547                        "for receive buffer\n", tls, data_len );
1548                 return -ENOMEM;
1549         }
1550
1551         /* Move to data state */
1552         tls->rx_state = TLS_RX_DATA;
1553
1554         return 0;
1555 }
1556
1557 /**
1558  * Handle received TLS data payload
1559  *
1560  * @v tls               TLS session
1561  * @ret rc              Returned status code
1562  */
1563 static int tls_newdata_process_data ( struct tls_session *tls ) {
1564         int rc;
1565
1566         /* Process record */
1567         if ( ( rc = tls_new_ciphertext ( tls, &tls->rx_header,
1568                                          tls->rx_data ) ) != 0 )
1569                 return rc;
1570
1571         /* Increment RX sequence number */
1572         tls->rx_seq += 1;
1573
1574         /* Free data buffer */
1575         free ( tls->rx_data );
1576         tls->rx_data = NULL;
1577
1578         /* Return to header state */
1579         tls->rx_state = TLS_RX_HEADER;
1580
1581         return 0;
1582 }
1583
1584 /**
1585  * Receive new ciphertext
1586  *
1587  * @v app               Stream application
1588  * @v data              Data received
1589  * @v len               Length of received data
1590  * @ret rc              Return status code
1591  */
1592 static int tls_cipherstream_deliver_raw ( struct xfer_interface *xfer,
1593                                           const void *data, size_t len ) {
1594         struct tls_session *tls = 
1595                 container_of ( xfer, struct tls_session, cipherstream.xfer );
1596         size_t frag_len;
1597         void *buf;
1598         size_t buf_len;
1599         int ( * process ) ( struct tls_session *tls );
1600         int rc;
1601
1602         while ( len ) {
1603                 /* Select buffer according to current state */
1604                 switch ( tls->rx_state ) {
1605                 case TLS_RX_HEADER:
1606                         buf = &tls->rx_header;
1607                         buf_len = sizeof ( tls->rx_header );
1608                         process = tls_newdata_process_header;
1609                         break;
1610                 case TLS_RX_DATA:
1611                         buf = tls->rx_data;
1612                         buf_len = ntohs ( tls->rx_header.length );
1613                         process = tls_newdata_process_data;
1614                         break;
1615                 default:
1616                         assert ( 0 );
1617                         return -EINVAL;
1618                 }
1619
1620                 /* Copy data portion to buffer */
1621                 frag_len = ( buf_len - tls->rx_rcvd );
1622                 if ( frag_len > len )
1623                         frag_len = len;
1624                 memcpy ( ( buf + tls->rx_rcvd ), data, frag_len );
1625                 tls->rx_rcvd += frag_len;
1626                 data += frag_len;
1627                 len -= frag_len;
1628
1629                 /* Process data if buffer is now full */
1630                 if ( tls->rx_rcvd == buf_len ) {
1631                         if ( ( rc = process ( tls ) ) != 0 ) {
1632                                 tls_close ( tls, rc );
1633                                 return rc;
1634                         }
1635                         tls->rx_rcvd = 0;
1636                 }
1637         }
1638
1639         return 0;
1640 }
1641
1642 /** TLS ciphertext stream operations */
1643 static struct xfer_interface_operations tls_cipherstream_operations = {
1644         .close          = tls_cipherstream_close,
1645         .vredirect      = xfer_vreopen,
1646         .window         = filter_window,
1647         .alloc_iob      = default_xfer_alloc_iob,
1648         .deliver_iob    = xfer_deliver_as_raw,
1649         .deliver_raw    = tls_cipherstream_deliver_raw,
1650 };
1651
1652 /******************************************************************************
1653  *
1654  * Controlling process
1655  *
1656  ******************************************************************************
1657  */
1658
1659 /**
1660  * TLS TX state machine
1661  *
1662  * @v process           TLS process
1663  */
1664 static void tls_step ( struct process *process ) {
1665         struct tls_session *tls =
1666                 container_of ( process, struct tls_session, process );
1667         int rc;
1668
1669         /* Wait for cipherstream to become ready */
1670         if ( ! xfer_window ( &tls->cipherstream.xfer ) )
1671                 return;
1672
1673         switch ( tls->tx_state ) {
1674         case TLS_TX_NONE:
1675                 /* Nothing to do */
1676                 break;
1677         case TLS_TX_CLIENT_HELLO:
1678                 /* Send Client Hello */
1679                 if ( ( rc = tls_send_client_hello ( tls ) ) != 0 ) {
1680                         DBGC ( tls, "TLS %p could not send Client Hello: %s\n",
1681                                tls, strerror ( rc ) );
1682                         goto err;
1683                 }
1684                 tls->tx_state = TLS_TX_NONE;
1685                 break;
1686         case TLS_TX_CLIENT_KEY_EXCHANGE:
1687                 /* Send Client Key Exchange */
1688                 if ( ( rc = tls_send_client_key_exchange ( tls ) ) != 0 ) {
1689                         DBGC ( tls, "TLS %p could send Client Key Exchange: "
1690                                "%s\n", tls, strerror ( rc ) );
1691                         goto err;
1692                 }
1693                 tls->tx_state = TLS_TX_CHANGE_CIPHER;
1694                 break;
1695         case TLS_TX_CHANGE_CIPHER:
1696                 /* Send Change Cipher, and then change the cipher in use */
1697                 if ( ( rc = tls_send_change_cipher ( tls ) ) != 0 ) {
1698                         DBGC ( tls, "TLS %p could not send Change Cipher: "
1699                                "%s\n", tls, strerror ( rc ) );
1700                         goto err;
1701                 }
1702                 if ( ( rc = tls_change_cipher ( tls,
1703                                                 &tls->tx_cipherspec_pending,
1704                                                 &tls->tx_cipherspec )) != 0 ){
1705                         DBGC ( tls, "TLS %p could not activate TX cipher: "
1706                                "%s\n", tls, strerror ( rc ) );
1707                         goto err;
1708                 }
1709                 tls->tx_seq = 0;
1710                 tls->tx_state = TLS_TX_FINISHED;
1711                 break;
1712         case TLS_TX_FINISHED:
1713                 /* Send Finished */
1714                 if ( ( rc = tls_send_finished ( tls ) ) != 0 ) {
1715                         DBGC ( tls, "TLS %p could not send Finished: %s\n",
1716                                tls, strerror ( rc ) );
1717                         goto err;
1718                 }
1719                 tls->tx_state = TLS_TX_NONE;
1720                 break;
1721         case TLS_TX_DATA:
1722                 /* Nothing to do */
1723                 break;
1724         default:
1725                 assert ( 0 );
1726         }
1727
1728         return;
1729
1730  err:
1731         tls_close ( tls, rc );
1732 }
1733
1734 /******************************************************************************
1735  *
1736  * Instantiator
1737  *
1738  ******************************************************************************
1739  */
1740
1741 int add_tls ( struct xfer_interface *xfer, struct xfer_interface **next ) {
1742         struct tls_session *tls;
1743
1744         /* Allocate and initialise TLS structure */
1745         tls = malloc ( sizeof ( *tls ) );
1746         if ( ! tls )
1747                 return -ENOMEM;
1748         memset ( tls, 0, sizeof ( *tls ) );
1749         tls->refcnt.free = free_tls;
1750         filter_init ( &tls->plainstream, &tls_plainstream_operations,
1751                       &tls->cipherstream, &tls_cipherstream_operations,
1752                       &tls->refcnt );
1753         tls_clear_cipher ( tls, &tls->tx_cipherspec );
1754         tls_clear_cipher ( tls, &tls->tx_cipherspec_pending );
1755         tls_clear_cipher ( tls, &tls->rx_cipherspec );
1756         tls_clear_cipher ( tls, &tls->rx_cipherspec_pending );
1757         tls->client_random.gmt_unix_time = 0;
1758         tls_generate_random ( &tls->client_random.random,
1759                               ( sizeof ( tls->client_random.random ) ) );
1760         tls->pre_master_secret.version = htons ( TLS_VERSION_TLS_1_0 );
1761         tls_generate_random ( &tls->pre_master_secret.random,
1762                               ( sizeof ( tls->pre_master_secret.random ) ) );
1763         digest_init ( &md5_algorithm, tls->handshake_md5_ctx );
1764         digest_init ( &sha1_algorithm, tls->handshake_sha1_ctx );
1765         tls->tx_state = TLS_TX_CLIENT_HELLO;
1766         process_init ( &tls->process, tls_step, &tls->refcnt );
1767
1768         /* Attach to parent interface, mortalise self, and return */
1769         xfer_plug_plug ( &tls->plainstream.xfer, xfer );
1770         *next = &tls->cipherstream.xfer;
1771         ref_put ( &tls->refcnt );
1772         return 0;
1773 }
1774