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