|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.