From 05ef835b6a97ca85c331c0160278dabd6c92d99b Mon Sep 17 00:00:00 2001
From: Paul Bakker
Date: Tue, 8 May 2012 09:17:57 +0000
Subject: [PATCH] - Added support for Hardware Acceleration hooking in SSL/TLS
---
ChangeLog | 1 +
include/polarssl/config.h | 10 +++
include/polarssl/error.h | 3 +-
include/polarssl/ssl.h | 13 ++++
library/error.c | 6 +-
library/ssl_tls.c | 127 ++++++++++++++++++++++++++++++--------
6 files changed, 132 insertions(+), 28 deletions(-)
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 */