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