X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=qemu%2Froms%2Fipxe%2Fsrc%2Fnet%2Ftls.c;fp=qemu%2Froms%2Fipxe%2Fsrc%2Fnet%2Ftls.c;h=db01fb2913b0ad661e5ed44d29ba4d11cc80ab3a;hb=437fd90c0250dee670290f9b714253671a990160;hp=30ccc932e69ac4efdd239df25996a417926cd017;hpb=5bbd6fe9b8bab2a93e548c5a53b032d1939eec05;p=kvmfornfv.git diff --git a/qemu/roms/ipxe/src/net/tls.c b/qemu/roms/ipxe/src/net/tls.c index 30ccc932e..db01fb291 100644 --- a/qemu/roms/ipxe/src/net/tls.c +++ b/qemu/roms/ipxe/src/net/tls.c @@ -179,20 +179,29 @@ static void tls_clear_cipher ( struct tls_session *tls, ****************************************************************************** */ +/** A TLS 24-bit integer + * + * TLS uses 24-bit integers in several places, which are awkward to + * parse in C. + */ +typedef struct { + /** High byte */ + uint8_t high; + /** Low word */ + uint16_t low; +} __attribute__ (( packed )) tls24_t; + /** * Extract 24-bit field value * * @v field24 24-bit field * @ret value Field value * - * TLS uses 24-bit integers in several places, which are awkward to - * parse in C. */ static inline __attribute__ (( always_inline )) unsigned long -tls_uint24 ( const uint8_t field24[3] ) { - const uint32_t *field32 __attribute__ (( may_alias )) = - ( ( const void * ) field24 ); - return ( be32_to_cpu ( *field32 ) >> 8 ); +tls_uint24 ( const tls24_t *field24 ) { + + return ( ( field24->high << 16 ) | be16_to_cpu ( field24->low ) ); } /** @@ -200,13 +209,11 @@ tls_uint24 ( const uint8_t field24[3] ) { * * @v field24 24-bit field * @v value Field value - * - * The field must be pre-zeroed. */ -static void tls_set_uint24 ( uint8_t field24[3], unsigned long value ) { - uint32_t *field32 __attribute__ (( may_alias )) = - ( ( void * ) field24 ); - *field32 |= cpu_to_be32 ( value << 8 ); +static void tls_set_uint24 ( tls24_t *field24, unsigned long value ) { + + field24->high = ( value >> 16 ); + field24->low = cpu_to_be16 ( value ); } /** @@ -659,41 +666,8 @@ struct tls_cipher_suite tls_cipher_suite_null = { .digest = &digest_null, }; -/** Supported cipher suites, in order of preference */ -struct tls_cipher_suite tls_cipher_suites[] = { - { - .code = htons ( TLS_RSA_WITH_AES_256_CBC_SHA256 ), - .key_len = ( 256 / 8 ), - .pubkey = &rsa_algorithm, - .cipher = &aes_cbc_algorithm, - .digest = &sha256_algorithm, - }, - { - .code = htons ( TLS_RSA_WITH_AES_128_CBC_SHA256 ), - .key_len = ( 128 / 8 ), - .pubkey = &rsa_algorithm, - .cipher = &aes_cbc_algorithm, - .digest = &sha256_algorithm, - }, - { - .code = htons ( TLS_RSA_WITH_AES_256_CBC_SHA ), - .key_len = ( 256 / 8 ), - .pubkey = &rsa_algorithm, - .cipher = &aes_cbc_algorithm, - .digest = &sha1_algorithm, - }, - { - .code = htons ( TLS_RSA_WITH_AES_128_CBC_SHA ), - .key_len = ( 128 / 8 ), - .pubkey = &rsa_algorithm, - .cipher = &aes_cbc_algorithm, - .digest = &sha1_algorithm, - }, -}; - /** Number of supported cipher suites */ -#define TLS_NUM_CIPHER_SUITES \ - ( sizeof ( tls_cipher_suites ) / sizeof ( tls_cipher_suites[0] ) ) +#define TLS_NUM_CIPHER_SUITES table_num_entries ( TLS_CIPHER_SUITES ) /** * Identify cipher suite @@ -704,11 +678,9 @@ struct tls_cipher_suite tls_cipher_suites[] = { static struct tls_cipher_suite * tls_find_cipher_suite ( unsigned int cipher_suite ) { struct tls_cipher_suite *suite; - unsigned int i; /* Identify cipher suite */ - for ( i = 0 ; i < TLS_NUM_CIPHER_SUITES ; i++ ) { - suite = &tls_cipher_suites[i]; + for_each_table_entry ( suite, TLS_CIPHER_SUITES ) { if ( suite->code == cipher_suite ) return suite; } @@ -841,26 +813,9 @@ static int tls_change_cipher ( struct tls_session *tls, ****************************************************************************** */ -/** Supported signature and hash algorithms - * - * Note that the default (TLSv1.1 and earlier) algorithm using - * MD5+SHA1 is never explicitly specified. - */ -struct tls_signature_hash_algorithm tls_signature_hash_algorithms[] = { - { - .code = { - .signature = TLS_RSA_ALGORITHM, - .hash = TLS_SHA256_ALGORITHM, - }, - .pubkey = &rsa_algorithm, - .digest = &sha256_algorithm, - }, -}; - /** Number of supported signature and hash algorithms */ -#define TLS_NUM_SIG_HASH_ALGORITHMS \ - ( sizeof ( tls_signature_hash_algorithms ) / \ - sizeof ( tls_signature_hash_algorithms[0] ) ) +#define TLS_NUM_SIG_HASH_ALGORITHMS \ + table_num_entries ( TLS_SIG_HASH_ALGORITHMS ) /** * Find TLS signature and hash algorithm @@ -873,11 +828,9 @@ static struct tls_signature_hash_algorithm * tls_signature_hash_algorithm ( struct pubkey_algorithm *pubkey, struct digest_algorithm *digest ) { struct tls_signature_hash_algorithm *sig_hash; - unsigned int i; /* Identify signature and hash algorithm */ - for ( i = 0 ; i < TLS_NUM_SIG_HASH_ALGORITHMS ; i++ ) { - sig_hash = &tls_signature_hash_algorithms[i]; + for_each_table_entry ( sig_hash, TLS_SIG_HASH_ALGORITHMS ) { if ( ( sig_hash->pubkey == pubkey ) && ( sig_hash->digest == digest ) ) { return sig_hash; @@ -994,8 +947,17 @@ static int tls_send_client_hello ( struct tls_session *tls ) { struct { uint8_t max; } __attribute__ (( packed )) max_fragment_length; + uint16_t signature_algorithms_type; + uint16_t signature_algorithms_len; + struct { + uint16_t len; + struct tls_signature_hash_id + code[TLS_NUM_SIG_HASH_ALGORITHMS]; + } __attribute__ (( packed )) signature_algorithms; } __attribute__ (( packed )) extensions; } __attribute__ (( packed )) hello; + struct tls_cipher_suite *suite; + struct tls_signature_hash_algorithm *sighash; unsigned int i; memset ( &hello, 0, sizeof ( hello ) ); @@ -1005,8 +967,8 @@ static int tls_send_client_hello ( struct tls_session *tls ) { hello.version = htons ( tls->version ); memcpy ( &hello.random, &tls->client_random, sizeof ( hello.random ) ); hello.cipher_suite_len = htons ( sizeof ( hello.cipher_suites ) ); - for ( i = 0 ; i < TLS_NUM_CIPHER_SUITES ; i++ ) - hello.cipher_suites[i] = tls_cipher_suites[i].code; + i = 0 ; for_each_table_entry ( suite, TLS_CIPHER_SUITES ) + hello.cipher_suites[i++] = suite->code; hello.compression_methods_len = sizeof ( hello.compression_methods ); hello.extensions_len = htons ( sizeof ( hello.extensions ) ); hello.extensions.server_name_type = htons ( TLS_SERVER_NAME ); @@ -1025,6 +987,14 @@ static int tls_send_client_hello ( struct tls_session *tls ) { = htons ( sizeof ( hello.extensions.max_fragment_length ) ); hello.extensions.max_fragment_length.max = TLS_MAX_FRAGMENT_LENGTH_4096; + hello.extensions.signature_algorithms_type + = htons ( TLS_SIGNATURE_ALGORITHMS ); + hello.extensions.signature_algorithms_len + = htons ( sizeof ( hello.extensions.signature_algorithms ) ); + hello.extensions.signature_algorithms.len + = htons ( sizeof ( hello.extensions.signature_algorithms.code)); + i = 0 ; for_each_table_entry ( sighash, TLS_SIG_HASH_ALGORITHMS ) + hello.extensions.signature_algorithms.code[i++] = sighash->code; return tls_send_handshake ( tls, &hello, sizeof ( hello ) ); } @@ -1038,9 +1008,9 @@ static int tls_send_client_hello ( struct tls_session *tls ) { static int tls_send_certificate ( struct tls_session *tls ) { struct { uint32_t type_length; - uint8_t length[3]; + tls24_t length; struct { - uint8_t length[3]; + tls24_t length; uint8_t data[ tls->cert->raw.len ]; } __attribute__ (( packed )) certificates[1]; } __attribute__ (( packed )) *certificate; @@ -1058,9 +1028,9 @@ static int tls_send_certificate ( struct tls_session *tls ) { ( cpu_to_le32 ( TLS_CERTIFICATE ) | htonl ( sizeof ( *certificate ) - sizeof ( certificate->type_length ) ) ); - tls_set_uint24 ( certificate->length, + tls_set_uint24 ( &certificate->length, sizeof ( certificate->certificates ) ); - tls_set_uint24 ( certificate->certificates[0].length, + tls_set_uint24 ( &certificate->certificates[0].length, sizeof ( certificate->certificates[0].data ) ); memcpy ( certificate->certificates[0].data, tls->cert->raw.data, @@ -1412,7 +1382,7 @@ static int tls_parse_chain ( struct tls_session *tls, const void *data, size_t len ) { const void *end = ( data + len ); const struct { - uint8_t length[3]; + tls24_t length; uint8_t data[0]; } __attribute__ (( packed )) *certificate; size_t certificate_len; @@ -1436,7 +1406,7 @@ static int tls_parse_chain ( struct tls_session *tls, /* Extract raw certificate data */ certificate = data; - certificate_len = tls_uint24 ( certificate->length ); + certificate_len = tls_uint24 ( &certificate->length ); next = ( certificate->data + certificate_len ); if ( next > end ) { DBGC ( tls, "TLS %p overlength certificate:\n", tls ); @@ -1482,10 +1452,10 @@ static int tls_parse_chain ( struct tls_session *tls, static int tls_new_certificate ( struct tls_session *tls, const void *data, size_t len ) { const struct { - uint8_t length[3]; + tls24_t length; uint8_t certificates[0]; } __attribute__ (( packed )) *certificate = data; - size_t certificates_len = tls_uint24 ( certificate->length ); + size_t certificates_len = tls_uint24 ( &certificate->length ); const void *end = ( certificate->certificates + certificates_len ); int rc; @@ -1634,12 +1604,12 @@ static int tls_new_handshake ( struct tls_session *tls, while ( data != end ) { const struct { uint8_t type; - uint8_t length[3]; + tls24_t length; uint8_t payload[0]; } __attribute__ (( packed )) *handshake = data; - void *payload = &handshake->payload; - size_t payload_len = tls_uint24 ( handshake->length ); - void *next = ( payload + payload_len ); + const void *payload = &handshake->payload; + size_t payload_len = tls_uint24 ( &handshake->length ); + const void *next = ( payload + payload_len ); /* Sanity check */ if ( next > end ) { @@ -2637,3 +2607,9 @@ int add_tls ( struct interface *xfer, const char *name, err_alloc: return rc; } + +/* Drag in objects via add_tls() */ +REQUIRING_SYMBOL ( add_tls ); + +/* Drag in crypto configuration */ +REQUIRE_OBJECT ( config_crypto );