Annotation of qemu/roms/ipxe/src/net/tls.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.