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