diff --git a/ChangeLog b/ChangeLog index 47b393782..8d88ccfd9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -16,6 +16,7 @@ Features * Added TLS 1.2 support * Added GCM suites to TLS 1.2 (RFC 5288) * Added commandline error code convertor (util/strerror) + * Added support for Hardware Acceleration hooking in SSL/TLS Changes * Removed redundant POLARSSL_DEBUG_MSG define diff --git a/include/polarssl/config.h b/include/polarssl/config.h index c65bcd823..a14e27124 100644 --- a/include/polarssl/config.h +++ b/include/polarssl/config.h @@ -228,6 +228,16 @@ */ #define POLARSSL_SELF_TEST +/** + * \def POLARSSL_SSL_HW_RECORD_ACCEL + * + * Enable hooking functions in SSL module for hardware acceleration of + * individual records. + * + * Uncomment this macro to enable hooking functions. +#define POLARSSL_SSL_HW_RECORD_ACCEL + */ + /** * \def POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION * diff --git a/include/polarssl/error.h b/include/polarssl/error.h index f3514df91..fb739b187 100644 --- a/include/polarssl/error.h +++ b/include/polarssl/error.h @@ -75,7 +75,8 @@ * RSA 4 9 * MD 5 4 * CIPHER 6 5 - * SSL 7 30 + * SSL 6 1 (Started from top) + * SSL 7 31 * * Module dependent error code (5 bits 0x.08.-0x.F8.) */ diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h index 4ac6f86c0..729e47c31 100644 --- a/include/polarssl/ssl.h +++ b/include/polarssl/ssl.h @@ -84,6 +84,8 @@ #define POLARSSL_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC -0x7E00 /**< Processing of the ChangeCipherSpec handshake message failed. */ #define POLARSSL_ERR_SSL_BAD_HS_FINISHED -0x7E80 /**< Processing of the Finished handshake message failed. */ #define POLARSSL_ERR_SSL_MALLOC_FAILED -0x7F00 /**< Memory allocation failed */ +#define POLARSSL_ERR_SSL_HW_ACCEL_FAILED -0x7F80 /**< Hardware acceleration function returned with error */ +#define POLARSSL_ERR_SSL_HW_ACCEL_FALLTHROUGH -0x6F80 /**< Hardware acceleration function skipped / left alone data */ /* * Various constants @@ -385,6 +387,17 @@ extern "C" { extern int ssl_default_ciphersuites[]; +#if defined(POLARSSL_SSL_HW_RECORD_ACCEL) +extern int (*ssl_hw_record_init)(ssl_context *ssl, + const unsigned char *key_enc, const unsigned char *key_dec, + const unsigned char *iv_enc, const unsigned char *iv_dec, + const unsigned char *mac_enc, const unsigned char *mac_dec); +extern int (*ssl_hw_record_reset)(ssl_context *ssl); +extern int (*ssl_hw_record_write)(ssl_context *ssl); +extern int (*ssl_hw_record_read)(ssl_context *ssl); +extern int (*ssl_hw_record_finish)(ssl_context *ssl); +#endif + /** * \brief Returns the list of ciphersuites supported by the SSL/TLS module. * diff --git a/library/error.c b/library/error.c index 61ff9c719..195a25506 100644 --- a/library/error.c +++ b/library/error.c @@ -169,7 +169,7 @@ void error_strerror( int ret, char *buf, size_t buflen ) if( use_ret == -(POLARSSL_ERR_DHM_READ_PUBLIC_FAILED) ) snprintf( buf, buflen, "DHM - Reading of the public values failed" ); if( use_ret == -(POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED) ) - snprintf( buf, buflen, "DHM - Makeing of the public value failed" ); + snprintf( buf, buflen, "DHM - Making of the public value failed" ); if( use_ret == -(POLARSSL_ERR_DHM_CALC_SECRET_FAILED) ) snprintf( buf, buflen, "DHM - Calculation of the DHM secret failed" ); #endif /* POLARSSL_DHM_C */ @@ -286,6 +286,10 @@ void error_strerror( int ret, char *buf, size_t buflen ) snprintf( buf, buflen, "SSL - Processing of the Finished handshake message failed" ); if( use_ret == -(POLARSSL_ERR_SSL_MALLOC_FAILED) ) snprintf( buf, buflen, "SSL - Memory allocation failed" ); + if( use_ret == -(POLARSSL_ERR_SSL_HW_ACCEL_FAILED) ) + snprintf( buf, buflen, "SSL - Hardware acceleration function returned with error" ); + if( use_ret == -(POLARSSL_ERR_SSL_HW_ACCEL_FALLTHROUGH) ) + snprintf( buf, buflen, "SSL - Hardware acceleration function skipped / left alone data" ); #endif /* POLARSSL_SSL_TLS_C */ #if defined(POLARSSL_X509_PARSE_C) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 88c6e55de..bbafcf35c 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -54,6 +54,17 @@ #define strcasecmp _stricmp #endif +#if defined(POLARSSL_SSL_HW_RECORD_ACCEL) +int (*ssl_hw_record_init)(ssl_context *ssl, + const unsigned char *key_enc, const unsigned char *key_dec, + const unsigned char *iv_enc, const unsigned char *iv_dec, + const unsigned char *mac_enc, const unsigned char *mac_dec) = NULL; +int (*ssl_hw_record_reset)(ssl_context *ssl) = NULL; +int (*ssl_hw_record_write)(ssl_context *ssl) = NULL; +int (*ssl_hw_record_read)(ssl_context *ssl) = NULL; +int (*ssl_hw_record_finish)(ssl_context *ssl) = NULL; +#endif + /* * Key material generation */ @@ -520,6 +531,23 @@ int ssl_derive_keys( ssl_context *ssl ) iv_copy_len ); } +#if defined(POLARSSL_SSL_HW_RECORD_ACCEL) + if( ssl_hw_record_init != NULL) + { + int ret = 0; + + SSL_DEBUG_MSG( 2, ( "going for ssl_hw_record_init()" ) ); + + if( ( ret = ssl_hw_record_init( ssl, key1, key2, ssl->iv_enc, + ssl->iv_dec, ssl->mac_enc, + ssl->mac_dec ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_hw_record_init", ret ); + return POLARSSL_ERR_SSL_HW_ACCEL_FAILED; + } + } +#endif + switch( ssl->session->ciphersuite ) { #if defined(POLARSSL_ARC4_C) @@ -1422,17 +1450,11 @@ int ssl_flush_output( ssl_context *ssl ) */ int ssl_write_record( ssl_context *ssl ) { - int ret; + int ret, done = 0; size_t len = ssl->out_msglen; SSL_DEBUG_MSG( 2, ( "=> write record" ) ); - ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype; - ssl->out_hdr[1] = (unsigned char) ssl->major_ver; - ssl->out_hdr[2] = (unsigned char) ssl->minor_ver; - ssl->out_hdr[3] = (unsigned char)( len >> 8 ); - ssl->out_hdr[4] = (unsigned char)( len ); - if( ssl->out_msgtype == SSL_MSG_HANDSHAKE ) { ssl->out_msg[1] = (unsigned char)( ( len - 4 ) >> 16 ); @@ -1442,29 +1464,52 @@ int ssl_write_record( ssl_context *ssl ) ssl->update_checksum( ssl, ssl->out_msg, len ); } - if( ssl->do_crypt != 0 ) +#if defined(POLARSSL_SSL_HW_RECORD_ACCEL) + if( ssl_hw_record_write != NULL) { - if( ( ret = ssl_encrypt_buf( ssl ) ) != 0 ) - { - SSL_DEBUG_RET( 1, "ssl_encrypt_buf", ret ); - return( ret ); - } + SSL_DEBUG_MSG( 2, ( "going for ssl_hw_record_write()" ) ); - len = ssl->out_msglen; + ret = ssl_hw_record_write( ssl ); + if( ret != 0 && ret != POLARSSL_ERR_SSL_HW_ACCEL_FALLTHROUGH ) + { + SSL_DEBUG_RET( 1, "ssl_hw_record_write", ret ); + return POLARSSL_ERR_SSL_HW_ACCEL_FAILED; + } + done = 1; + } +#endif + if( !done ) + { + ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype; + ssl->out_hdr[1] = (unsigned char) ssl->major_ver; + ssl->out_hdr[2] = (unsigned char) ssl->minor_ver; ssl->out_hdr[3] = (unsigned char)( len >> 8 ); ssl->out_hdr[4] = (unsigned char)( len ); + + if( ssl->do_crypt != 0 ) + { + if( ( ret = ssl_encrypt_buf( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_encrypt_buf", ret ); + return( ret ); + } + + len = ssl->out_msglen; + ssl->out_hdr[3] = (unsigned char)( len >> 8 ); + ssl->out_hdr[4] = (unsigned char)( len ); + } + + ssl->out_left = 5 + ssl->out_msglen; + + SSL_DEBUG_MSG( 3, ( "output record: msgtype = %d, " + "version = [%d:%d], msglen = %d", + ssl->out_hdr[0], ssl->out_hdr[1], ssl->out_hdr[2], + ( ssl->out_hdr[3] << 8 ) | ssl->out_hdr[4] ) ); + + SSL_DEBUG_BUF( 4, "output record sent to network", + ssl->out_hdr, 5 + ssl->out_msglen ); } - ssl->out_left = 5 + ssl->out_msglen; - - SSL_DEBUG_MSG( 3, ( "output record: msgtype = %d, " - "version = [%d:%d], msglen = %d", - ssl->out_hdr[0], ssl->out_hdr[1], ssl->out_hdr[2], - ( ssl->out_hdr[3] << 8 ) | ssl->out_hdr[4] ) ); - - SSL_DEBUG_BUF( 4, "output record sent to network", - ssl->out_hdr, 5 + ssl->out_msglen ); - if( ( ret = ssl_flush_output( ssl ) ) != 0 ) { SSL_DEBUG_RET( 1, "ssl_flush_output", ret ); @@ -1478,7 +1523,7 @@ int ssl_write_record( ssl_context *ssl ) int ssl_read_record( ssl_context *ssl ) { - int ret; + int ret, done = 0; SSL_DEBUG_MSG( 2, ( "=> read record" ) ); @@ -1598,7 +1643,21 @@ int ssl_read_record( ssl_context *ssl ) SSL_DEBUG_BUF( 4, "input record from network", ssl->in_hdr, 5 + ssl->in_msglen ); - if( ssl->do_crypt != 0 ) +#if defined(POLARSSL_SSL_HW_RECORD_ACCEL) + if( ssl_hw_record_read != NULL) + { + SSL_DEBUG_MSG( 2, ( "going for ssl_hw_record_read()" ) ); + + ret = ssl_hw_record_read( ssl ); + if( ret != 0 && ret != POLARSSL_ERR_SSL_HW_ACCEL_FALLTHROUGH ) + { + SSL_DEBUG_RET( 1, "ssl_hw_record_read", ret ); + return POLARSSL_ERR_SSL_HW_ACCEL_FAILED; + } + done = 1; + } +#endif + if( !done && ssl->do_crypt != 0 ) { if( ( ret = ssl_decrypt_buf( ssl ) ) != 0 ) { @@ -2458,6 +2517,14 @@ void ssl_session_reset( ssl_context *ssl ) memset( ssl->ctx_dec, 0, 128 ); ssl->update_checksum = ssl_update_checksum_start; + +#if defined(POLARSSL_SSL_HW_RECORD_ACCEL) + if( ssl_hw_record_reset != NULL) + { + SSL_DEBUG_MSG( 2, ( "going for ssl_hw_record_reset()" ) ); + ssl_hw_record_reset( ssl ); + } +#endif } /* @@ -3157,6 +3224,14 @@ void ssl_free( ssl_context *ssl ) ssl->hostname_len = 0; } +#if defined(POLARSSL_SSL_HW_RECORD_ACCEL) + if( ssl_hw_record_finish != NULL ) + { + SSL_DEBUG_MSG( 2, ( "going for ssl_hw_record_finish()" ) ); + ssl_hw_record_finish( ssl ); + } +#endif + SSL_DEBUG_MSG( 2, ( "<= free" ) ); /* Actually free after last debug message */