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