~ubuntu-branches/ubuntu/trusty/grub2/trusty

« back to all changes in this revision

Viewing changes to debian/grub-extras/disabled/gpxe/src/net/tls.c

  • Committer: Package Import Robot
  • Author(s): Colin Watson
  • Date: 2014-01-16 15:18:04 UTC
  • mfrom: (17.6.38 experimental)
  • Revision ID: package-import@ubuntu.com-20140116151804-3foouk7fpqcq3sxx
Tags: 2.02~beta2-2
* Convert patch handling to git-dpm.
* Add bi-endian support to ELF parser (Tomohiro B Berry).
* Adjust restore_mkdevicemap.patch to mark get_kfreebsd_version as static,
  to appease "gcc -Werror=missing-prototypes".
* Cherry-pick from upstream:
  - Change grub-macbless' manual page section to 8.
* Install grub-glue-efi, grub-macbless, grub-render-label, and
  grub-syslinux2cfg.
* grub-shell: Pass -no-pad to xorriso when building floppy images.

Show diffs side-by-side

added added

removed removed

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