Merge branch 'ecc-devel-mpg' into development
diff --git a/ChangeLog b/ChangeLog
index c1b6c88..59a43dc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,63 @@
PolarSSL ChangeLog
-= Version Master
+= Development
+Changes
+ * Introduced separate SSL Ciphersuites module that is based on
+ Cipher and MD information
+ * Internals for SSL module adapted to have separate IV pointer that is
+ dynamically set (Better support for hardware acceleration)
+
+= Version 1.2.6 released 2013-03-11
+Bugfix
+ * Fixed memory leak in ssl_free() and ssl_reset() for active session
+ * Corrected GCM counter incrementation to use only 32-bits instead of
+ 128-bits (found by Yawning Angel)
+ * Fixes for 64-bit compilation with MS Visual Studio
+ * Fixed net_bind() for specified IP addresses on little endian systems
+ * Fixed assembly code for ARM (Thumb and regular) for some compilers
+
+Changes
+ * Internally split up rsa_pkcs1_encrypt(), rsa_pkcs1_decrypt(),
+ rsa_pkcs1_sign() and rsa_pkcs1_verify() to separate PKCS#1 v1.5 and
+ PKCS#1 v2.1 functions
+ * Added support for custom labels when using rsa_rsaes_oaep_encrypt()
+ or rsa_rsaes_oaep_decrypt()
+ * Re-added handling for SSLv2 Client Hello when the define
+ POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO is set
+ * The SSL session cache module (ssl_cache) now also retains peer_cert
+ information (not the entire chain)
+
+Security
+ * Removed further timing differences during SSL message decryption in
+ ssl_decrypt_buf()
+ * Removed timing differences due to bad padding from
+ rsa_rsaes_pkcs1_v15_decrypt() and rsa_pkcs1_decrypt() for PKCS#1 v1.5
+ operations
+
+= Version 1.2.5 released 2013-02-02
+Changes
+ * Allow enabling of dummy error_strerror() to support some use-cases
+ * Debug messages about padding errors during SSL message decryption are
+ disabled by default and can be enabled with POLARSSL_SSL_DEBUG_ALL
+ * Sending of security-relevant alert messages that do not break
+ interoperability can be switched on/off with the flag
+ POLARSSL_SSL_ALL_ALERT_MESSAGES
+
+Security
+ * Removed timing differences during SSL message decryption in
+ ssl_decrypt_buf() due to badly formatted padding
+
+= Version 1.2.4 released 2013-01-25
+Changes
+ * More advanced SSL ciphersuite representation and moved to more dynamic
+ SSL core
+ * Added ssl_handshake_step() to allow single stepping the handshake process
+
Bugfix
* Memory leak when using RSA_PKCS_V21 operations fixed
* Handle future version properly in ssl_write_certificate_request()
+ * Correctly handle CertificateRequest message in client for <= TLS 1.1
+ without DN list
= Version 1.2.3 released 2012-11-26
Bugfix
@@ -101,6 +155,30 @@
* Fixed potential memory zeroization on miscrafted RSA key (found by Eloi
Vanderbeken)
+= Version 1.1.5 released on 2013-01-16
+Bugfix
+ * Fixed MPI assembly for SPARC64 platform
+ * Handle existence of OpenSSL Trust Extensions at end of X.509 DER blob
+ * mpi_add_abs() now correctly handles adding short numbers to long numbers
+ with carry rollover
+ * Moved mpi_inv_mod() outside POLARSSL_GENPRIME
+ * Prevent reading over buffer boundaries on X509 certificate parsing
+ * mpi_exp_mod() now correctly handles negative base numbers (Closes ticket
+ #52)
+ * Fixed possible segfault in mpi_shift_r() (found by Manuel
+ Pégourié-Gonnard)
+ * Allow R and A to point to same mpi in mpi_div_mpi (found by Manuel
+ Pégourié-Gonnard)
+ * Added max length check for rsa_pkcs1_sign with PKCS#1 v2.1
+ * Memory leak when using RSA_PKCS_V21 operations fixed
+ * Handle encryption with private key and decryption with public key as per
+ RFC 2313
+ * Fixes for MSVC6
+
+Security
+ * Fixed potential memory zeroization on miscrafted RSA key (found by Eloi
+ Vanderbeken)
+
= Version 1.1.4 released on 2012-05-31
Bugfix
* Correctly handle empty SSL/TLS packets (Found by James Yonan)
@@ -164,12 +242,12 @@
management (Closes ticket #44)
* Changed the used random function pointer to more flexible format. Renamed
havege_rand() to havege_random() to prevent mistakes. Lots of changes as
- a consequence in library code and programs
+ a consequence in library code and programs
* Moved all examples programs to use the new entropy and CTR_DRBG
* Added permissive certificate parsing to x509parse_crt() and
x509parse_crtfile(). With permissive parsing the parsing does not stop on
- encountering a parse-error. Beware that the meaning of return values has
- changed!
+ encountering a parse-error. Beware that the meaning of return values has
+ changed!
* All error codes are now negative. Even on mermory failures and IO errors.
Bugfix
@@ -205,7 +283,7 @@
Features
* Added additional Cipher Block Modes to symmetric ciphers
(AES CTR, Camellia CTR, XTEA CBC) including the option to
- enable and disable individual modes when needed
+ enable and disable individual modes when needed
* Functions requiring File System functions can now be disabled
by undefining POLARSSL_FS_IO
* A error_strerror function() has been added to translate between
@@ -217,22 +295,22 @@
Changes
* Major argument / variable rewrite. Introduced use of size_t
instead of int for buffer lengths and loop variables for
- better unsigned / signed use. Renamed internal bigint types
- t_int and t_dbl to t_uint and t_udbl in the process
+ better unsigned / signed use. Renamed internal bigint types
+ t_int and t_dbl to t_uint and t_udbl in the process
* mpi_init() and mpi_free() now only accept a single MPI
argument and do not accept variable argument lists anymore.
* The error codes have been remapped and combining error codes
is now done with a PLUS instead of an OR as error codes
- used are negative.
+ used are negative.
* Changed behaviour of net_read(), ssl_fetch_input() and ssl_recv().
net_recv() now returns 0 on EOF instead of
- POLARSSL_ERR_NET_CONN_RESET. ssl_fetch_input() returns
- POLARSSL_ERR_SSL_CONN_EOF on an EOF from its f_recv() function.
- ssl_read() returns 0 if a POLARSSL_ERR_SSL_CONN_EOF is received
- after the handshake.
+ POLARSSL_ERR_NET_CONN_RESET. ssl_fetch_input() returns
+ POLARSSL_ERR_SSL_CONN_EOF on an EOF from its f_recv() function.
+ ssl_read() returns 0 if a POLARSSL_ERR_SSL_CONN_EOF is received
+ after the handshake.
* Network functions now return POLARSSL_ERR_NET_WANT_READ or
POLARSSL_ERR_NET_WANT_WRITE instead of the ambiguous
- POLARSSL_ERR_NET_TRY_AGAIN
+ POLARSSL_ERR_NET_TRY_AGAIN
= Version 0.99-pre4 released on 2011-04-01
Features
@@ -248,12 +326,12 @@
displays actual bit size of the value.
* x509parse_key() (and as a consequence x509parse_keyfile())
does not zeroize memory in advance anymore. Use rsa_init()
- before parsing a key or keyfile!
+ before parsing a key or keyfile!
Bugfix
* Debug output of MPI's now the same independent of underlying
platform (32-bit / 64-bit) (Fixes ticket #19, found by Mads
- Kiilerich and Mihai Militaru)
+ Kiilerich and Mihai Militaru)
* Fixed bug in ssl_write() when flushing old data (Fixed ticket
#18, found by Nikolay Epifanov)
* Fixed proper handling of RSASSA-PSS verification with variable
@@ -270,7 +348,7 @@
Changes
* Parsing of PEM files moved to separate module (Fixes
ticket #13). Also possible to remove PEM support for
- systems only using DER encoding
+ systems only using DER encoding
Bugfixes
* Corrected parsing of UTCTime dates before 1990 and
@@ -282,12 +360,12 @@
* Replaced the expired test certificates
* Do not bail out if no client certificate specified. Try
to negotiate anonymous connection (Fixes ticket #12,
- found by Boris Krasnovskiy)
+ found by Boris Krasnovskiy)
Security fixes
* Fixed a possible Man-in-the-Middle attack on the
Diffie Hellman key exchange (thanks to Larry Highsmith,
- Subreption LLC)
+ Subreption LLC)
= Version 0.99-pre1 released on 2011-01-30
Features
@@ -315,9 +393,9 @@
the existing date check
* The ciphers member of ssl_context and the cipher member
of ssl_session have been renamed to ciphersuites and
- ciphersuite respectively. This clarifies the difference
- with the generic cipher layer and is better naming
- altogether
+ ciphersuite respectively. This clarifies the difference
+ with the generic cipher layer and is better naming
+ altogether
= Version 0.14.0 released on 2010-08-16
Features
@@ -331,8 +409,8 @@
* Made Makefile cleaner
* Removed dependency on rand() in rsa_pkcs1_encrypt().
Now using random fuction provided to function and
- changed the prototype of rsa_pkcs1_encrypt(),
- rsa_init() and rsa_gen_key().
+ changed the prototype of rsa_pkcs1_encrypt(),
+ rsa_init() and rsa_gen_key().
* Some SSL defines were renamed in order to avoid
future confusion
diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h
index 9824692..dc98951 100644
--- a/doxygen/input/doc_mainpage.h
+++ b/doxygen/input/doc_mainpage.h
@@ -4,7 +4,7 @@
*/
/**
- * @mainpage PolarSSL v1.2.3 source code documentation
+ * @mainpage PolarSSL v1.2.6 source code documentation
*
* This documentation describes the internal structure of PolarSSL. It was
* automatically generated from specially formatted comment blocks in
diff --git a/doxygen/polarssl.doxyfile b/doxygen/polarssl.doxyfile
index cd5eef3..5fbc133 100644
--- a/doxygen/polarssl.doxyfile
+++ b/doxygen/polarssl.doxyfile
@@ -25,7 +25,7 @@
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
# by quotes) that should identify the project.
-PROJECT_NAME = "PolarSSL v1.2.3"
+PROJECT_NAME = "PolarSSL v1.2.6"
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
diff --git a/include/polarssl/base64.h b/include/polarssl/base64.h
index 883215d..fb0d753 100644
--- a/include/polarssl/base64.h
+++ b/include/polarssl/base64.h
@@ -63,8 +63,8 @@
* \param slen amount of data to be decoded
*
* \return 0 if successful, POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL, or
- * POLARSSL_ERR_BASE64_INVALID_DATA if the input data is not
- * correct. *dlen is always updated to reflect the amount
+ * POLARSSL_ERR_BASE64_INVALID_CHARACTER if the input data is
+ * not correct. *dlen is always updated to reflect the amount
* of data that has (or would have) been written.
*
* \note Call this function with *dlen = 0 to obtain the
diff --git a/include/polarssl/bignum.h b/include/polarssl/bignum.h
index ce29ca3..e02db3f 100644
--- a/include/polarssl/bignum.h
+++ b/include/polarssl/bignum.h
@@ -42,6 +42,7 @@
typedef UINT16 uint16_t;
#endif
typedef INT32 int32_t;
+typedef INT64 int64_t;
typedef UINT32 uint32_t;
typedef UINT64 uint64_t;
#else
@@ -77,7 +78,7 @@
/*
* Maximum size of MPIs allowed in bits and bytes for user-MPIs.
- * ( Default: 512 bytes => 4096 bits, Maximum: 1024 bytes => 8192 bits )
+ * ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits )
*
* Note: Calculations can results temporarily in larger MPIs. So the number
* of limbs required (POLARSSL_MPI_MAX_LIMBS) is higher.
@@ -122,7 +123,7 @@
typedef uint32_t t_udbl;
#define POLARSSL_HAVE_UDBL
#else
- #if ( defined(__MSC_VER) && defined(_M_AMD64) )
+ #if ( defined(_MSC_VER) && defined(_M_AMD64) )
typedef int64_t t_sint;
typedef uint64_t t_uint;
#else
diff --git a/include/polarssl/bn_mul.h b/include/polarssl/bn_mul.h
index ae6e2d6..6bb511d 100644
--- a/include/polarssl/bn_mul.h
+++ b/include/polarssl/bn_mul.h
@@ -551,75 +551,97 @@
#if defined(__thumb__)
#define MULADDC_INIT \
- asm( "ldr r0, %0 " :: "m" (s)); \
- asm( "ldr r1, %0 " :: "m" (d)); \
- asm( "ldr r2, %0 " :: "m" (c)); \
- asm( "ldr r3, %0 " :: "m" (b)); \
- asm( "lsr r7, r3, #16 " ); \
- asm( "mov r9, r7 " ); \
- asm( "lsl r7, r3, #16 " ); \
- asm( "lsr r7, r7, #16 " ); \
- asm( "mov r8, r7 " );
+ asm( \
+ " \
+ ldr r0, %3; \
+ ldr r1, %4; \
+ ldr r2, %5; \
+ ldr r3, %6; \
+ lsr r7, r3, #16; \
+ mov r9, r7; \
+ lsl r7, r3, #16; \
+ lsr r7, r7, #16; \
+ mov r8, r7; \
+ "
#define MULADDC_CORE \
- asm( "ldmia r0!, {r6} " ); \
- asm( "lsr r7, r6, #16 " ); \
- asm( "lsl r6, r6, #16 " ); \
- asm( "lsr r6, r6, #16 " ); \
- asm( "mov r4, r8 " ); \
- asm( "mul r4, r6 " ); \
- asm( "mov r3, r9 " ); \
- asm( "mul r6, r3 " ); \
- asm( "mov r5, r9 " ); \
- asm( "mul r5, r7 " ); \
- asm( "mov r3, r8 " ); \
- asm( "mul r7, r3 " ); \
- asm( "lsr r3, r6, #16 " ); \
- asm( "add r5, r5, r3 " ); \
- asm( "lsr r3, r7, #16 " ); \
- asm( "add r5, r5, r3 " ); \
- asm( "add r4, r4, r2 " ); \
- asm( "mov r2, #0 " ); \
- asm( "adc r5, r2 " ); \
- asm( "lsl r3, r6, #16 " ); \
- asm( "add r4, r4, r3 " ); \
- asm( "adc r5, r2 " ); \
- asm( "lsl r3, r7, #16 " ); \
- asm( "add r4, r4, r3 " ); \
- asm( "adc r5, r2 " ); \
- asm( "ldr r3, [r1] " ); \
- asm( "add r4, r4, r3 " ); \
- asm( "adc r2, r5 " ); \
- asm( "stmia r1!, {r4} " );
+ " \
+ ldmia r0!, {r6}; \
+ lsr r7, r6, #16; \
+ lsl r6, r6, #16; \
+ lsr r6, r6, #16; \
+ mov r4, r8; \
+ mul r4, r6; \
+ mov r3, r9; \
+ mul r6, r3; \
+ mov r5, r9; \
+ mul r5, r7; \
+ mov r3, r8; \
+ mul r7, r3; \
+ lsr r3, r6, #16; \
+ add r5, r5, r3; \
+ lsr r3, r7, #16; \
+ add r5, r5, r3; \
+ add r4, r4, r2; \
+ mov r2, #0; \
+ adc r5, r2; \
+ lsl r3, r6, #16; \
+ add r4, r4, r3; \
+ adc r5, r2; \
+ lsl r3, r7, #16; \
+ add r4, r4, r3; \
+ adc r5, r2; \
+ ldr r3, [r1]; \
+ add r4, r4, r3; \
+ adc r2, r5; \
+ stmia r1!, {r4}; \
+ "
#define MULADDC_STOP \
- asm( "str r2, %0 " : "=m" (c)); \
- asm( "str r1, %0 " : "=m" (d)); \
- asm( "str r0, %0 " : "=m" (s) :: \
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
+ " \
+ str r2, %0; \
+ str r1, %1; \
+ str r0, %2; \
+ " \
+ : "=m" (c), "=m" (d), "=m" (s) \
+ : "m" (s), "m" (d), "m" (c), "m" (b) \
+ : "r0", "r1", "r2", "r3", "r4", "r5", \
+ "r6", "r7", "r8", "r9" \
+ );
#else
#define MULADDC_INIT \
- asm( "ldr r0, %0 " :: "m" (s)); \
- asm( "ldr r1, %0 " :: "m" (d)); \
- asm( "ldr r2, %0 " :: "m" (c)); \
- asm( "ldr r3, %0 " :: "m" (b));
+ asm( \
+ " \
+ ldr r0, %3; \
+ ldr r1, %4; \
+ ldr r2, %5; \
+ ldr r3, %6; \
+ "
#define MULADDC_CORE \
- asm( "ldr r4, [r0], #4 " ); \
- asm( "mov r5, #0 " ); \
- asm( "ldr r6, [r1] " ); \
- asm( "umlal r2, r5, r3, r4 " ); \
- asm( "adds r7, r6, r2 " ); \
- asm( "adc r2, r5, #0 " ); \
- asm( "str r7, [r1], #4 " );
+ " \
+ ldr r4, [r0], #4; \
+ mov r5, #0; \
+ ldr r6, [r1]; \
+ umlal r2, r5, r3, r4; \
+ adds r7, r6, r2; \
+ adc r2, r5, #0; \
+ str r7, [r1], #4; \
+ "
#define MULADDC_STOP \
- asm( "str r2, %0 " : "=m" (c)); \
- asm( "str r1, %0 " : "=m" (d)); \
- asm( "str r0, %0 " : "=m" (s) :: \
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" );
+ " \
+ str r2, %0; \
+ str r1, %1; \
+ str r0, %2; \
+ " \
+ : "=m" (c), "=m" (d), "=m" (s) \
+ : "m" (s), "m" (d), "m" (c), "m" (b) \
+ : "r0", "r1", "r2", "r3", "r4", "r5", \
+ "r6", "r7" \
+ );
#endif /* Thumb */
diff --git a/include/polarssl/cipher.h b/include/polarssl/cipher.h
index 8224128..2ffdf66 100644
--- a/include/polarssl/cipher.h
+++ b/include/polarssl/cipher.h
@@ -5,7 +5,7 @@
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
- * Copyright (C) 2006-2012, Brainspark B.V.
+ * Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
@@ -54,6 +54,7 @@
POLARSSL_CIPHER_ID_3DES,
POLARSSL_CIPHER_ID_CAMELLIA,
POLARSSL_CIPHER_ID_BLOWFISH,
+ POLARSSL_CIPHER_ID_ARC4,
} cipher_id_t;
typedef enum {
@@ -68,6 +69,8 @@
POLARSSL_CIPHER_AES_128_CTR,
POLARSSL_CIPHER_AES_192_CTR,
POLARSSL_CIPHER_AES_256_CTR,
+ POLARSSL_CIPHER_AES_128_GCM,
+ POLARSSL_CIPHER_AES_256_GCM,
POLARSSL_CIPHER_CAMELLIA_128_CBC,
POLARSSL_CIPHER_CAMELLIA_192_CBC,
POLARSSL_CIPHER_CAMELLIA_256_CBC,
@@ -83,6 +86,7 @@
POLARSSL_CIPHER_BLOWFISH_CBC,
POLARSSL_CIPHER_BLOWFISH_CFB64,
POLARSSL_CIPHER_BLOWFISH_CTR,
+ POLARSSL_CIPHER_ARC4_128,
} cipher_type_t;
typedef enum {
@@ -92,6 +96,8 @@
POLARSSL_MODE_CFB,
POLARSSL_MODE_OFB,
POLARSSL_MODE_CTR,
+ POLARSSL_MODE_GCM,
+ POLARSSL_MODE_STREAM,
} cipher_mode_t;
typedef enum {
@@ -351,10 +357,10 @@
*/
static inline int cipher_get_key_size ( const cipher_context_t *ctx )
{
- if( NULL == ctx )
+ if( NULL == ctx || NULL == ctx->cipher_info )
return POLARSSL_KEY_LENGTH_NONE;
- return ctx->key_length;
+ return ctx->cipher_info->key_length;
}
/**
@@ -448,7 +454,6 @@
*/
int cipher_finish( cipher_context_t *ctx, unsigned char *output, size_t *olen);
-
/**
* \brief Checkup routine
*
diff --git a/include/polarssl/cipher_wrap.h b/include/polarssl/cipher_wrap.h
index 4abbc4e..4dabb44 100644
--- a/include/polarssl/cipher_wrap.h
+++ b/include/polarssl/cipher_wrap.h
@@ -5,7 +5,7 @@
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
- * Copyright (C) 2006-2012, Brainspark B.V.
+ * Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
@@ -54,6 +54,11 @@
extern const cipher_info_t aes_256_ctr_info;
#endif /* POLARSSL_CIPHER_MODE_CTR */
+#if defined(POLARSSL_GCM_C)
+extern const cipher_info_t aes_128_gcm_info;
+extern const cipher_info_t aes_256_gcm_info;
+#endif /* POLARSSL_GCM_C */
+
#endif /* defined(POLARSSL_AES_C) */
#if defined(POLARSSL_CAMELLIA_C)
@@ -96,6 +101,10 @@
#endif /* POLARSSL_CIPHER_MODE_CTR */
#endif /* defined(POLARSSL_BLOWFISH_C) */
+#if defined(POLARSSL_ARC4_C)
+extern const cipher_info_t arc4_128_info;
+#endif /* defined(POLARSSL_ARC4_C) */
+
#if defined(POLARSSL_CIPHER_NULL_CIPHER)
extern const cipher_info_t null_cipher_info;
#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
diff --git a/include/polarssl/config.h b/include/polarssl/config.h
index fcdce0b..7640a96 100644
--- a/include/polarssl/config.h
+++ b/include/polarssl/config.h
@@ -161,6 +161,17 @@
*/
/**
+ * \def POLARSSL_ERROR_STRERROR_DUMMY
+ *
+ * Enable a dummy error function to make use of error_strerror() in
+ * third party libraries easier.
+ *
+ * Disable if you run into name conflicts and want to really remove the
+ * error_strerror()
+ */
+#define POLARSSL_ERROR_STRERROR_DUMMY
+
+/**
* \def POLARSSL_GENPRIME
*
* Requires: POLARSSL_BIGNUM_C, POLARSSL_RSA_C
@@ -228,6 +239,36 @@
#define POLARSSL_SELF_TEST
/**
+ * \def POLARSSL_SSL_ALL_ALERT_MESSAGES
+ *
+ * Enable sending of alert messages in case of encountered errors as per RFC.
+ * If you choose not to send the alert messages, PolarSSL can still communicate
+ * with other servers, only debugging of failures is harder.
+ *
+ * The advantage of not sending alert messages, is that no information is given
+ * about reasons for failures thus preventing adversaries of gaining intel.
+ *
+ * Enable sending of all alert messages
+ */
+#define POLARSSL_SSL_ALERT_MESSAGES
+
+/**
+ * \def POLARSSL_SSL_DEBUG_ALL
+ *
+ * Enable the debug messages in SSL module for all issues.
+ * Debug messages have been disabled in some places to prevent timing
+ * attacks due to (unbalanced) debugging function calls.
+ *
+ * If you need all error reporting you should enable this during debugging,
+ * but remove this for production servers that should log as well.
+ *
+ * Uncomment this macro to report all debug messages on errors introducing
+ * a timing side-channel.
+ *
+#define POLARSSL_SSL_DEBUG_ALL
+ */
+
+/**
* \def POLARSSL_SSL_HW_RECORD_ACCEL
*
* Enable hooking functions in SSL module for hardware acceleration of
@@ -238,6 +279,16 @@
*/
/**
+ * \def POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
+ *
+ * Enable support for receiving and parsing SSLv2 Client Hello messages for the
+ * SSL Server module (POLARSSL_SSL_SRV_C)
+ *
+ * Comment this macro to disable support for SSLv2 Client Hello messages.
+ */
+#define POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
+
+/**
* \def POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
*
* If set, the X509 parser will not break-off when parsing an X509 certificate
@@ -294,6 +345,8 @@
* TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
* TLS_RSA_WITH_AES_128_GCM_SHA256
* TLS_RSA_WITH_AES_256_GCM_SHA384
+ *
+ * PEM uses AES for decrypting encrypted keys.
*/
#define POLARSSL_AES_C
@@ -445,12 +498,15 @@
* Enable the DES block cipher.
*
* Module: library/des.c
- * Caller: library/ssl_tls.c
+ * Caller: library/pem.c
+ * library/ssl_tls.c
*
* This module enables the following ciphersuites (if other requisites are
* enabled as well):
* TLS_RSA_WITH_3DES_EDE_CBC_SHA
* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+ *
+ * PEM uses DES/3DES for decrypting encrypted keys.
*/
#define POLARSSL_DES_C
@@ -617,10 +673,12 @@
* Enable the MD5 hash algorithm
*
* Module: library/md5.c
- * Caller: library/ssl_tls.c
+ * Caller: library/pem.c
+ * library/ssl_tls.c
* library/x509parse.c
*
* This module is required for SSL/TLS and X.509.
+ * PEM uses MD5 for decrypting encrypted keys.
*/
#define POLARSSL_MD5_C
diff --git a/include/polarssl/md.h b/include/polarssl/md.h
index 88596cb..b81ebf1 100644
--- a/include/polarssl/md.h
+++ b/include/polarssl/md.h
@@ -111,6 +111,8 @@
/** Free the given context */
void (*ctx_free_func)( void *ctx );
+ /** Internal use only */
+ void (*process_func)( void *ctx, const unsigned char *input );
} md_info_t;
/**
@@ -347,6 +349,9 @@
const unsigned char *input, size_t ilen,
unsigned char *output );
+/* Internal use */
+int md_process( md_context_t *ctx, const unsigned char *data );
+
#ifdef __cplusplus
}
#endif
diff --git a/include/polarssl/md2.h b/include/polarssl/md2.h
index 1f60470..02a0a10 100644
--- a/include/polarssl/md2.h
+++ b/include/polarssl/md2.h
@@ -146,6 +146,9 @@
*/
int md2_self_test( int verbose );
+/* Internal use */
+void md2_process( md2_context *ctx );
+
#ifdef __cplusplus
}
#endif
diff --git a/include/polarssl/md4.h b/include/polarssl/md4.h
index 641edf1..4791fb1 100644
--- a/include/polarssl/md4.h
+++ b/include/polarssl/md4.h
@@ -152,6 +152,9 @@
*/
int md4_self_test( int verbose );
+/* Internal use */
+void md4_process( md4_context *ctx, const unsigned char data[64] );
+
#ifdef __cplusplus
}
#endif
diff --git a/include/polarssl/md5.h b/include/polarssl/md5.h
index 2e97c2b..b0611e2 100644
--- a/include/polarssl/md5.h
+++ b/include/polarssl/md5.h
@@ -154,6 +154,9 @@
*/
int md5_self_test( int verbose );
+/* Internal use */
+void md5_process( md5_context *ctx, const unsigned char data[64] );
+
#ifdef __cplusplus
}
#endif
diff --git a/include/polarssl/rsa.h b/include/polarssl/rsa.h
index 3a822cb..f9a0220 100644
--- a/include/polarssl/rsa.h
+++ b/include/polarssl/rsa.h
@@ -255,7 +255,9 @@
unsigned char *output );
/**
- * \brief Add the message padding, then do an RSA operation
+ * \brief Generic wrapper to perform a PKCS#1 encryption using the
+ * mode from the context. Add the message padding, then do an
+ * RSA operation.
*
* \param ctx RSA context
* \param f_rng RNG function (Needed for padding and PKCS#1 v2.1 encoding)
@@ -278,7 +280,59 @@
unsigned char *output );
/**
- * \brief Do an RSA operation, then remove the message padding
+ * \brief Perform a PKCS#1 v1.5 encryption (RSAES-PKCS1-v1_5-ENCRYPT)
+ *
+ * \param ctx RSA context
+ * \param f_rng RNG function (Needed for padding)
+ * \param p_rng RNG parameter
+ * \param mode RSA_PUBLIC or RSA_PRIVATE
+ * \param ilen contains the plaintext length
+ * \param input buffer holding the data to be encrypted
+ * \param output buffer that will hold the ciphertext
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The output buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_rsaes_pkcs1_v15_encrypt( rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ int mode, size_t ilen,
+ const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief Perform a PKCS#1 v2.1 OAEP encryption (RSAES-OAEP-ENCRYPT)
+ *
+ * \param ctx RSA context
+ * \param f_rng RNG function (Needed for padding and PKCS#1 v2.1 encoding)
+ * \param p_rng RNG parameter
+ * \param mode RSA_PUBLIC or RSA_PRIVATE
+ * \param label buffer holding the custom label to use
+ * \param label_len contains the label length
+ * \param ilen contains the plaintext length
+ * \param input buffer holding the data to be encrypted
+ * \param output buffer that will hold the ciphertext
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The output buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_rsaes_oaep_encrypt( rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ int mode,
+ const unsigned char *label, size_t label_len,
+ size_t ilen,
+ const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief Generic wrapper to perform a PKCS#1 decryption using the
+ * mode from the context. Do an RSA operation, then remove
+ * the message padding
*
* \param ctx RSA context
* \param mode RSA_PUBLIC or RSA_PRIVATE
@@ -300,7 +354,57 @@
size_t output_max_len );
/**
- * \brief Do a private RSA to sign a message digest
+ * \brief Perform a PKCS#1 v1.5 decryption (RSAES-PKCS1-v1_5-DECRYPT)
+ *
+ * \param ctx RSA context
+ * \param mode RSA_PUBLIC or RSA_PRIVATE
+ * \param olen will contain the plaintext length
+ * \param input buffer holding the encrypted data
+ * \param output buffer that will hold the plaintext
+ * \param output_max_len maximum length of the output buffer
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The output buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
+ * an error is thrown.
+ */
+int rsa_rsaes_pkcs1_v15_decrypt( rsa_context *ctx,
+ int mode, size_t *olen,
+ const unsigned char *input,
+ unsigned char *output,
+ size_t output_max_len );
+
+/**
+ * \brief Perform a PKCS#1 v2.1 OAEP decryption (RSAES-OAEP-DECRYPT)
+ *
+ * \param ctx RSA context
+ * \param mode RSA_PUBLIC or RSA_PRIVATE
+ * \param label buffer holding the custom label to use
+ * \param label_len contains the label length
+ * \param olen will contain the plaintext length
+ * \param input buffer holding the encrypted data
+ * \param output buffer that will hold the plaintext
+ * \param output_max_len maximum length of the output buffer
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The output buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
+ * an error is thrown.
+ */
+int rsa_rsaes_oaep_decrypt( rsa_context *ctx,
+ int mode,
+ const unsigned char *label, size_t label_len,
+ size_t *olen,
+ const unsigned char *input,
+ unsigned char *output,
+ size_t output_max_len );
+
+/**
+ * \brief Generic wrapper to perform a PKCS#1 signature using the
+ * mode from the context. Do a private RSA operation to sign
+ * a message digest
*
* \param ctx RSA context
* \param f_rng RNG function (Needed for PKCS#1 v2.1 encoding)
@@ -333,7 +437,65 @@
unsigned char *sig );
/**
- * \brief Do a public RSA and check the message digest
+ * \brief Perform a PKCS#1 v1.5 signature (RSASSA-PKCS1-v1_5-SIGN)
+ *
+ * \param ctx RSA context
+ * \param mode RSA_PUBLIC or RSA_PRIVATE
+ * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
+ * \param hashlen message digest length (for SIG_RSA_RAW only)
+ * \param hash buffer holding the message digest
+ * \param sig buffer that will hold the ciphertext
+ *
+ * \return 0 if the signing operation was successful,
+ * or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The "sig" buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx,
+ int mode,
+ int hash_id,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig );
+
+/**
+ * \brief Perform a PKCS#1 v2.1 PSS signature (RSASSA-PSS-SIGN)
+ *
+ * \param ctx RSA context
+ * \param f_rng RNG function (Needed for PKCS#1 v2.1 encoding)
+ * \param p_rng RNG parameter
+ * \param mode RSA_PUBLIC or RSA_PRIVATE
+ * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
+ * \param hashlen message digest length (for SIG_RSA_RAW only)
+ * \param hash buffer holding the message digest
+ * \param sig buffer that will hold the ciphertext
+ *
+ * \return 0 if the signing operation was successful,
+ * or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The "sig" buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ *
+ * \note In case of PKCS#1 v2.1 encoding keep in mind that
+ * the hash_id in the RSA context is the one used for the
+ * encoding. hash_id in the function call is the type of hash
+ * that is encoded. According to RFC 3447 it is advised to
+ * keep both hashes the same.
+ */
+int rsa_rsassa_pss_sign( rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ int mode,
+ int hash_id,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig );
+
+/**
+ * \brief Generic wrapper to perform a PKCS#1 verification using the
+ * mode from the context. Do a public RSA operation and check
+ * the message digest
*
* \param ctx points to an RSA public key
* \param mode RSA_PUBLIC or RSA_PRIVATE
@@ -362,6 +524,59 @@
unsigned char *sig );
/**
+ * \brief Perform a PKCS#1 v1.5 verification (RSASSA-PKCS1-v1_5-VERIFY)
+ *
+ * \param ctx points to an RSA public key
+ * \param mode RSA_PUBLIC or RSA_PRIVATE
+ * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
+ * \param hashlen message digest length (for SIG_RSA_RAW only)
+ * \param hash buffer holding the message digest
+ * \param sig buffer holding the ciphertext
+ *
+ * \return 0 if the verify operation was successful,
+ * or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The "sig" buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_rsassa_pkcs1_v15_verify( rsa_context *ctx,
+ int mode,
+ int hash_id,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig );
+
+/**
+ * \brief Perform a PKCS#1 v2.1 PSS verification (RSASSA-PSS-VERIFY)
+ * \brief Do a public RSA and check the message digest
+ *
+ * \param ctx points to an RSA public key
+ * \param mode RSA_PUBLIC or RSA_PRIVATE
+ * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
+ * \param hashlen message digest length (for SIG_RSA_RAW only)
+ * \param hash buffer holding the message digest
+ * \param sig buffer holding the ciphertext
+ *
+ * \return 0 if the verify operation was successful,
+ * or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The "sig" buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ *
+ * \note In case of PKCS#1 v2.1 encoding keep in mind that
+ * the hash_id in the RSA context is the one used for the
+ * verification. hash_id in the function call is the type of hash
+ * that is verified. According to RFC 3447 it is advised to
+ * keep both hashes the same.
+ */
+int rsa_rsassa_pss_verify( rsa_context *ctx,
+ int mode,
+ int hash_id,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig );
+
+/**
* \brief Free the components of an RSA key
*
* \param ctx RSA Context to free
diff --git a/include/polarssl/sha1.h b/include/polarssl/sha1.h
index 45ffadc..48da246 100644
--- a/include/polarssl/sha1.h
+++ b/include/polarssl/sha1.h
@@ -152,6 +152,9 @@
*/
int sha1_self_test( int verbose );
+/* Internal use */
+void sha1_process( sha1_context *ctx, const unsigned char data[64] );
+
#ifdef __cplusplus
}
#endif
diff --git a/include/polarssl/sha2.h b/include/polarssl/sha2.h
index 054988d..39d9347 100644
--- a/include/polarssl/sha2.h
+++ b/include/polarssl/sha2.h
@@ -160,6 +160,9 @@
*/
int sha2_self_test( int verbose );
+/* Internal use */
+void sha2_process( sha2_context *ctx, const unsigned char data[64] );
+
#ifdef __cplusplus
}
#endif
diff --git a/include/polarssl/sha4.h b/include/polarssl/sha4.h
index 6aae124..5563676 100644
--- a/include/polarssl/sha4.h
+++ b/include/polarssl/sha4.h
@@ -161,6 +161,9 @@
*/
int sha4_self_test( int verbose );
+/* Internal use */
+void sha4_process( sha4_context *ctx, const unsigned char data[128] );
+
#ifdef __cplusplus
}
#endif
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index e5d9eb7..756441c 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -3,7 +3,7 @@
*
* \brief SSL/TLS functions.
*
- * Copyright (C) 2006-2012, Brainspark B.V.
+ * Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
@@ -37,6 +37,7 @@
#include "sha4.h"
#include "x509.h"
#include "config.h"
+#include "ssl_ciphersuites.h"
#if defined(POLARSSL_DHM_C)
#include "dhm.h"
@@ -323,6 +324,8 @@
/*
* Session specific crypto layer
*/
+ const ssl_ciphersuite_t *ciphersuite_info;
+ /*!< Chosen cipersuite_info */
unsigned int keylen; /*!< symmetric key length */
size_t minlen; /*!< min. ciphertext length */
size_t ivlen; /*!< IV length */
@@ -332,8 +335,12 @@
unsigned char iv_enc[16]; /*!< IV (encryption) */
unsigned char iv_dec[16]; /*!< IV (decryption) */
- unsigned char mac_enc[32]; /*!< MAC (encryption) */
- unsigned char mac_dec[32]; /*!< MAC (decryption) */
+ /* Needed only for SSL v3.0 secret */
+ unsigned char mac_enc[32]; /*!< SSL v3.0 secret (enc) */
+ unsigned char mac_dec[32]; /*!< SSL v3.0 secret (dec) */
+
+ md_context_t md_ctx_enc; /*!< MAC (encryption) */
+ md_context_t md_ctx_dec; /*!< MAC (decryption) */
uint32_t ctx_enc[136]; /*!< encryption context */
uint32_t ctx_dec[136]; /*!< decryption context */
@@ -448,7 +455,8 @@
*/
unsigned char *in_ctr; /*!< 64-bit incoming message counter */
unsigned char *in_hdr; /*!< 5-byte record header (in_ctr+8) */
- unsigned char *in_msg; /*!< the message contents (in_hdr+5) */
+ unsigned char *in_iv; /*!< ivlen-byte IV (in_hdr+5) */
+ unsigned char *in_msg; /*!< message contents (in_iv+ivlen) */
unsigned char *in_offt; /*!< read offset in application data */
int in_msgtype; /*!< record header: message type */
@@ -463,7 +471,8 @@
*/
unsigned char *out_ctr; /*!< 64-bit outgoing message counter */
unsigned char *out_hdr; /*!< 5-byte record header (out_ctr+8) */
- unsigned char *out_msg; /*!< the message contents (out_hdr+32)*/
+ unsigned char *out_iv; /*!< ivlen-byte IV (out_hdr+5) */
+ unsigned char *out_msg; /*!< message contents (out_iv+ivlen) */
int out_msgtype; /*!< record header: message type */
size_t out_msglen; /*!< record header: message length */
@@ -518,13 +527,19 @@
extern "C" {
#endif
-extern const int ssl_default_ciphersuites[];
-
#if defined(POLARSSL_SSL_HW_RECORD_ACCEL)
+
+#define SSL_CHANNEL_OUTBOUND 0
+#define SSL_CHANNEL_INBOUND 1
+
extern int (*ssl_hw_record_init)(ssl_context *ssl,
const unsigned char *key_enc, const unsigned char *key_dec,
+ size_t keylen,
const unsigned char *iv_enc, const unsigned char *iv_dec,
- const unsigned char *mac_enc, const unsigned char *mac_dec);
+ size_t ivlen,
+ const unsigned char *mac_enc, const unsigned char *mac_dec,
+ size_t maclen);
+extern int (*ssl_hw_record_activate)(ssl_context *ssl, int direction);
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);
@@ -537,10 +552,7 @@
* \return a statically allocated array of ciphersuites, the last
* entry is 0.
*/
-static inline const int *ssl_list_ciphersuites( void )
-{
- return ssl_default_ciphersuites;
-}
+const int *ssl_list_ciphersuites( void );
/**
* \brief Return the name of the ciphersuite associated with the given
@@ -971,6 +983,20 @@
int ssl_handshake( ssl_context *ssl );
/**
+ * \brief Perform a single step of the SSL handshake
+ *
+ * Note: the state of the context (ssl->state) will be at
+ * the following state after execution of this function.
+ * Do not call this function if state is SSL_HANDSHAKE_OVER.
+ *
+ * \param ssl SSL context
+ *
+ * \return 0 if successful, POLARSSL_ERR_NET_WANT_READ,
+ * POLARSSL_ERR_NET_WANT_WRITE, or a specific SSL error code.
+ */
+int ssl_handshake_step( ssl_context *ssl );
+
+/**
* \brief Perform an SSL renegotiation on the running connection
*
* \param ssl SSL context
@@ -1061,8 +1087,8 @@
/*
* Internal functions (do not call directly)
*/
-int ssl_handshake_client( ssl_context *ssl );
-int ssl_handshake_server( ssl_context *ssl );
+int ssl_handshake_client_step( ssl_context *ssl );
+int ssl_handshake_server_step( ssl_context *ssl );
void ssl_handshake_wrapup( ssl_context *ssl );
int ssl_send_fatal_handshake_failure( ssl_context *ssl );
diff --git a/include/polarssl/ssl_cache.h b/include/polarssl/ssl_cache.h
index 85e0ed1..10cff20 100644
--- a/include/polarssl/ssl_cache.h
+++ b/include/polarssl/ssl_cache.h
@@ -46,6 +46,7 @@
{
time_t timestamp; /*!< entry timestamp */
ssl_session session; /*!< entry session */
+ x509_buf peer_cert; /*!< entry peer_cert */
ssl_cache_entry *next; /*!< chain pointer */
};
diff --git a/include/polarssl/ssl_ciphersuites.h b/include/polarssl/ssl_ciphersuites.h
new file mode 100644
index 0000000..62a928e
--- /dev/null
+++ b/include/polarssl/ssl_ciphersuites.h
@@ -0,0 +1,76 @@
+/**
+ * \file ssl_ciphersuites.h
+ *
+ * \brief SSL Ciphersuites for PolarSSL
+ *
+ * Copyright (C) 2006-2013, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef POLARSSL_SSL_CIPHERSUITES_H
+#define POLARSSL_SSL_CIPHERSUITES_H
+
+#include "cipher.h"
+#include "md.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ POLARSSL_KEY_EXCHANGE_NONE = 0,
+ POLARSSL_KEY_EXCHANGE_RSA,
+ POLARSSL_KEY_EXCHANGE_DHE_RSA
+} key_exchange_type_t;
+
+typedef struct _ssl_ciphersuite_t ssl_ciphersuite_t;
+
+#define POLARSSL_CIPHERSUITE_WEAK 0x01
+
+/**
+ * \brief This structure is used for storing ciphersuite information
+ */
+struct _ssl_ciphersuite_t
+{
+ int id;
+ const char * name;
+
+ cipher_type_t cipher;
+ md_type_t mac;
+ key_exchange_type_t key_exchange;
+
+ int min_major_ver;
+ int min_minor_ver;
+ int max_major_ver;
+ int max_minor_ver;
+
+ unsigned char flags;
+};
+
+const int *ssl_ciphersuites_list( void );
+
+const ssl_ciphersuite_t *ssl_ciphersuite_from_string( const char *ciphersuite_name );
+const ssl_ciphersuite_t *ssl_ciphersuite_from_id( int ciphersuite_id );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ssl_ciphersuites.h */
diff --git a/include/polarssl/version.h b/include/polarssl/version.h
index 0aadd9e..4f73ee2 100644
--- a/include/polarssl/version.h
+++ b/include/polarssl/version.h
@@ -39,16 +39,16 @@
*/
#define POLARSSL_VERSION_MAJOR 1
#define POLARSSL_VERSION_MINOR 2
-#define POLARSSL_VERSION_PATCH 3
+#define POLARSSL_VERSION_PATCH 6
/**
* The single version number has the following structure:
* MMNNPP00
* Major version | Minor version | Patch version
*/
-#define POLARSSL_VERSION_NUMBER 0x01020300
-#define POLARSSL_VERSION_STRING "1.2.3"
-#define POLARSSL_VERSION_STRING_FULL "PolarSSL 1.2.3"
+#define POLARSSL_VERSION_NUMBER 0x01020600
+#define POLARSSL_VERSION_STRING "1.2.6"
+#define POLARSSL_VERSION_STRING_FULL "PolarSSL 1.2.6"
#if defined(POLARSSL_VERSION_C)
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 6bc46e0..c96a42a 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -39,6 +39,7 @@
sha2.c
sha4.c
ssl_cache.c
+ ssl_ciphersuites.c
ssl_cli.c
ssl_srv.c
ssl_tls.c
@@ -60,7 +61,7 @@
else(NOT USE_SHARED_POLARSSL_LIBRARY)
add_library(polarssl SHARED ${src})
-set_target_properties(polarssl PROPERTIES VERSION 1.2.3 SOVERSION 2)
+set_target_properties(polarssl PROPERTIES VERSION 1.2.6 SOVERSION 2)
endif(NOT USE_SHARED_POLARSSL_LIBRARY)
diff --git a/library/Makefile b/library/Makefile
index c3cd451..1d3a38a 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -49,7 +49,7 @@
pkcs11.o \
rsa.o sha1.o sha2.o \
sha4.o ssl_cache.o ssl_cli.o \
- ssl_srv.o \
+ ssl_srv.o ssl_ciphersuites.o \
ssl_tls.o timing.o version.o \
x509parse.o x509write.o xtea.o
diff --git a/library/bignum.c b/library/bignum.c
index f2608c1..d9845da 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -1372,7 +1372,7 @@
t_uint z = 1;
mpi U;
- U.n = U.s = z;
+ U.n = U.s = (int) z;
U.p = &z;
mpi_montmul( A, &U, N, mm, T );
diff --git a/library/cipher.c b/library/cipher.c
index f20cc73..2a2d782 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -5,7 +5,7 @@
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
- * Copyright (C) 2006-2012, Brainspark B.V.
+ * Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
@@ -142,6 +142,13 @@
return &aes_256_ctr_info;
#endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
+#if defined(POLARSSL_GCM_C)
+ case POLARSSL_CIPHER_AES_128_GCM:
+ return &aes_128_gcm_info;
+ case POLARSSL_CIPHER_AES_256_GCM:
+ return &aes_256_gcm_info;
+#endif /* defined(POLARSSL_GCM_C) */
+
#endif
#if defined(POLARSSL_CAMELLIA_C)
@@ -181,6 +188,11 @@
return &des_ede3_cbc_info;
#endif
+#if defined(POLARSSL_ARC4_C)
+ case POLARSSL_CIPHER_ARC4_128:
+ return &arc4_128_info;
+#endif
+
#if defined(POLARSSL_BLOWFISH_C)
case POLARSSL_CIPHER_BLOWFISH_CBC:
return &blowfish_cbc_info;
@@ -374,19 +386,28 @@
int ret;
size_t copy_len = 0;
- if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ||
- input == output )
+ *olen = 0;
+
+ if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
{
return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
}
- *olen = 0;
+ if( input == output &&
+ ( ctx->unprocessed_len != 0 || ilen % cipher_get_block_size( ctx ) ) )
+ {
+ return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
+ }
#if defined(POLARSSL_CIPHER_NULL_CIPHER)
if( ctx->cipher_info->mode == POLARSSL_MODE_NULL )
{
- memcpy( output, input, ilen );
*olen = ilen;
+
+ if( output == input )
+ return( 0 );
+
+ memcpy( output, input, ilen );
return 0;
}
#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
@@ -465,6 +486,7 @@
return 0;
}
+#if defined(POLARSSL_CIPHER_MODE_CFB)
if( ctx->cipher_info->mode == POLARSSL_MODE_CFB )
{
if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx,
@@ -478,7 +500,9 @@
return 0;
}
+#endif
+#if defined(POLARSSL_CIPHER_MODE_CTR)
if( ctx->cipher_info->mode == POLARSSL_MODE_CTR )
{
if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx,
@@ -492,6 +516,7 @@
return 0;
}
+#endif
return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
}
diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c
index 6b85903..7ee2178 100644
--- a/library/cipher_wrap.c
+++ b/library/cipher_wrap.c
@@ -1,11 +1,11 @@
/**
- * \file md_wrap.c
+ * \file cipher_wrap.c
*
* \brief Generic cipher wrapper for PolarSSL
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
- * Copyright (C) 2006-2012, Brainspark B.V.
+ * Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
@@ -53,13 +53,13 @@
#if defined(POLARSSL_AES_C)
-int aes_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
+static int aes_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
unsigned char *iv, const unsigned char *input, unsigned char *output )
{
return aes_crypt_cbc( (aes_context *) ctx, operation, length, iv, input, output );
}
-int aes_crypt_cfb128_wrap( void *ctx, operation_t operation, size_t length,
+static int aes_crypt_cfb128_wrap( void *ctx, operation_t operation, size_t length,
size_t *iv_off, unsigned char *iv, const unsigned char *input, unsigned char *output )
{
#if defined(POLARSSL_CIPHER_MODE_CFB)
@@ -77,7 +77,7 @@
#endif
}
-int aes_crypt_ctr_wrap( void *ctx, size_t length,
+static int aes_crypt_ctr_wrap( void *ctx, size_t length,
size_t *nc_off, unsigned char *nonce_counter, unsigned char *stream_block,
const unsigned char *input, unsigned char *output )
{
@@ -97,12 +97,12 @@
#endif
}
-int aes_setkey_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
+static int aes_setkey_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
return aes_setkey_dec( (aes_context *) ctx, key, key_length );
}
-int aes_setkey_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
+static int aes_setkey_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
return aes_setkey_enc( (aes_context *) ctx, key, key_length );
}
@@ -222,17 +222,39 @@
};
#endif /* POLARSSL_CIPHER_MODE_CTR */
+#if defined(POLARSSL_GCM_C)
+const cipher_info_t aes_128_gcm_info = {
+ POLARSSL_CIPHER_AES_128_GCM,
+ POLARSSL_MODE_GCM,
+ 128,
+ "AES-128-GCM",
+ 16,
+ 16,
+ &aes_info
+};
+
+const cipher_info_t aes_256_gcm_info = {
+ POLARSSL_CIPHER_AES_256_GCM,
+ POLARSSL_MODE_GCM,
+ 256,
+ "AES-256-GCM",
+ 16,
+ 16,
+ &aes_info
+};
+#endif /* POLARSSL_GCM_C */
+
#endif
#if defined(POLARSSL_CAMELLIA_C)
-int camellia_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
+static int camellia_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
unsigned char *iv, const unsigned char *input, unsigned char *output )
{
return camellia_crypt_cbc( (camellia_context *) ctx, operation, length, iv, input, output );
}
-int camellia_crypt_cfb128_wrap( void *ctx, operation_t operation, size_t length,
+static int camellia_crypt_cfb128_wrap( void *ctx, operation_t operation, size_t length,
size_t *iv_off, unsigned char *iv, const unsigned char *input, unsigned char *output )
{
#if defined(POLARSSL_CIPHER_MODE_CFB)
@@ -250,7 +272,7 @@
#endif
}
-int camellia_crypt_ctr_wrap( void *ctx, size_t length,
+static int camellia_crypt_ctr_wrap( void *ctx, size_t length,
size_t *nc_off, unsigned char *nonce_counter, unsigned char *stream_block,
const unsigned char *input, unsigned char *output )
{
@@ -270,12 +292,12 @@
#endif
}
-int camellia_setkey_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
+static int camellia_setkey_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
return camellia_setkey_dec( (camellia_context *) ctx, key, key_length );
}
-int camellia_setkey_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
+static int camellia_setkey_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
return camellia_setkey_enc( (camellia_context *) ctx, key, key_length );
}
@@ -399,19 +421,19 @@
#if defined(POLARSSL_DES_C)
-int des_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
+static int des_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
unsigned char *iv, const unsigned char *input, unsigned char *output )
{
return des_crypt_cbc( (des_context *) ctx, operation, length, iv, input, output );
}
-int des3_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
+static int des3_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
unsigned char *iv, const unsigned char *input, unsigned char *output )
{
return des3_crypt_cbc( (des3_context *) ctx, operation, length, iv, input, output );
}
-int des_crypt_cfb128_wrap( void *ctx, operation_t operation, size_t length,
+static int des_crypt_cfb128_wrap( void *ctx, operation_t operation, size_t length,
size_t *iv_off, unsigned char *iv, const unsigned char *input, unsigned char *output )
{
((void) ctx);
@@ -425,7 +447,7 @@
return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
}
-int des_crypt_ctr_wrap( void *ctx, size_t length,
+static int des_crypt_ctr_wrap( void *ctx, size_t length,
size_t *nc_off, unsigned char *nonce_counter, unsigned char *stream_block,
const unsigned char *input, unsigned char *output )
{
@@ -440,43 +462,42 @@
return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
}
-
-int des_setkey_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
+static int des_setkey_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
((void) key_length);
return des_setkey_dec( (des_context *) ctx, key );
}
-int des_setkey_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
+static int des_setkey_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
((void) key_length);
return des_setkey_enc( (des_context *) ctx, key );
}
-int des3_set2key_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
+static int des3_set2key_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
((void) key_length);
return des3_set2key_dec( (des3_context *) ctx, key );
}
-int des3_set2key_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
+static int des3_set2key_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
((void) key_length);
return des3_set2key_enc( (des3_context *) ctx, key );
}
-int des3_set3key_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
+static int des3_set3key_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
((void) key_length);
return des3_set3key_dec( (des3_context *) ctx, key );
}
-int des3_set3key_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
+static int des3_set3key_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
((void) key_length);
@@ -564,13 +585,13 @@
#if defined(POLARSSL_BLOWFISH_C)
-int blowfish_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
+static int blowfish_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
unsigned char *iv, const unsigned char *input, unsigned char *output )
{
return blowfish_crypt_cbc( (blowfish_context *) ctx, operation, length, iv, input, output );
}
-int blowfish_crypt_cfb64_wrap( void *ctx, operation_t operation, size_t length,
+static int blowfish_crypt_cfb64_wrap( void *ctx, operation_t operation, size_t length,
size_t *iv_off, unsigned char *iv, const unsigned char *input, unsigned char *output )
{
#if defined(POLARSSL_CIPHER_MODE_CFB)
@@ -588,7 +609,7 @@
#endif
}
-int blowfish_crypt_ctr_wrap( void *ctx, size_t length,
+static int blowfish_crypt_ctr_wrap( void *ctx, size_t length,
size_t *nc_off, unsigned char *nonce_counter, unsigned char *stream_block,
const unsigned char *input, unsigned char *output )
{
@@ -608,12 +629,12 @@
#endif
}
-int blowfish_setkey_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
+static int blowfish_setkey_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
return blowfish_setkey( (blowfish_context *) ctx, key, key_length );
}
-int blowfish_setkey_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
+static int blowfish_setkey_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
return blowfish_setkey( (blowfish_context *) ctx, key, key_length );
}
@@ -674,6 +695,40 @@
#endif /* POLARSSL_CIPHER_MODE_CTR */
#endif /* POLARSSL_BLOWFISH_C */
+#if defined(POLARSSL_ARC4_C)
+static void * arc4_ctx_alloc( void )
+{
+ return (void *) 1;
+}
+
+
+static void arc4_ctx_free( void *ctx )
+{
+ ((void) ctx);
+}
+
+const cipher_base_t arc4_base_info = {
+ POLARSSL_CIPHER_ID_ARC4,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ arc4_ctx_alloc,
+ arc4_ctx_free
+};
+
+const cipher_info_t arc4_128_info = {
+ POLARSSL_CIPHER_ARC4_128,
+ POLARSSL_MODE_STREAM,
+ 128,
+ "ARC4-128",
+ 0,
+ 1,
+ &arc4_base_info
+};
+#endif /* POLARSSL_ARC4_C */
+
#if defined(POLARSSL_CIPHER_NULL_CIPHER)
static void * null_ctx_alloc( void )
{
@@ -702,7 +757,7 @@
POLARSSL_MODE_NULL,
0,
"NULL",
- 1,
+ 0,
1,
&null_base_info
};
diff --git a/library/error.c b/library/error.c
index 1e96ebb..1a8457b 100644
--- a/library/error.c
+++ b/library/error.c
@@ -564,4 +564,22 @@
snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
}
+#else /* POLARSSL_ERROR_C */
+
+#if defined(POLARSSL_ERROR_STRERROR_DUMMY)
+
+#include <string.h>
+
+/*
+ * Provide an non-function in case POLARSSL_ERROR_C is not defined
+ */
+void error_strerror( int ret, char *buf, size_t buflen )
+{
+ ((void) ret);
+
+ if( buflen > 0 )
+ buf[0] = '\0';
+}
+
+#endif /* POLARSSL_ERROR_STRERROR_DUMMY */
#endif /* POLARSSL_ERROR_C */
diff --git a/library/gcm.c b/library/gcm.c
index c91598c..7d79f1a 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -193,23 +193,14 @@
size_t use_len;
size_t orig_len = length * 8;
size_t orig_add_len = add_len * 8;
- unsigned char **xor_p;
memset( y, 0x00, 16 );
memset( work_buf, 0x00, 16 );
memset( tag, 0x00, tag_len );
memset( buf, 0x00, 16 );
- if( ( mode == GCM_DECRYPT && output <= input && ( input - output ) < 8 ) ||
- ( output > input && (size_t) ( output - input ) < length ) )
- {
+ if( output > input && (size_t) ( output - input ) < length )
return( POLARSSL_ERR_GCM_BAD_INPUT );
- }
-
- if( mode == GCM_ENCRYPT )
- xor_p = (unsigned char **) &out_p;
- else
- xor_p = (unsigned char **) &p;
if( iv_len == 12 )
{
@@ -263,7 +254,7 @@
{
use_len = ( length < 16 ) ? length : 16;
- for( i = 16; i > 0; i-- )
+ for( i = 16; i > 12; i-- )
if( ++y[i - 1] != 0 )
break;
@@ -271,8 +262,11 @@
for( i = 0; i < use_len; i++ )
{
+ if( mode == GCM_DECRYPT )
+ buf[i] ^= p[i];
out_p[i] = ectr[i] ^ p[i];
- buf[i] ^= (*xor_p)[i];
+ if( mode == GCM_ENCRYPT )
+ buf[i] ^= out_p[i];
}
gcm_mult( ctx, buf, buf );
diff --git a/library/md.c b/library/md.c
index 96065c9..07a93ec 100644
--- a/library/md.c
+++ b/library/md.c
@@ -294,4 +294,14 @@
return 0;
}
+int md_process( md_context_t *ctx, const unsigned char *data )
+{
+ if( ctx == NULL || ctx->md_info == NULL )
+ return POLARSSL_ERR_MD_BAD_INPUT_DATA;
+
+ ctx->md_info->process_func( ctx->md_ctx, data );
+
+ return 0;
+}
+
#endif
diff --git a/library/md2.c b/library/md2.c
index 954aa07..73abdfa 100644
--- a/library/md2.c
+++ b/library/md2.c
@@ -80,7 +80,7 @@
ctx->left = 0;
}
-static void md2_process( md2_context *ctx )
+void md2_process( md2_context *ctx )
{
int i, j;
unsigned char t = 0;
diff --git a/library/md4.c b/library/md4.c
index 82adcd8..6012526 100644
--- a/library/md4.c
+++ b/library/md4.c
@@ -76,7 +76,7 @@
ctx->state[3] = 0x10325476;
}
-static void md4_process( md4_context *ctx, const unsigned char data[64] )
+void md4_process( md4_context *ctx, const unsigned char data[64] )
{
uint32_t X[16], A, B, C, D;
diff --git a/library/md5.c b/library/md5.c
index 298f1fa..b2ee10b 100644
--- a/library/md5.c
+++ b/library/md5.c
@@ -75,7 +75,7 @@
ctx->state[3] = 0x10325476;
}
-static void md5_process( md5_context *ctx, const unsigned char data[64] )
+void md5_process( md5_context *ctx, const unsigned char data[64] )
{
uint32_t X[16], A, B, C, D;
diff --git a/library/md_wrap.c b/library/md_wrap.c
index f276db5..5f64df7 100644
--- a/library/md_wrap.c
+++ b/library/md_wrap.c
@@ -117,6 +117,13 @@
free( ctx );
}
+static void md2_process_wrap( void *ctx, const unsigned char *data )
+{
+ ((void) data);
+
+ md2_process( (md2_context *) ctx );
+}
+
const md_info_t md2_info = {
POLARSSL_MD_MD2,
"MD2",
@@ -133,28 +140,29 @@
md2_hmac,
md2_ctx_alloc,
md2_ctx_free,
+ md2_process_wrap,
};
#endif
#if defined(POLARSSL_MD4_C)
-void md4_starts_wrap( void *ctx )
+static void md4_starts_wrap( void *ctx )
{
md4_starts( (md4_context *) ctx );
}
-void md4_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
+static void md4_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
md4_update( (md4_context *) ctx, input, ilen );
}
-void md4_finish_wrap( void *ctx, unsigned char *output )
+static void md4_finish_wrap( void *ctx, unsigned char *output )
{
md4_finish( (md4_context *) ctx, output );
}
-int md4_file_wrap( const char *path, unsigned char *output )
+static int md4_file_wrap( const char *path, unsigned char *output )
{
#if defined(POLARSSL_FS_IO)
return md4_file( path, output );
@@ -165,36 +173,41 @@
#endif
}
-void md4_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
+static void md4_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
{
md4_hmac_starts( (md4_context *) ctx, key, keylen );
}
-void md4_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
+static void md4_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
md4_hmac_update( (md4_context *) ctx, input, ilen );
}
-void md4_hmac_finish_wrap( void *ctx, unsigned char *output )
+static void md4_hmac_finish_wrap( void *ctx, unsigned char *output )
{
md4_hmac_finish( (md4_context *) ctx, output );
}
-void md4_hmac_reset_wrap( void *ctx )
+static void md4_hmac_reset_wrap( void *ctx )
{
md4_hmac_reset( (md4_context *) ctx );
}
-void *md4_ctx_alloc( void )
+static void *md4_ctx_alloc( void )
{
return malloc( sizeof( md4_context ) );
}
-void md4_ctx_free( void *ctx )
+static void md4_ctx_free( void *ctx )
{
free( ctx );
}
+static void md4_process_wrap( void *ctx, const unsigned char *data )
+{
+ md4_process( (md4_context *) ctx, data );
+}
+
const md_info_t md4_info = {
POLARSSL_MD_MD4,
"MD4",
@@ -211,6 +224,7 @@
md4_hmac,
md4_ctx_alloc,
md4_ctx_free,
+ md4_process_wrap,
};
#endif
@@ -273,6 +287,11 @@
free( ctx );
}
+static void md5_process_wrap( void *ctx, const unsigned char *data )
+{
+ md5_process( (md5_context *) ctx, data );
+}
+
const md_info_t md5_info = {
POLARSSL_MD_MD5,
"MD5",
@@ -289,28 +308,29 @@
md5_hmac,
md5_ctx_alloc,
md5_ctx_free,
+ md5_process_wrap,
};
#endif
#if defined(POLARSSL_SHA1_C)
-void sha1_starts_wrap( void *ctx )
+static void sha1_starts_wrap( void *ctx )
{
sha1_starts( (sha1_context *) ctx );
}
-void sha1_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
+static void sha1_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
sha1_update( (sha1_context *) ctx, input, ilen );
}
-void sha1_finish_wrap( void *ctx, unsigned char *output )
+static void sha1_finish_wrap( void *ctx, unsigned char *output )
{
sha1_finish( (sha1_context *) ctx, output );
}
-int sha1_file_wrap( const char *path, unsigned char *output )
+static int sha1_file_wrap( const char *path, unsigned char *output )
{
#if defined(POLARSSL_FS_IO)
return sha1_file( path, output );
@@ -321,36 +341,41 @@
#endif
}
-void sha1_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
+static void sha1_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
{
sha1_hmac_starts( (sha1_context *) ctx, key, keylen );
}
-void sha1_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
+static void sha1_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
sha1_hmac_update( (sha1_context *) ctx, input, ilen );
}
-void sha1_hmac_finish_wrap( void *ctx, unsigned char *output )
+static void sha1_hmac_finish_wrap( void *ctx, unsigned char *output )
{
sha1_hmac_finish( (sha1_context *) ctx, output );
}
-void sha1_hmac_reset_wrap( void *ctx )
+static void sha1_hmac_reset_wrap( void *ctx )
{
sha1_hmac_reset( (sha1_context *) ctx );
}
-void * sha1_ctx_alloc( void )
+static void * sha1_ctx_alloc( void )
{
return malloc( sizeof( sha1_context ) );
}
-void sha1_ctx_free( void *ctx )
+static void sha1_ctx_free( void *ctx )
{
free( ctx );
}
+static void sha1_process_wrap( void *ctx, const unsigned char *data )
+{
+ sha1_process( (sha1_context *) ctx, data );
+}
+
const md_info_t sha1_info = {
POLARSSL_MD_SHA1,
"SHA1",
@@ -367,6 +392,7 @@
sha1_hmac,
sha1_ctx_alloc,
sha1_ctx_free,
+ sha1_process_wrap,
};
#endif
@@ -376,28 +402,28 @@
*/
#if defined(POLARSSL_SHA2_C)
-void sha224_starts_wrap( void *ctx )
+static void sha224_starts_wrap( void *ctx )
{
sha2_starts( (sha2_context *) ctx, 1 );
}
-void sha224_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
+static void sha224_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
sha2_update( (sha2_context *) ctx, input, ilen );
}
-void sha224_finish_wrap( void *ctx, unsigned char *output )
+static void sha224_finish_wrap( void *ctx, unsigned char *output )
{
sha2_finish( (sha2_context *) ctx, output );
}
-void sha224_wrap( const unsigned char *input, size_t ilen,
+static void sha224_wrap( const unsigned char *input, size_t ilen,
unsigned char *output )
{
sha2( input, ilen, output, 1 );
}
-int sha224_file_wrap( const char *path, unsigned char *output )
+static int sha224_file_wrap( const char *path, unsigned char *output )
{
#if defined(POLARSSL_FS_IO)
return sha2_file( path, output, 1 );
@@ -408,43 +434,48 @@
#endif
}
-void sha224_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
+static void sha224_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
{
sha2_hmac_starts( (sha2_context *) ctx, key, keylen, 1 );
}
-void sha224_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
+static void sha224_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
sha2_hmac_update( (sha2_context *) ctx, input, ilen );
}
-void sha224_hmac_finish_wrap( void *ctx, unsigned char *output )
+static void sha224_hmac_finish_wrap( void *ctx, unsigned char *output )
{
sha2_hmac_finish( (sha2_context *) ctx, output );
}
-void sha224_hmac_reset_wrap( void *ctx )
+static void sha224_hmac_reset_wrap( void *ctx )
{
sha2_hmac_reset( (sha2_context *) ctx );
}
-void sha224_hmac_wrap( const unsigned char *key, size_t keylen,
+static void sha224_hmac_wrap( const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output )
{
sha2_hmac( key, keylen, input, ilen, output, 1 );
}
-void * sha224_ctx_alloc( void )
+static void * sha224_ctx_alloc( void )
{
return malloc( sizeof( sha2_context ) );
}
-void sha224_ctx_free( void *ctx )
+static void sha224_ctx_free( void *ctx )
{
free( ctx );
}
+static void sha224_process_wrap( void *ctx, const unsigned char *data )
+{
+ sha2_process( (sha2_context *) ctx, data );
+}
+
const md_info_t sha224_info = {
POLARSSL_MD_SHA224,
"SHA224",
@@ -461,30 +492,31 @@
sha224_hmac_wrap,
sha224_ctx_alloc,
sha224_ctx_free,
+ sha224_process_wrap,
};
-void sha256_starts_wrap( void *ctx )
+static void sha256_starts_wrap( void *ctx )
{
sha2_starts( (sha2_context *) ctx, 0 );
}
-void sha256_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
+static void sha256_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
sha2_update( (sha2_context *) ctx, input, ilen );
}
-void sha256_finish_wrap( void *ctx, unsigned char *output )
+static void sha256_finish_wrap( void *ctx, unsigned char *output )
{
sha2_finish( (sha2_context *) ctx, output );
}
-void sha256_wrap( const unsigned char *input, size_t ilen,
+static void sha256_wrap( const unsigned char *input, size_t ilen,
unsigned char *output )
{
sha2( input, ilen, output, 0 );
}
-int sha256_file_wrap( const char *path, unsigned char *output )
+static int sha256_file_wrap( const char *path, unsigned char *output )
{
#if defined(POLARSSL_FS_IO)
return sha2_file( path, output, 0 );
@@ -495,43 +527,48 @@
#endif
}
-void sha256_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
+static void sha256_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
{
sha2_hmac_starts( (sha2_context *) ctx, key, keylen, 0 );
}
-void sha256_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
+static void sha256_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
sha2_hmac_update( (sha2_context *) ctx, input, ilen );
}
-void sha256_hmac_finish_wrap( void *ctx, unsigned char *output )
+static void sha256_hmac_finish_wrap( void *ctx, unsigned char *output )
{
sha2_hmac_finish( (sha2_context *) ctx, output );
}
-void sha256_hmac_reset_wrap( void *ctx )
+static void sha256_hmac_reset_wrap( void *ctx )
{
sha2_hmac_reset( (sha2_context *) ctx );
}
-void sha256_hmac_wrap( const unsigned char *key, size_t keylen,
+static void sha256_hmac_wrap( const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output )
{
sha2_hmac( key, keylen, input, ilen, output, 0 );
}
-void * sha256_ctx_alloc( void )
+static void * sha256_ctx_alloc( void )
{
return malloc( sizeof( sha2_context ) );
}
-void sha256_ctx_free( void *ctx )
+static void sha256_ctx_free( void *ctx )
{
free( ctx );
}
+static void sha256_process_wrap( void *ctx, const unsigned char *data )
+{
+ sha2_process( (sha2_context *) ctx, data );
+}
+
const md_info_t sha256_info = {
POLARSSL_MD_SHA256,
"SHA256",
@@ -548,34 +585,35 @@
sha256_hmac_wrap,
sha256_ctx_alloc,
sha256_ctx_free,
+ sha256_process_wrap,
};
#endif
#if defined(POLARSSL_SHA4_C)
-void sha384_starts_wrap( void *ctx )
+static void sha384_starts_wrap( void *ctx )
{
sha4_starts( (sha4_context *) ctx, 1 );
}
-void sha384_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
+static void sha384_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
sha4_update( (sha4_context *) ctx, input, ilen );
}
-void sha384_finish_wrap( void *ctx, unsigned char *output )
+static void sha384_finish_wrap( void *ctx, unsigned char *output )
{
sha4_finish( (sha4_context *) ctx, output );
}
-void sha384_wrap( const unsigned char *input, size_t ilen,
+static void sha384_wrap( const unsigned char *input, size_t ilen,
unsigned char *output )
{
sha4( input, ilen, output, 1 );
}
-int sha384_file_wrap( const char *path, unsigned char *output )
+static int sha384_file_wrap( const char *path, unsigned char *output )
{
#if defined(POLARSSL_FS_IO)
return sha4_file( path, output, 1 );
@@ -586,43 +624,48 @@
#endif
}
-void sha384_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
+static void sha384_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
{
sha4_hmac_starts( (sha4_context *) ctx, key, keylen, 1 );
}
-void sha384_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
+static void sha384_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
sha4_hmac_update( (sha4_context *) ctx, input, ilen );
}
-void sha384_hmac_finish_wrap( void *ctx, unsigned char *output )
+static void sha384_hmac_finish_wrap( void *ctx, unsigned char *output )
{
sha4_hmac_finish( (sha4_context *) ctx, output );
}
-void sha384_hmac_reset_wrap( void *ctx )
+static void sha384_hmac_reset_wrap( void *ctx )
{
sha4_hmac_reset( (sha4_context *) ctx );
}
-void sha384_hmac_wrap( const unsigned char *key, size_t keylen,
+static void sha384_hmac_wrap( const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output )
{
sha4_hmac( key, keylen, input, ilen, output, 1 );
}
-void * sha384_ctx_alloc( void )
+static void * sha384_ctx_alloc( void )
{
return malloc( sizeof( sha4_context ) );
}
-void sha384_ctx_free( void *ctx )
+static void sha384_ctx_free( void *ctx )
{
free( ctx );
}
+static void sha384_process_wrap( void *ctx, const unsigned char *data )
+{
+ sha4_process( (sha4_context *) ctx, data );
+}
+
const md_info_t sha384_info = {
POLARSSL_MD_SHA384,
"SHA384",
@@ -639,30 +682,31 @@
sha384_hmac_wrap,
sha384_ctx_alloc,
sha384_ctx_free,
+ sha384_process_wrap,
};
-void sha512_starts_wrap( void *ctx )
+static void sha512_starts_wrap( void *ctx )
{
sha4_starts( (sha4_context *) ctx, 0 );
}
-void sha512_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
+static void sha512_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
sha4_update( (sha4_context *) ctx, input, ilen );
}
-void sha512_finish_wrap( void *ctx, unsigned char *output )
+static void sha512_finish_wrap( void *ctx, unsigned char *output )
{
sha4_finish( (sha4_context *) ctx, output );
}
-void sha512_wrap( const unsigned char *input, size_t ilen,
+static void sha512_wrap( const unsigned char *input, size_t ilen,
unsigned char *output )
{
sha4( input, ilen, output, 0 );
}
-int sha512_file_wrap( const char *path, unsigned char *output )
+static int sha512_file_wrap( const char *path, unsigned char *output )
{
#if defined(POLARSSL_FS_IO)
return sha4_file( path, output, 0 );
@@ -673,43 +717,48 @@
#endif
}
-void sha512_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
+static void sha512_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
{
sha4_hmac_starts( (sha4_context *) ctx, key, keylen, 0 );
}
-void sha512_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
+static void sha512_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
sha4_hmac_update( (sha4_context *) ctx, input, ilen );
}
-void sha512_hmac_finish_wrap( void *ctx, unsigned char *output )
+static void sha512_hmac_finish_wrap( void *ctx, unsigned char *output )
{
sha4_hmac_finish( (sha4_context *) ctx, output );
}
-void sha512_hmac_reset_wrap( void *ctx )
+static void sha512_hmac_reset_wrap( void *ctx )
{
sha4_hmac_reset( (sha4_context *) ctx );
}
-void sha512_hmac_wrap( const unsigned char *key, size_t keylen,
+static void sha512_hmac_wrap( const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output )
{
sha4_hmac( key, keylen, input, ilen, output, 0 );
}
-void * sha512_ctx_alloc( void )
+static void * sha512_ctx_alloc( void )
{
return malloc( sizeof( sha4_context ) );
}
-void sha512_ctx_free( void *ctx )
+static void sha512_ctx_free( void *ctx )
{
free( ctx );
}
+static void sha512_process_wrap( void *ctx, const unsigned char *data )
+{
+ sha4_process( (sha4_context *) ctx, data );
+}
+
const md_info_t sha512_info = {
POLARSSL_MD_SHA512,
"SHA512",
@@ -726,6 +775,7 @@
sha512_hmac_wrap,
sha512_ctx_alloc,
sha512_ctx_free,
+ sha512_process_wrap,
};
#endif
diff --git a/library/net.c b/library/net.c
index fedde16..7a1818d 100644
--- a/library/net.c
+++ b/library/net.c
@@ -90,12 +90,20 @@
*/
#if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN
#define POLARSSL_HTONS(n) (n)
+#define POLARSSL_HTONL(n) (n)
#else
-#define POLARSSL_HTONS(n) (((((unsigned short)(n) & 0xFF)) << 8) | (((unsigned short)(n) & 0xFF00) >> 8))
+#define POLARSSL_HTONS(n) ((((unsigned short)(n) & 0xFF ) << 8 ) | \
+ (((unsigned short)(n) & 0xFF00 ) >> 8 ))
+#define POLARSSL_HTONL(n) ((((unsigned long )(n) & 0xFF ) << 24) | \
+ (((unsigned long )(n) & 0xFF00 ) << 8 ) | \
+ (((unsigned long )(n) & 0xFF0000 ) >> 8 ) | \
+ (((unsigned long )(n) & 0xFF000000) >> 24))
#endif
unsigned short net_htons(unsigned short n);
+unsigned long net_htonl(unsigned long n);
#define net_htons(n) POLARSSL_HTONS(n)
+#define net_htonl(n) POLARSSL_HTONL(n)
/*
* Initiate a TCP connection with host:port
@@ -171,7 +179,7 @@
setsockopt( *fd, SOL_SOCKET, SO_REUSEADDR,
(const char *) &n, sizeof( n ) );
- server_addr.sin_addr.s_addr = INADDR_ANY;
+ server_addr.sin_addr.s_addr = net_htonl( INADDR_ANY );
server_addr.sin_family = AF_INET;
server_addr.sin_port = net_htons( port );
@@ -185,11 +193,11 @@
break;
if( n == 4 )
- server_addr.sin_addr.s_addr =
+ server_addr.sin_addr.s_addr = net_htonl(
( (uint32_t) c[0] << 24 ) |
( (uint32_t) c[1] << 16 ) |
( (uint32_t) c[2] << 8 ) |
- ( (uint32_t) c[3] );
+ ( (uint32_t) c[3] ) );
}
if( bind( *fd, (struct sockaddr *) &server_addr,
diff --git a/library/rsa.c b/library/rsa.c
index ee6ca01..e53d9a2 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -361,6 +361,140 @@
}
#endif
+#if defined(POLARSSL_PKCS1_V21)
+/*
+ * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function
+ */
+int rsa_rsaes_oaep_encrypt( rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ int mode,
+ const unsigned char *label, size_t label_len,
+ size_t ilen,
+ const unsigned char *input,
+ unsigned char *output )
+{
+ size_t olen;
+ int ret;
+ unsigned char *p = output;
+ unsigned int hlen;
+ const md_info_t *md_info;
+ md_context_t md_ctx;
+
+ if( ctx->padding != RSA_PKCS_V21 || f_rng == NULL )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ md_info = md_info_from_type( ctx->hash_id );
+
+ if( md_info == NULL )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ olen = ctx->len;
+ hlen = md_get_size( md_info );
+
+ if( olen < ilen + 2 * hlen + 2 || f_rng == NULL )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ memset( output, 0, olen );
+
+ *p++ = 0;
+
+ // Generate a random octet string seed
+ //
+ if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
+ return( POLARSSL_ERR_RSA_RNG_FAILED + ret );
+
+ p += hlen;
+
+ // Construct DB
+ //
+ md( md_info, label, label_len, p );
+ p += hlen;
+ p += olen - 2 * hlen - 2 - ilen;
+ *p++ = 1;
+ memcpy( p, input, ilen );
+
+ md_init_ctx( &md_ctx, md_info );
+
+ // maskedDB: Apply dbMask to DB
+ //
+ mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
+ &md_ctx );
+
+ // maskedSeed: Apply seedMask to seed
+ //
+ mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
+ &md_ctx );
+
+ md_free_ctx( &md_ctx );
+
+ return( ( mode == RSA_PUBLIC )
+ ? rsa_public( ctx, output, output )
+ : rsa_private( ctx, output, output ) );
+}
+#endif /* POLARSSL_PKCS1_V21 */
+
+/*
+ * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function
+ */
+int rsa_rsaes_pkcs1_v15_encrypt( rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ int mode, size_t ilen,
+ const unsigned char *input,
+ unsigned char *output )
+{
+ size_t nb_pad, olen;
+ int ret;
+ unsigned char *p = output;
+
+ if( ctx->padding != RSA_PKCS_V15 || f_rng == NULL )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ olen = ctx->len;
+
+ if( olen < ilen + 11 )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ nb_pad = olen - 3 - ilen;
+
+ *p++ = 0;
+ if( mode == RSA_PUBLIC )
+ {
+ *p++ = RSA_CRYPT;
+
+ while( nb_pad-- > 0 )
+ {
+ int rng_dl = 100;
+
+ do {
+ ret = f_rng( p_rng, p, 1 );
+ } while( *p == 0 && --rng_dl && ret == 0 );
+
+ // Check if RNG failed to generate data
+ //
+ if( rng_dl == 0 || ret != 0)
+ return POLARSSL_ERR_RSA_RNG_FAILED + ret;
+
+ p++;
+ }
+ }
+ else
+ {
+ *p++ = RSA_SIGN;
+
+ while( nb_pad-- > 0 )
+ *p++ = 0xFF;
+ }
+
+ *p++ = 0;
+ memcpy( p, input, ilen );
+
+ return( ( mode == RSA_PUBLIC )
+ ? rsa_public( ctx, output, output )
+ : rsa_private( ctx, output, output ) );
+}
+
/*
* Add the message padding, then do an RSA operation
*/
@@ -371,139 +505,46 @@
const unsigned char *input,
unsigned char *output )
{
- size_t nb_pad, olen;
- int ret;
- unsigned char *p = output;
-#if defined(POLARSSL_PKCS1_V21)
- unsigned int hlen;
- const md_info_t *md_info;
- md_context_t md_ctx;
-#endif
-
- olen = ctx->len;
-
- if( f_rng == NULL )
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
-
switch( ctx->padding )
{
case RSA_PKCS_V15:
+ return rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen,
+ input, output );
- if( olen < ilen + 11 )
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
-
- nb_pad = olen - 3 - ilen;
-
- *p++ = 0;
- if( mode == RSA_PUBLIC )
- {
- *p++ = RSA_CRYPT;
-
- while( nb_pad-- > 0 )
- {
- int rng_dl = 100;
-
- do {
- ret = f_rng( p_rng, p, 1 );
- } while( *p == 0 && --rng_dl && ret == 0 );
-
- // Check if RNG failed to generate data
- //
- if( rng_dl == 0 || ret != 0)
- return POLARSSL_ERR_RSA_RNG_FAILED + ret;
-
- p++;
- }
- }
- else
- {
- *p++ = RSA_SIGN;
-
- while( nb_pad-- > 0 )
- *p++ = 0xFF;
- }
-
- *p++ = 0;
- memcpy( p, input, ilen );
- break;
-
#if defined(POLARSSL_PKCS1_V21)
case RSA_PKCS_V21:
-
- md_info = md_info_from_type( ctx->hash_id );
- if( md_info == NULL )
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
-
- hlen = md_get_size( md_info );
-
- if( olen < ilen + 2 * hlen + 2 || f_rng == NULL )
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
-
- memset( output, 0, olen );
-
- *p++ = 0;
-
- // Generate a random octet string seed
- //
- if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
- return( POLARSSL_ERR_RSA_RNG_FAILED + ret );
-
- p += hlen;
-
- // Construct DB
- //
- md( md_info, p, 0, p );
- p += hlen;
- p += olen - 2 * hlen - 2 - ilen;
- *p++ = 1;
- memcpy( p, input, ilen );
-
- md_init_ctx( &md_ctx, md_info );
-
- // maskedDB: Apply dbMask to DB
- //
- mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
- &md_ctx );
-
- // maskedSeed: Apply seedMask to seed
- //
- mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
- &md_ctx );
-
- md_free_ctx( &md_ctx );
- break;
+ return rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0,
+ ilen, input, output );
#endif
default:
-
return( POLARSSL_ERR_RSA_INVALID_PADDING );
}
-
- return( ( mode == RSA_PUBLIC )
- ? rsa_public( ctx, output, output )
- : rsa_private( ctx, output, output ) );
}
+#if defined(POLARSSL_PKCS1_V21)
/*
- * Do an RSA operation, then remove the message padding
+ * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function
*/
-int rsa_pkcs1_decrypt( rsa_context *ctx,
- int mode, size_t *olen,
- const unsigned char *input,
- unsigned char *output,
- size_t output_max_len)
+int rsa_rsaes_oaep_decrypt( rsa_context *ctx,
+ int mode,
+ const unsigned char *label, size_t label_len,
+ size_t *olen,
+ const unsigned char *input,
+ unsigned char *output,
+ size_t output_max_len )
{
int ret;
size_t ilen;
unsigned char *p;
- unsigned char bt;
unsigned char buf[POLARSSL_MPI_MAX_SIZE];
-#if defined(POLARSSL_PKCS1_V21)
unsigned char lhash[POLARSSL_MD_MAX_SIZE];
unsigned int hlen;
const md_info_t *md_info;
md_context_t md_ctx;
-#endif
+
+ if( ctx->padding != RSA_PKCS_V21 )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ilen = ctx->len;
@@ -519,97 +560,49 @@
p = buf;
- switch( ctx->padding )
- {
- case RSA_PKCS_V15:
+ if( *p++ != 0 )
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
- if( *p++ != 0 )
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
-
- bt = *p++;
- if( ( bt != RSA_CRYPT && mode == RSA_PRIVATE ) ||
- ( bt != RSA_SIGN && mode == RSA_PUBLIC ) )
- {
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
- }
+ md_info = md_info_from_type( ctx->hash_id );
+ if( md_info == NULL )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
- if( bt == RSA_CRYPT )
- {
- while( *p != 0 && p < buf + ilen - 1 )
- p++;
+ hlen = md_get_size( md_info );
- if( *p != 0 || p >= buf + ilen - 1 )
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ md_init_ctx( &md_ctx, md_info );
- p++;
- }
- else
- {
- while( *p == 0xFF && p < buf + ilen - 1 )
- p++;
+ // Generate lHash
+ //
+ md( md_info, label, label_len, lhash );
- if( *p != 0 || p >= buf + ilen - 1 )
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ // seed: Apply seedMask to maskedSeed
+ //
+ mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
+ &md_ctx );
- p++;
- }
+ // DB: Apply dbMask to maskedDB
+ //
+ mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
+ &md_ctx );
- break;
+ p += hlen;
+ md_free_ctx( &md_ctx );
-#if defined(POLARSSL_PKCS1_V21)
- case RSA_PKCS_V21:
-
- if( *p++ != 0 )
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ // Check validity
+ //
+ if( memcmp( lhash, p, hlen ) != 0 )
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
- md_info = md_info_from_type( ctx->hash_id );
- if( md_info == NULL )
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
-
- hlen = md_get_size( md_info );
+ p += hlen;
- md_init_ctx( &md_ctx, md_info );
-
- // Generate lHash
- //
- md( md_info, lhash, 0, lhash );
+ while( *p == 0 && p < buf + ilen )
+ p++;
- // seed: Apply seedMask to maskedSeed
- //
- mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
- &md_ctx );
+ if( p == buf + ilen )
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
- // DB: Apply dbMask to maskedDB
- //
- mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
- &md_ctx );
-
- p += hlen;
- md_free_ctx( &md_ctx );
-
- // Check validity
- //
- if( memcmp( lhash, p, hlen ) != 0 )
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
-
- p += hlen;
-
- while( *p == 0 && p < buf + ilen )
- p++;
-
- if( p == buf + ilen )
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
-
- if( *p++ != 0x01 )
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
-
- break;
-#endif
-
- default:
-
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
- }
+ if( *p++ != 0x01 )
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
if (ilen - (p - buf) > output_max_len)
return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );
@@ -619,6 +612,367 @@
return( 0 );
}
+#endif /* POLARSSL_PKCS1_V21 */
+
+/*
+ * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
+ */
+int rsa_rsaes_pkcs1_v15_decrypt( rsa_context *ctx,
+ int mode, size_t *olen,
+ const unsigned char *input,
+ unsigned char *output,
+ size_t output_max_len)
+{
+ int ret, correct = 1;
+ size_t ilen, pad_count = 0;
+ unsigned char *p, *q;
+ unsigned char bt;
+ unsigned char buf[POLARSSL_MPI_MAX_SIZE];
+
+ if( ctx->padding != RSA_PKCS_V15 )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ ilen = ctx->len;
+
+ if( ilen < 16 || ilen > sizeof( buf ) )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ ret = ( mode == RSA_PUBLIC )
+ ? rsa_public( ctx, input, buf )
+ : rsa_private( ctx, input, buf );
+
+ if( ret != 0 )
+ return( ret );
+
+ p = buf;
+
+ if( *p++ != 0 )
+ correct = 0;
+
+ bt = *p++;
+ if( ( bt != RSA_CRYPT && mode == RSA_PRIVATE ) ||
+ ( bt != RSA_SIGN && mode == RSA_PUBLIC ) )
+ {
+ correct = 0;
+ }
+
+ if( bt == RSA_CRYPT )
+ {
+ while( *p != 0 && p < buf + ilen - 1 )
+ pad_count += ( *p++ != 0 );
+
+ correct &= ( *p == 0 && p < buf + ilen - 1 );
+
+ q = p;
+
+ // Also pass over all other bytes to reduce timing differences
+ //
+ while ( q < buf + ilen - 1 )
+ pad_count += ( *q++ != 0 );
+
+ // Prevent compiler optimization of pad_count
+ //
+ correct |= pad_count & 0x100000; /* Always 0 unless 1M bit keys */
+ p++;
+ }
+ else
+ {
+ while( *p == 0xFF && p < buf + ilen - 1 )
+ pad_count += ( *p++ == 0xFF );
+
+ correct &= ( *p == 0 && p < buf + ilen - 1 );
+
+ q = p;
+
+ // Also pass over all other bytes to reduce timing differences
+ //
+ while ( q < buf + ilen - 1 )
+ pad_count += ( *q++ != 0 );
+
+ // Prevent compiler optimization of pad_count
+ //
+ correct |= pad_count & 0x100000; /* Always 0 unless 1M bit keys */
+ p++;
+ }
+
+ if( correct == 0 )
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+
+ if (ilen - (p - buf) > output_max_len)
+ return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );
+
+ *olen = ilen - (p - buf);
+ memcpy( output, p, *olen );
+
+ return( 0 );
+}
+
+/*
+ * Do an RSA operation, then remove the message padding
+ */
+int rsa_pkcs1_decrypt( rsa_context *ctx,
+ int mode, size_t *olen,
+ const unsigned char *input,
+ unsigned char *output,
+ size_t output_max_len)
+{
+ switch( ctx->padding )
+ {
+ case RSA_PKCS_V15:
+ return rsa_rsaes_pkcs1_v15_decrypt( ctx, mode, olen, input, output,
+ output_max_len );
+
+#if defined(POLARSSL_PKCS1_V21)
+ case RSA_PKCS_V21:
+ return rsa_rsaes_oaep_decrypt( ctx, mode, NULL, 0, olen, input,
+ output, output_max_len );
+#endif
+
+ default:
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ }
+}
+
+#if defined(POLARSSL_PKCS1_V21)
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
+ */
+int rsa_rsassa_pss_sign( rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ int mode,
+ int hash_id,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig )
+{
+ size_t olen;
+ unsigned char *p = sig;
+ unsigned char salt[POLARSSL_MD_MAX_SIZE];
+ unsigned int slen, hlen, offset = 0;
+ int ret;
+ size_t msb;
+ const md_info_t *md_info;
+ md_context_t md_ctx;
+
+ if( ctx->padding != RSA_PKCS_V21 || f_rng == NULL )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ olen = ctx->len;
+
+ switch( hash_id )
+ {
+ case SIG_RSA_MD2:
+ case SIG_RSA_MD4:
+ case SIG_RSA_MD5:
+ hashlen = 16;
+ break;
+
+ case SIG_RSA_SHA1:
+ hashlen = 20;
+ break;
+
+ case SIG_RSA_SHA224:
+ hashlen = 28;
+ break;
+
+ case SIG_RSA_SHA256:
+ hashlen = 32;
+ break;
+
+ case SIG_RSA_SHA384:
+ hashlen = 48;
+ break;
+
+ case SIG_RSA_SHA512:
+ hashlen = 64;
+ break;
+
+ default:
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+ }
+
+ md_info = md_info_from_type( ctx->hash_id );
+ if( md_info == NULL )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ hlen = md_get_size( md_info );
+ slen = hlen;
+
+ if( olen < hlen + slen + 2 )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ memset( sig, 0, olen );
+
+ msb = mpi_msb( &ctx->N ) - 1;
+
+ // Generate salt of length slen
+ //
+ if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
+ return( POLARSSL_ERR_RSA_RNG_FAILED + ret );
+
+ // Note: EMSA-PSS encoding is over the length of N - 1 bits
+ //
+ msb = mpi_msb( &ctx->N ) - 1;
+ p += olen - hlen * 2 - 2;
+ *p++ = 0x01;
+ memcpy( p, salt, slen );
+ p += slen;
+
+ md_init_ctx( &md_ctx, md_info );
+
+ // Generate H = Hash( M' )
+ //
+ md_starts( &md_ctx );
+ md_update( &md_ctx, p, 8 );
+ md_update( &md_ctx, hash, hashlen );
+ md_update( &md_ctx, salt, slen );
+ md_finish( &md_ctx, p );
+
+ // Compensate for boundary condition when applying mask
+ //
+ if( msb % 8 == 0 )
+ offset = 1;
+
+ // maskedDB: Apply dbMask to DB
+ //
+ mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx );
+
+ md_free_ctx( &md_ctx );
+
+ msb = mpi_msb( &ctx->N ) - 1;
+ sig[0] &= 0xFF >> ( olen * 8 - msb );
+
+ p += hlen;
+ *p++ = 0xBC;
+
+ return( ( mode == RSA_PUBLIC )
+ ? rsa_public( ctx, sig, sig )
+ : rsa_private( ctx, sig, sig ) );
+}
+#endif /* POLARSSL_PKCS1_V21 */
+
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function
+ */
+/*
+ * Do an RSA operation to sign the message digest
+ */
+int rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx,
+ int mode,
+ int hash_id,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig )
+{
+ size_t nb_pad, olen;
+ unsigned char *p = sig;
+
+ if( ctx->padding != RSA_PKCS_V15 )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ olen = ctx->len;
+
+ switch( hash_id )
+ {
+ case SIG_RSA_RAW:
+ nb_pad = olen - 3 - hashlen;
+ break;
+
+ case SIG_RSA_MD2:
+ case SIG_RSA_MD4:
+ case SIG_RSA_MD5:
+ nb_pad = olen - 3 - 34;
+ break;
+
+ case SIG_RSA_SHA1:
+ nb_pad = olen - 3 - 35;
+ break;
+
+ case SIG_RSA_SHA224:
+ nb_pad = olen - 3 - 47;
+ break;
+
+ case SIG_RSA_SHA256:
+ nb_pad = olen - 3 - 51;
+ break;
+
+ case SIG_RSA_SHA384:
+ nb_pad = olen - 3 - 67;
+ break;
+
+ case SIG_RSA_SHA512:
+ nb_pad = olen - 3 - 83;
+ break;
+
+
+ default:
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+ }
+
+ if( ( nb_pad < 8 ) || ( nb_pad > olen ) )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ *p++ = 0;
+ *p++ = RSA_SIGN;
+ memset( p, 0xFF, nb_pad );
+ p += nb_pad;
+ *p++ = 0;
+
+ switch( hash_id )
+ {
+ case SIG_RSA_RAW:
+ memcpy( p, hash, hashlen );
+ break;
+
+ case SIG_RSA_MD2:
+ memcpy( p, ASN1_HASH_MDX, 18 );
+ memcpy( p + 18, hash, 16 );
+ p[13] = 2; break;
+
+ case SIG_RSA_MD4:
+ memcpy( p, ASN1_HASH_MDX, 18 );
+ memcpy( p + 18, hash, 16 );
+ p[13] = 4; break;
+
+ case SIG_RSA_MD5:
+ memcpy( p, ASN1_HASH_MDX, 18 );
+ memcpy( p + 18, hash, 16 );
+ p[13] = 5; break;
+
+ case SIG_RSA_SHA1:
+ memcpy( p, ASN1_HASH_SHA1, 15 );
+ memcpy( p + 15, hash, 20 );
+ break;
+
+ case SIG_RSA_SHA224:
+ memcpy( p, ASN1_HASH_SHA2X, 19 );
+ memcpy( p + 19, hash, 28 );
+ p[1] += 28; p[14] = 4; p[18] += 28; break;
+
+ case SIG_RSA_SHA256:
+ memcpy( p, ASN1_HASH_SHA2X, 19 );
+ memcpy( p + 19, hash, 32 );
+ p[1] += 32; p[14] = 1; p[18] += 32; break;
+
+ case SIG_RSA_SHA384:
+ memcpy( p, ASN1_HASH_SHA2X, 19 );
+ memcpy( p + 19, hash, 48 );
+ p[1] += 48; p[14] = 2; p[18] += 48; break;
+
+ case SIG_RSA_SHA512:
+ memcpy( p, ASN1_HASH_SHA2X, 19 );
+ memcpy( p + 19, hash, 64 );
+ p[1] += 64; p[14] = 3; p[18] += 64; break;
+
+ default:
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+ }
+
+ return( ( mode == RSA_PUBLIC )
+ ? rsa_public( ctx, sig, sig )
+ : rsa_private( ctx, sig, sig ) );
+}
/*
* Do an RSA operation to sign the message digest
@@ -632,250 +986,48 @@
const unsigned char *hash,
unsigned char *sig )
{
- size_t nb_pad, olen;
- unsigned char *p = sig;
-#if defined(POLARSSL_PKCS1_V21)
- unsigned char salt[POLARSSL_MD_MAX_SIZE];
- unsigned int slen, hlen, offset = 0;
- int ret;
- size_t msb;
- const md_info_t *md_info;
- md_context_t md_ctx;
-#else
- (void) f_rng;
- (void) p_rng;
-#endif
-
- olen = ctx->len;
-
switch( ctx->padding )
{
case RSA_PKCS_V15:
-
- switch( hash_id )
- {
- case SIG_RSA_RAW:
- nb_pad = olen - 3 - hashlen;
- break;
-
- case SIG_RSA_MD2:
- case SIG_RSA_MD4:
- case SIG_RSA_MD5:
- nb_pad = olen - 3 - 34;
- break;
-
- case SIG_RSA_SHA1:
- nb_pad = olen - 3 - 35;
- break;
-
- case SIG_RSA_SHA224:
- nb_pad = olen - 3 - 47;
- break;
-
- case SIG_RSA_SHA256:
- nb_pad = olen - 3 - 51;
- break;
-
- case SIG_RSA_SHA384:
- nb_pad = olen - 3 - 67;
- break;
-
- case SIG_RSA_SHA512:
- nb_pad = olen - 3 - 83;
- break;
-
-
- default:
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
- }
-
- if( ( nb_pad < 8 ) || ( nb_pad > olen ) )
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
-
- *p++ = 0;
- *p++ = RSA_SIGN;
- memset( p, 0xFF, nb_pad );
- p += nb_pad;
- *p++ = 0;
-
- switch( hash_id )
- {
- case SIG_RSA_RAW:
- memcpy( p, hash, hashlen );
- break;
-
- case SIG_RSA_MD2:
- memcpy( p, ASN1_HASH_MDX, 18 );
- memcpy( p + 18, hash, 16 );
- p[13] = 2; break;
-
- case SIG_RSA_MD4:
- memcpy( p, ASN1_HASH_MDX, 18 );
- memcpy( p + 18, hash, 16 );
- p[13] = 4; break;
-
- case SIG_RSA_MD5:
- memcpy( p, ASN1_HASH_MDX, 18 );
- memcpy( p + 18, hash, 16 );
- p[13] = 5; break;
-
- case SIG_RSA_SHA1:
- memcpy( p, ASN1_HASH_SHA1, 15 );
- memcpy( p + 15, hash, 20 );
- break;
-
- case SIG_RSA_SHA224:
- memcpy( p, ASN1_HASH_SHA2X, 19 );
- memcpy( p + 19, hash, 28 );
- p[1] += 28; p[14] = 4; p[18] += 28; break;
-
- case SIG_RSA_SHA256:
- memcpy( p, ASN1_HASH_SHA2X, 19 );
- memcpy( p + 19, hash, 32 );
- p[1] += 32; p[14] = 1; p[18] += 32; break;
-
- case SIG_RSA_SHA384:
- memcpy( p, ASN1_HASH_SHA2X, 19 );
- memcpy( p + 19, hash, 48 );
- p[1] += 48; p[14] = 2; p[18] += 48; break;
-
- case SIG_RSA_SHA512:
- memcpy( p, ASN1_HASH_SHA2X, 19 );
- memcpy( p + 19, hash, 64 );
- p[1] += 64; p[14] = 3; p[18] += 64; break;
-
- default:
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
- }
-
- break;
+ return rsa_rsassa_pkcs1_v15_sign( ctx, mode, hash_id,
+ hashlen, hash, sig );
#if defined(POLARSSL_PKCS1_V21)
case RSA_PKCS_V21:
-
- if( f_rng == NULL )
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
-
- switch( hash_id )
- {
- case SIG_RSA_MD2:
- case SIG_RSA_MD4:
- case SIG_RSA_MD5:
- hashlen = 16;
- break;
-
- case SIG_RSA_SHA1:
- hashlen = 20;
- break;
-
- case SIG_RSA_SHA224:
- hashlen = 28;
- break;
-
- case SIG_RSA_SHA256:
- hashlen = 32;
- break;
-
- case SIG_RSA_SHA384:
- hashlen = 48;
- break;
-
- case SIG_RSA_SHA512:
- hashlen = 64;
- break;
-
- default:
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
- }
-
- md_info = md_info_from_type( ctx->hash_id );
- if( md_info == NULL )
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
-
- hlen = md_get_size( md_info );
- slen = hlen;
-
- if( olen < hlen + slen + 2 )
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
-
- memset( sig, 0, olen );
-
- msb = mpi_msb( &ctx->N ) - 1;
-
- // Generate salt of length slen
- //
- if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
- return( POLARSSL_ERR_RSA_RNG_FAILED + ret );
-
- // Note: EMSA-PSS encoding is over the length of N - 1 bits
- //
- msb = mpi_msb( &ctx->N ) - 1;
- p += olen - hlen * 2 - 2;
- *p++ = 0x01;
- memcpy( p, salt, slen );
- p += slen;
-
- md_init_ctx( &md_ctx, md_info );
-
- // Generate H = Hash( M' )
- //
- md_starts( &md_ctx );
- md_update( &md_ctx, p, 8 );
- md_update( &md_ctx, hash, hashlen );
- md_update( &md_ctx, salt, slen );
- md_finish( &md_ctx, p );
-
- // Compensate for boundary condition when applying mask
- //
- if( msb % 8 == 0 )
- offset = 1;
-
- // maskedDB: Apply dbMask to DB
- //
- mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx );
-
- md_free_ctx( &md_ctx );
-
- msb = mpi_msb( &ctx->N ) - 1;
- sig[0] &= 0xFF >> ( olen * 8 - msb );
-
- p += hlen;
- *p++ = 0xBC;
- break;
+ return rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, hash_id,
+ hashlen, hash, sig );
#endif
default:
-
return( POLARSSL_ERR_RSA_INVALID_PADDING );
}
-
- return( ( mode == RSA_PUBLIC )
- ? rsa_public( ctx, sig, sig )
- : rsa_private( ctx, sig, sig ) );
}
+#if defined(POLARSSL_PKCS1_V21)
/*
- * Do an RSA operation and check the message digest
+ * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
*/
-int rsa_pkcs1_verify( rsa_context *ctx,
- int mode,
- int hash_id,
- unsigned int hashlen,
- const unsigned char *hash,
- unsigned char *sig )
+int rsa_rsassa_pss_verify( rsa_context *ctx,
+ int mode,
+ int hash_id,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig )
{
int ret;
- size_t len, siglen;
- unsigned char *p, c;
+ size_t siglen;
+ unsigned char *p;
unsigned char buf[POLARSSL_MPI_MAX_SIZE];
-#if defined(POLARSSL_PKCS1_V21)
unsigned char result[POLARSSL_MD_MAX_SIZE];
unsigned char zeros[8];
unsigned int hlen;
size_t slen, msb;
const md_info_t *md_info;
md_context_t md_ctx;
-#endif
+
+ if( ctx->padding != RSA_PKCS_V21 )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
siglen = ctx->len;
if( siglen < 16 || siglen > sizeof( buf ) )
@@ -890,189 +1042,235 @@
p = buf;
- switch( ctx->padding )
+ if( buf[siglen - 1] != 0xBC )
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+
+ switch( hash_id )
{
- case RSA_PKCS_V15:
-
- if( *p++ != 0 || *p++ != RSA_SIGN )
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
-
- while( *p != 0 )
- {
- if( p >= buf + siglen - 1 || *p != 0xFF )
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
- p++;
- }
- p++;
-
- len = siglen - ( p - buf );
-
- if( len == 33 && hash_id == SIG_RSA_SHA1 )
- {
- if( memcmp( p, ASN1_HASH_SHA1_ALT, 13 ) == 0 &&
- memcmp( p + 13, hash, 20 ) == 0 )
- return( 0 );
- else
- return( POLARSSL_ERR_RSA_VERIFY_FAILED );
- }
- if( len == 34 )
- {
- c = p[13];
- p[13] = 0;
-
- if( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 )
- return( POLARSSL_ERR_RSA_VERIFY_FAILED );
-
- if( ( c == 2 && hash_id == SIG_RSA_MD2 ) ||
- ( c == 4 && hash_id == SIG_RSA_MD4 ) ||
- ( c == 5 && hash_id == SIG_RSA_MD5 ) )
- {
- if( memcmp( p + 18, hash, 16 ) == 0 )
- return( 0 );
- else
- return( POLARSSL_ERR_RSA_VERIFY_FAILED );
- }
- }
-
- if( len == 35 && hash_id == SIG_RSA_SHA1 )
- {
- if( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 &&
- memcmp( p + 15, hash, 20 ) == 0 )
- return( 0 );
- else
- return( POLARSSL_ERR_RSA_VERIFY_FAILED );
- }
- if( ( len == 19 + 28 && p[14] == 4 && hash_id == SIG_RSA_SHA224 ) ||
- ( len == 19 + 32 && p[14] == 1 && hash_id == SIG_RSA_SHA256 ) ||
- ( len == 19 + 48 && p[14] == 2 && hash_id == SIG_RSA_SHA384 ) ||
- ( len == 19 + 64 && p[14] == 3 && hash_id == SIG_RSA_SHA512 ) )
- {
- c = p[1] - 17;
- p[1] = 17;
- p[14] = 0;
-
- if( p[18] == c &&
- memcmp( p, ASN1_HASH_SHA2X, 18 ) == 0 &&
- memcmp( p + 19, hash, c ) == 0 )
- return( 0 );
- else
- return( POLARSSL_ERR_RSA_VERIFY_FAILED );
- }
-
- if( len == hashlen && hash_id == SIG_RSA_RAW )
- {
- if( memcmp( p, hash, hashlen ) == 0 )
- return( 0 );
- else
- return( POLARSSL_ERR_RSA_VERIFY_FAILED );
- }
-
+ case SIG_RSA_MD2:
+ case SIG_RSA_MD4:
+ case SIG_RSA_MD5:
+ hashlen = 16;
break;
-#if defined(POLARSSL_PKCS1_V21)
- case RSA_PKCS_V21:
-
- if( buf[siglen - 1] != 0xBC )
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ case SIG_RSA_SHA1:
+ hashlen = 20;
+ break;
- switch( hash_id )
- {
- case SIG_RSA_MD2:
- case SIG_RSA_MD4:
- case SIG_RSA_MD5:
- hashlen = 16;
- break;
+ case SIG_RSA_SHA224:
+ hashlen = 28;
+ break;
- case SIG_RSA_SHA1:
- hashlen = 20;
- break;
+ case SIG_RSA_SHA256:
+ hashlen = 32;
+ break;
- case SIG_RSA_SHA224:
- hashlen = 28;
- break;
+ case SIG_RSA_SHA384:
+ hashlen = 48;
+ break;
- case SIG_RSA_SHA256:
- hashlen = 32;
- break;
+ case SIG_RSA_SHA512:
+ hashlen = 64;
+ break;
- case SIG_RSA_SHA384:
- hashlen = 48;
- break;
+ default:
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+ }
- case SIG_RSA_SHA512:
- hashlen = 64;
- break;
+ md_info = md_info_from_type( ctx->hash_id );
+ if( md_info == NULL )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
- default:
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
- }
+ hlen = md_get_size( md_info );
+ slen = siglen - hlen - 1;
- md_info = md_info_from_type( ctx->hash_id );
- if( md_info == NULL )
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
-
- hlen = md_get_size( md_info );
- slen = siglen - hlen - 1;
+ memset( zeros, 0, 8 );
- memset( zeros, 0, 8 );
+ // Note: EMSA-PSS verification is over the length of N - 1 bits
+ //
+ msb = mpi_msb( &ctx->N ) - 1;
- // Note: EMSA-PSS verification is over the length of N - 1 bits
- //
- msb = mpi_msb( &ctx->N ) - 1;
+ // Compensate for boundary condition when applying mask
+ //
+ if( msb % 8 == 0 )
+ {
+ p++;
+ siglen -= 1;
+ }
+ if( buf[0] >> ( 8 - siglen * 8 + msb ) )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
- // Compensate for boundary condition when applying mask
- //
- if( msb % 8 == 0 )
- {
- p++;
- siglen -= 1;
- }
- if( buf[0] >> ( 8 - siglen * 8 + msb ) )
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+ md_init_ctx( &md_ctx, md_info );
- md_init_ctx( &md_ctx, md_info );
+ mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx );
- mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx );
+ buf[0] &= 0xFF >> ( siglen * 8 - msb );
- buf[0] &= 0xFF >> ( siglen * 8 - msb );
+ while( *p == 0 && p < buf + siglen )
+ p++;
- while( *p == 0 && p < buf + siglen )
- p++;
+ if( p == buf + siglen ||
+ *p++ != 0x01 )
+ {
+ md_free_ctx( &md_ctx );
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ }
- if( p == buf + siglen ||
- *p++ != 0x01 )
- {
- md_free_ctx( &md_ctx );
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
- }
+ slen -= p - buf;
- slen -= p - buf;
+ // Generate H = Hash( M' )
+ //
+ md_starts( &md_ctx );
+ md_update( &md_ctx, zeros, 8 );
+ md_update( &md_ctx, hash, hashlen );
+ md_update( &md_ctx, p, slen );
+ md_finish( &md_ctx, result );
- // Generate H = Hash( M' )
- //
- md_starts( &md_ctx );
- md_update( &md_ctx, zeros, 8 );
- md_update( &md_ctx, hash, hashlen );
- md_update( &md_ctx, p, slen );
- md_finish( &md_ctx, result );
+ md_free_ctx( &md_ctx );
- md_free_ctx( &md_ctx );
+ if( memcmp( p + slen, result, hlen ) == 0 )
+ return( 0 );
+ else
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+}
+#endif /* POLARSSL_PKCS1_V21 */
- if( memcmp( p + slen, result, hlen ) == 0 )
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function
+ */
+int rsa_rsassa_pkcs1_v15_verify( rsa_context *ctx,
+ int mode,
+ int hash_id,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig )
+{
+ int ret;
+ size_t len, siglen;
+ unsigned char *p, c;
+ unsigned char buf[POLARSSL_MPI_MAX_SIZE];
+
+ if( ctx->padding != RSA_PKCS_V15 )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ siglen = ctx->len;
+
+ if( siglen < 16 || siglen > sizeof( buf ) )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ ret = ( mode == RSA_PUBLIC )
+ ? rsa_public( ctx, sig, buf )
+ : rsa_private( ctx, sig, buf );
+
+ if( ret != 0 )
+ return( ret );
+
+ p = buf;
+
+ if( *p++ != 0 || *p++ != RSA_SIGN )
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+
+ while( *p != 0 )
+ {
+ if( p >= buf + siglen - 1 || *p != 0xFF )
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ p++;
+ }
+ p++;
+
+ len = siglen - ( p - buf );
+
+ if( len == 33 && hash_id == SIG_RSA_SHA1 )
+ {
+ if( memcmp( p, ASN1_HASH_SHA1_ALT, 13 ) == 0 &&
+ memcmp( p + 13, hash, 20 ) == 0 )
+ return( 0 );
+ else
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+ }
+ if( len == 34 )
+ {
+ c = p[13];
+ p[13] = 0;
+
+ if( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 )
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+ if( ( c == 2 && hash_id == SIG_RSA_MD2 ) ||
+ ( c == 4 && hash_id == SIG_RSA_MD4 ) ||
+ ( c == 5 && hash_id == SIG_RSA_MD5 ) )
+ {
+ if( memcmp( p + 18, hash, 16 ) == 0 )
return( 0 );
else
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
-#endif
+ }
+ }
- default:
+ if( len == 35 && hash_id == SIG_RSA_SHA1 )
+ {
+ if( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 &&
+ memcmp( p + 15, hash, 20 ) == 0 )
+ return( 0 );
+ else
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+ }
+ if( ( len == 19 + 28 && p[14] == 4 && hash_id == SIG_RSA_SHA224 ) ||
+ ( len == 19 + 32 && p[14] == 1 && hash_id == SIG_RSA_SHA256 ) ||
+ ( len == 19 + 48 && p[14] == 2 && hash_id == SIG_RSA_SHA384 ) ||
+ ( len == 19 + 64 && p[14] == 3 && hash_id == SIG_RSA_SHA512 ) )
+ {
+ c = p[1] - 17;
+ p[1] = 17;
+ p[14] = 0;
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ if( p[18] == c &&
+ memcmp( p, ASN1_HASH_SHA2X, 18 ) == 0 &&
+ memcmp( p + 19, hash, c ) == 0 )
+ return( 0 );
+ else
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+ }
+
+ if( len == hashlen && hash_id == SIG_RSA_RAW )
+ {
+ if( memcmp( p, hash, hashlen ) == 0 )
+ return( 0 );
+ else
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
}
return( POLARSSL_ERR_RSA_INVALID_PADDING );
}
/*
+ * Do an RSA operation and check the message digest
+ */
+int rsa_pkcs1_verify( rsa_context *ctx,
+ int mode,
+ int hash_id,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig )
+{
+ switch( ctx->padding )
+ {
+ case RSA_PKCS_V15:
+ return rsa_rsassa_pkcs1_v15_verify( ctx, mode, hash_id,
+ hashlen, hash, sig );
+
+#if defined(POLARSSL_PKCS1_V21)
+ case RSA_PKCS_V21:
+ return rsa_rsassa_pss_verify( ctx, mode, hash_id,
+ hashlen, hash, sig );
+#endif
+
+ default:
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ }
+}
+
+/*
* Free the components of an RSA key
*/
void rsa_free( rsa_context *ctx )
diff --git a/library/sha1.c b/library/sha1.c
index b0b6e43..1e82580 100644
--- a/library/sha1.c
+++ b/library/sha1.c
@@ -76,7 +76,7 @@
ctx->state[4] = 0xC3D2E1F0;
}
-static void sha1_process( sha1_context *ctx, const unsigned char data[64] )
+void sha1_process( sha1_context *ctx, const unsigned char data[64] )
{
uint32_t temp, W[16], A, B, C, D, E;
diff --git a/library/sha2.c b/library/sha2.c
index 0245f31..af3a6ee 100644
--- a/library/sha2.c
+++ b/library/sha2.c
@@ -97,7 +97,7 @@
ctx->is224 = is224;
}
-static void sha2_process( sha2_context *ctx, const unsigned char data[64] )
+void sha2_process( sha2_context *ctx, const unsigned char data[64] )
{
uint32_t temp1, temp2, W[64];
uint32_t A, B, C, D, E, F, G, H;
diff --git a/library/sha4.c b/library/sha4.c
index 6361a54..556cc4f 100644
--- a/library/sha4.c
+++ b/library/sha4.c
@@ -152,7 +152,7 @@
ctx->is384 = is384;
}
-static void sha4_process( sha4_context *ctx, const unsigned char data[128] )
+void sha4_process( sha4_context *ctx, const unsigned char data[128] )
{
int i;
uint64_t temp1, temp2, W[80];
diff --git a/library/ssl_cache.c b/library/ssl_cache.c
index ab948d6..f5686be 100644
--- a/library/ssl_cache.c
+++ b/library/ssl_cache.c
@@ -71,6 +71,26 @@
continue;
memcpy( session->master, entry->session.master, 48 );
+
+ /*
+ * Restore peer certificate (without rest of the original chain)
+ */
+ if( entry->peer_cert.p != NULL )
+ {
+ session->peer_cert = (x509_cert *) malloc( sizeof(x509_cert) );
+ if( session->peer_cert == NULL )
+ return( 1 );
+
+ memset( session->peer_cert, 0, sizeof(x509_cert) );
+ if( x509parse_crt( session->peer_cert, entry->peer_cert.p,
+ entry->peer_cert.len ) != 0 )
+ {
+ free( session->peer_cert );
+ session->peer_cert = NULL;
+ return( 1 );
+ }
+ }
+
return( 0 );
}
@@ -119,15 +139,20 @@
if( old != NULL && count >= cache->max_entries )
{
cur = old;
- memset( &cur->session, 0, sizeof( ssl_session ) );
+ memset( &cur->session, 0, sizeof(ssl_session) );
+ if( cur->peer_cert.p != NULL )
+ {
+ free( cur->peer_cert.p );
+ memset( &cur->peer_cert, 0, sizeof(x509_buf) );
+ }
}
else
{
- cur = (ssl_cache_entry *) malloc( sizeof( ssl_cache_entry ) );
+ cur = (ssl_cache_entry *) malloc( sizeof(ssl_cache_entry) );
if( cur == NULL )
return( 1 );
- memset( cur, 0, sizeof( ssl_cache_entry ) );
+ memset( cur, 0, sizeof(ssl_cache_entry) );
if( prv == NULL )
cache->chain = cur;
@@ -140,9 +165,21 @@
memcpy( &cur->session, session, sizeof( ssl_session ) );
- // Do not include peer_cert in cache entry
- //
- cur->session.peer_cert = NULL;
+ /*
+ * Store peer certificate
+ */
+ if( session->peer_cert != NULL )
+ {
+ cur->peer_cert.p = (unsigned char *) malloc( session->peer_cert->raw.len );
+ if( cur->peer_cert.p == NULL )
+ return( 1 );
+
+ memcpy( cur->peer_cert.p, session->peer_cert->raw.p,
+ session->peer_cert->raw.len );
+ cur->peer_cert.len = session->peer_cert->raw.len;
+
+ cur->session.peer_cert = NULL;
+ }
return( 0 );
}
@@ -173,6 +210,10 @@
cur = cur->next;
ssl_session_free( &prv->session );
+
+ if( prv->peer_cert.p != NULL )
+ free( prv->peer_cert.p );
+
free( prv );
}
}
diff --git a/library/ssl_ciphersuites.c b/library/ssl_ciphersuites.c
new file mode 100644
index 0000000..0218194
--- /dev/null
+++ b/library/ssl_ciphersuites.c
@@ -0,0 +1,408 @@
+/**
+ * \file ssl_ciphersuites.c
+ *
+ * \brief SSL ciphersuites for PolarSSL
+ *
+ * Copyright (C) 2006-2013, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "polarssl/config.h"
+
+#if defined(POLARSSL_SSL_TLS_C)
+
+#include "polarssl/ssl_ciphersuites.h"
+#include "polarssl/ssl.h"
+
+#include <stdlib.h>
+
+const int supported_ciphersuites[] =
+{
+#if defined(POLARSSL_DHM_C)
+#if defined(POLARSSL_AES_C)
+#if defined(POLARSSL_SHA2_C)
+ TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
+#endif /* POLARSSL_SHA2_C */
+#if defined(POLARSSL_GCM_C) && defined(POLARSSL_SHA4_C)
+ TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
+#endif
+ TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
+#if defined(POLARSSL_SHA2_C)
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
+#endif /* POLARSSL_SHA2_C */
+#if defined(POLARSSL_GCM_C) && defined(POLARSSL_SHA2_C)
+ TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+#endif
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+#endif /* POLARSSL_AES_C */
+#if defined(POLARSSL_CAMELLIA_C)
+#if defined(POLARSSL_SHA2_C)
+ TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
+#endif /* POLARSSL_SHA2_C */
+ TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
+#if defined(POLARSSL_SHA2_C)
+ TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
+#endif /* POLARSSL_SHA2_C */
+ TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
+#endif /* POLARSSL_CAMELLIA_C */
+#if defined(POLARSSL_DES_C)
+ TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
+#endif
+#endif /* POLARSSL_DHM_C */
+
+#if defined(POLARSSL_AES_C)
+#if defined(POLARSSL_SHA2_C)
+ TLS_RSA_WITH_AES_256_CBC_SHA256,
+#endif /* POLARSSL_SHA2_C */
+#if defined(POLARSSL_GCM_C) && defined(POLARSSL_SHA4_C)
+ TLS_RSA_WITH_AES_256_GCM_SHA384,
+#endif
+ TLS_RSA_WITH_AES_256_CBC_SHA,
+#endif /* POLARSSL_AES_C */
+#if defined(POLARSSL_CAMELLIA_C)
+#if defined(POLARSSL_SHA2_C)
+ TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
+#endif /* POLARSSL_SHA2_C */
+ TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
+#endif /* POLARSSL_CAMELLIA_C */
+#if defined(POLARSSL_AES_C)
+#if defined(POLARSSL_SHA2_C)
+ TLS_RSA_WITH_AES_128_CBC_SHA256,
+#endif /* POLARSSL_SHA2_C */
+#if defined(POLARSSL_GCM_C) && defined(POLARSSL_SHA2_C)
+ TLS_RSA_WITH_AES_128_GCM_SHA256,
+#endif /* POLARSSL_SHA2_C */
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+#endif /* POLARSSL_AES_C */
+#if defined(POLARSSL_CAMELLIA_C)
+#if defined(POLARSSL_SHA2_C)
+ TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
+#endif /* POLARSSL_SHA2_C */
+ TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
+#endif /* POLARSSL_CAMELLIA_C */
+#if defined(POLARSSL_DES_C)
+ TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+#endif /* POLARSSL_DES_C */
+#if defined(POLARSSL_ARC4_C)
+ TLS_RSA_WITH_RC4_128_SHA,
+ TLS_RSA_WITH_RC4_128_MD5,
+#endif /* POLARSSL_ARC4_C */
+#if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES)
+#if defined(POLARSSL_DES_C)
+#if defined(POLARSSL_DHM_C)
+ TLS_DHE_RSA_WITH_DES_CBC_SHA,
+#endif /* POLARSSL_DHM_C */
+ TLS_RSA_WITH_DES_CBC_SHA,
+#endif /* POLARSSL_DES_C */
+#if defined(POLARSSL_CIPHER_NULL_CIPHER)
+#if defined(POLARSSL_SHA2_C)
+ TLS_RSA_WITH_NULL_SHA256,
+#endif
+ TLS_RSA_WITH_NULL_SHA,
+ TLS_RSA_WITH_NULL_MD5,
+#endif /* POLARSSL_CIPHER_NULL_CIPHER */
+#endif /* POLARSSL_ENABLE_WEAK_CIPHERSUITES */
+ 0
+};
+
+static const ssl_ciphersuite_t ciphersuite_definitions[] =
+{
+#if defined(POLARSSL_ARC4_C)
+ { TLS_RSA_WITH_RC4_128_MD5, "TLS-RSA-WITH-RC4-128-MD5",
+ POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_MD5, POLARSSL_KEY_EXCHANGE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+
+ { TLS_RSA_WITH_RC4_128_SHA, "TLS-RSA-WITH-RC4-128-SHA",
+ POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+#endif /* POLARSSL_ARC4_C */
+
+#if defined(POLARSSL_DHM_C)
+#if defined(POLARSSL_AES_C)
+#if defined(POLARSSL_SHA4_C) && defined(POLARSSL_GCM_C)
+ { TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384",
+ POLARSSL_CIPHER_AES_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_DHE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+#endif /* POLARSSL_SHA4_C && POLARSSL_GCM_C */
+
+#if defined(POLARSSL_SHA2_C)
+#if defined(POLARSSL_GCM_C)
+ { TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, "TLS-DHE-RSA-WITH-AES-128-GCM-SHA256",
+ POLARSSL_CIPHER_AES_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+#endif /* POLARSSL_GCM_C */
+
+ { TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, "TLS-DHE-RSA-WITH-AES-128-CBC-SHA256",
+ POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+
+ { TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256",
+ POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+#endif /* POLARSSL_SHA2_C */
+
+ { TLS_DHE_RSA_WITH_AES_128_CBC_SHA, "TLS-DHE-RSA-WITH-AES-128-CBC-SHA",
+ POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_DHE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+
+ { TLS_DHE_RSA_WITH_AES_256_CBC_SHA, "TLS-DHE-RSA-WITH-AES-256-CBC-SHA",
+ POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_DHE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+#endif /* POLARSSL_AES_C */
+
+#if defined(POLARSSL_CAMELLIA_C)
+#if defined(POLARSSL_SHA2_C)
+ { TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256",
+ POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+
+ { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256",
+ POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+#endif /* POLARSSL_SHA2_C */
+
+ { TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA",
+ POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_DHE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+
+ { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA",
+ POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_DHE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+#endif /* POLARSSL_CAMELLIA_C */
+
+#if defined(POLARSSL_DES_C)
+ { TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA",
+ POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_DHE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+#endif /* POLARSSL_DES_C */
+#endif /* POLARSSL_DHM_C */
+
+#if defined(POLARSSL_AES_C)
+#if defined(POLARSSL_SHA4_C) && defined(POLARSSL_GCM_C)
+ { TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS-RSA-WITH-AES-256-GCM-SHA384",
+ POLARSSL_CIPHER_AES_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+#endif /* POLARSSL_SHA4_C && POLARSSL_GCM_C */
+
+#if defined(POLARSSL_SHA2_C)
+#if defined(POLARSSL_GCM_C)
+ { TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS-RSA-WITH-AES-128-GCM-SHA256",
+ POLARSSL_CIPHER_AES_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+#endif /* POLARSSL_GCM_C */
+
+ { TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS-RSA-WITH-AES-128-CBC-SHA256",
+ POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+
+ { TLS_RSA_WITH_AES_256_CBC_SHA256, "TLS-RSA-WITH-AES-256-CBC-SHA256",
+ POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+#endif /* POLARSSL_SHA2_C */
+
+ { TLS_RSA_WITH_AES_128_CBC_SHA, "TLS-RSA-WITH-AES-128-CBC-SHA",
+ POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+
+ { TLS_RSA_WITH_AES_256_CBC_SHA, "TLS-RSA-WITH-AES-256-CBC-SHA",
+ POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+#endif /* POLARSSL_AES_C */
+
+#if defined(POLARSSL_CAMELLIA_C)
+#if defined(POLARSSL_SHA2_C)
+ { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256",
+ POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+
+ { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256",
+ POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+#endif /* POLARSSL_SHA2_C */
+
+ { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA",
+ POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+
+ { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA",
+ POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+#endif /* POLARSSL_CAMELLIA_C */
+
+#if defined(POLARSSL_DES_C)
+ { TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-RSA-WITH-3DES-EDE-CBC-SHA",
+ POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ 0 },
+#endif /* POLARSSL_DES_C */
+
+#if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES)
+#if defined(POLARSSL_CIPHER_NULL_CIPHER)
+ { TLS_RSA_WITH_NULL_MD5, "TLS-RSA-WITH-NULL-MD5",
+ POLARSSL_CIPHER_NULL, POLARSSL_MD_MD5, POLARSSL_KEY_EXCHANGE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ POLARSSL_CIPHERSUITE_WEAK },
+
+ { TLS_RSA_WITH_NULL_SHA, "TLS-RSA-WITH-NULL-SHA",
+ POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ POLARSSL_CIPHERSUITE_WEAK },
+
+ { TLS_RSA_WITH_NULL_SHA256, "TLS-RSA-WITH-NULL-SHA256",
+ POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ POLARSSL_CIPHERSUITE_WEAK },
+#endif /* POLARSSL_CIPHER_NULL_CIPHER */
+
+#if defined(POLARSSL_DES_C)
+#if defined(POLARSSL_DHM_C)
+ { TLS_DHE_RSA_WITH_DES_CBC_SHA, "TLS-DHE-RSA-WITH-DES-CBC-SHA",
+ POLARSSL_CIPHER_DES_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_DHE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ POLARSSL_CIPHERSUITE_WEAK },
+#endif /* POLARSSL_DHM_C */
+
+ { TLS_RSA_WITH_DES_CBC_SHA, "TLS-RSA-WITH-DES-CBC-SHA",
+ POLARSSL_CIPHER_DES_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
+ SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+ POLARSSL_CIPHERSUITE_WEAK },
+#endif /* POLARSSL_DES_C */
+
+#endif /* POLARSSL_ENABLE_WEAK_CIPHERSUITES */
+
+ { 0, "", 0, 0, 0, 0, 0, 0, 0, 0 }
+};
+
+const int *ssl_list_ciphersuites( void )
+{
+ return supported_ciphersuites;
+};
+
+const ssl_ciphersuite_t *ssl_ciphersuite_from_string( const char *ciphersuite_name )
+{
+ const ssl_ciphersuite_t *cur = ciphersuite_definitions;
+
+ if( NULL == ciphersuite_name )
+ return( NULL );
+
+ while( cur->id != 0 )
+ {
+ if( 0 == strcasecmp( cur->name, ciphersuite_name ) )
+ return( cur );
+
+ cur++;
+ }
+
+ return( NULL );
+}
+
+const ssl_ciphersuite_t *ssl_ciphersuite_from_id( int ciphersuite )
+{
+ const ssl_ciphersuite_t *cur = ciphersuite_definitions;
+
+ while( cur->id != 0 )
+ {
+ if( cur->id == ciphersuite )
+ return( cur );
+
+ cur++;
+ }
+
+ return( NULL );
+}
+
+const char *ssl_get_ciphersuite_name( const int ciphersuite_id )
+{
+ const ssl_ciphersuite_t *cur;
+
+ cur = ssl_ciphersuite_from_id( ciphersuite_id );
+
+ if( cur == NULL )
+ return( "unknown" );
+
+ return( cur->name );
+}
+
+int ssl_get_ciphersuite_id( const char *ciphersuite_name )
+{
+ const ssl_ciphersuite_t *cur;
+
+ cur = ssl_ciphersuite_from_string( ciphersuite_name );
+
+ if( cur == NULL )
+ return( 0 );
+
+ return( cur->id );
+}
+
+#endif
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index a716710..c426fa8 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1,7 +1,7 @@
/*
* SSLv3/TLSv1 client-side functions
*
- * Copyright (C) 2006-2012, Brainspark B.V.
+ * Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
@@ -473,6 +473,14 @@
* Initialize update checksum functions
*/
ssl_optimize_checksum( ssl, i );
+ ssl->transform_negotiate->ciphersuite_info = ssl_ciphersuite_from_id( i );
+
+ if( ssl->transform_negotiate->ciphersuite_info == NULL )
+ {
+ SSL_DEBUG_MSG( 1, ( "ciphersuite info for %02x not found",
+ ssl->ciphersuites[i] ) );
+ return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
+ }
SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
SSL_DEBUG_BUF( 3, "server hello, session id", buf + 39, n );
@@ -636,18 +644,8 @@
SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
- if( ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_DES_CBC_SHA &&
- ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA &&
- ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_AES_128_CBC_SHA &&
- ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_AES_256_CBC_SHA &&
- ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 &&
- ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 &&
- ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA &&
- ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA &&
- ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 &&
- ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 &&
- ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 &&
- ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 )
+ if( ssl->transform_negotiate->ciphersuite_info->key_exchange !=
+ POLARSSL_KEY_EXCHANGE_DHE_RSA )
{
SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
ssl->state++;
@@ -894,7 +892,7 @@
{
int ret;
unsigned char *buf, *p;
- size_t n = 0;
+ size_t n = 0, m = 0;
size_t cert_type_len = 0, sig_alg_len = 0, dn_len = 0;
SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
@@ -976,6 +974,7 @@
| ( buf[6 + n] ) );
p = buf + 7 + n;
+ m += 2;
n += sig_alg_len;
if( ssl->in_hslen < 6 + n )
@@ -985,11 +984,11 @@
}
}
- dn_len = ( ( buf[7 + n] << 8 )
- | ( buf[8 + n] ) );
+ dn_len = ( ( buf[5 + m + n] << 8 )
+ | ( buf[6 + m + n] ) );
n += dn_len;
- if( ssl->in_hslen != 9 + n )
+ if( ssl->in_hslen != 7 + m + n )
{
SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
@@ -1043,18 +1042,8 @@
SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) );
- if( ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_DES_CBC_SHA ||
- ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA ||
- ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_AES_128_CBC_SHA ||
- ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_AES_256_CBC_SHA ||
- ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 ||
- ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 ||
- ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA ||
- ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA ||
- ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 ||
- ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 ||
- ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 ||
- ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 )
+ if( ssl->transform_negotiate->ciphersuite_info->key_exchange ==
+ POLARSSL_KEY_EXCHANGE_DHE_RSA )
{
#if !defined(POLARSSL_DHM_C)
SSL_DEBUG_MSG( 1, ( "support for dhm in not available" ) );
@@ -1273,121 +1262,113 @@
}
/*
- * SSL handshake -- client side
+ * SSL handshake -- client side -- single step
*/
-int ssl_handshake_client( ssl_context *ssl )
+int ssl_handshake_client_step( ssl_context *ssl )
{
int ret = 0;
- SSL_DEBUG_MSG( 2, ( "=> handshake client" ) );
+ if( ssl->state == SSL_HANDSHAKE_OVER )
+ return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
- while( ssl->state != SSL_HANDSHAKE_OVER )
+ SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
+
+ if( ( ret = ssl_flush_output( ssl ) ) != 0 )
+ return( ret );
+
+ switch( ssl->state )
{
- SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
-
- if( ( ret = ssl_flush_output( ssl ) ) != 0 )
+ case SSL_HELLO_REQUEST:
+ ssl->state = SSL_CLIENT_HELLO;
break;
- switch( ssl->state )
- {
- case SSL_HELLO_REQUEST:
- ssl->state = SSL_CLIENT_HELLO;
- break;
+ /*
+ * ==> ClientHello
+ */
+ case SSL_CLIENT_HELLO:
+ ret = ssl_write_client_hello( ssl );
+ break;
- /*
- * ==> ClientHello
- */
- case SSL_CLIENT_HELLO:
- ret = ssl_write_client_hello( ssl );
- break;
+ /*
+ * <== ServerHello
+ * Certificate
+ * ( ServerKeyExchange )
+ * ( CertificateRequest )
+ * ServerHelloDone
+ */
+ case SSL_SERVER_HELLO:
+ ret = ssl_parse_server_hello( ssl );
+ break;
- /*
- * <== ServerHello
- * Certificate
- * ( ServerKeyExchange )
- * ( CertificateRequest )
- * ServerHelloDone
- */
- case SSL_SERVER_HELLO:
- ret = ssl_parse_server_hello( ssl );
- break;
+ case SSL_SERVER_CERTIFICATE:
+ ret = ssl_parse_certificate( ssl );
+ break;
- case SSL_SERVER_CERTIFICATE:
- ret = ssl_parse_certificate( ssl );
- break;
+ case SSL_SERVER_KEY_EXCHANGE:
+ ret = ssl_parse_server_key_exchange( ssl );
+ break;
- case SSL_SERVER_KEY_EXCHANGE:
- ret = ssl_parse_server_key_exchange( ssl );
- break;
+ case SSL_CERTIFICATE_REQUEST:
+ ret = ssl_parse_certificate_request( ssl );
+ break;
- case SSL_CERTIFICATE_REQUEST:
- ret = ssl_parse_certificate_request( ssl );
- break;
+ case SSL_SERVER_HELLO_DONE:
+ ret = ssl_parse_server_hello_done( ssl );
+ break;
- case SSL_SERVER_HELLO_DONE:
- ret = ssl_parse_server_hello_done( ssl );
- break;
+ /*
+ * ==> ( Certificate/Alert )
+ * ClientKeyExchange
+ * ( CertificateVerify )
+ * ChangeCipherSpec
+ * Finished
+ */
+ case SSL_CLIENT_CERTIFICATE:
+ ret = ssl_write_certificate( ssl );
+ break;
- /*
- * ==> ( Certificate/Alert )
- * ClientKeyExchange
- * ( CertificateVerify )
- * ChangeCipherSpec
- * Finished
- */
- case SSL_CLIENT_CERTIFICATE:
- ret = ssl_write_certificate( ssl );
- break;
+ case SSL_CLIENT_KEY_EXCHANGE:
+ ret = ssl_write_client_key_exchange( ssl );
+ break;
- case SSL_CLIENT_KEY_EXCHANGE:
- ret = ssl_write_client_key_exchange( ssl );
- break;
+ case SSL_CERTIFICATE_VERIFY:
+ ret = ssl_write_certificate_verify( ssl );
+ break;
- case SSL_CERTIFICATE_VERIFY:
- ret = ssl_write_certificate_verify( ssl );
- break;
+ case SSL_CLIENT_CHANGE_CIPHER_SPEC:
+ ret = ssl_write_change_cipher_spec( ssl );
+ break;
- case SSL_CLIENT_CHANGE_CIPHER_SPEC:
- ret = ssl_write_change_cipher_spec( ssl );
- break;
+ case SSL_CLIENT_FINISHED:
+ ret = ssl_write_finished( ssl );
+ break;
- case SSL_CLIENT_FINISHED:
- ret = ssl_write_finished( ssl );
- break;
+ /*
+ * <== ChangeCipherSpec
+ * Finished
+ */
+ case SSL_SERVER_CHANGE_CIPHER_SPEC:
+ ret = ssl_parse_change_cipher_spec( ssl );
+ break;
- /*
- * <== ChangeCipherSpec
- * Finished
- */
- case SSL_SERVER_CHANGE_CIPHER_SPEC:
- ret = ssl_parse_change_cipher_spec( ssl );
- break;
+ case SSL_SERVER_FINISHED:
+ ret = ssl_parse_finished( ssl );
+ break;
- case SSL_SERVER_FINISHED:
- ret = ssl_parse_finished( ssl );
- break;
+ case SSL_FLUSH_BUFFERS:
+ SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
+ ssl->state = SSL_HANDSHAKE_WRAPUP;
+ break;
- case SSL_FLUSH_BUFFERS:
- SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
- ssl->state = SSL_HANDSHAKE_WRAPUP;
- break;
+ case SSL_HANDSHAKE_WRAPUP:
+ ssl_handshake_wrapup( ssl );
+ break;
- case SSL_HANDSHAKE_WRAPUP:
- ssl_handshake_wrapup( ssl );
- break;
-
- default:
- SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
- return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
- }
-
- if( ret != 0 )
- break;
- }
-
- SSL_DEBUG_MSG( 2, ( "<= handshake client" ) );
+ default:
+ SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
+ return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
+ }
return( ret );
}
-
#endif
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 3825393..c5788ac 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -1,7 +1,7 @@
/*
* SSLv3/TLSv1 server-side functions
*
- * Copyright (C) 2006-2012, Brainspark B.V.
+ * Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
@@ -191,6 +191,216 @@
return( 0 );
}
+#if defined(POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO)
+static int ssl_parse_client_hello_v2( ssl_context *ssl )
+{
+ int ret;
+ unsigned int i, j;
+ size_t n;
+ unsigned int ciph_len, sess_len, chal_len;
+ unsigned char *buf, *p;
+
+ SSL_DEBUG_MSG( 2, ( "=> parse client hello v2" ) );
+
+ if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE )
+ {
+ SSL_DEBUG_MSG( 1, ( "client hello v2 illegal for renegotiation" ) );
+
+ if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
+ return( ret );
+
+ return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+
+ buf = ssl->in_hdr;
+
+ SSL_DEBUG_BUF( 4, "record header", buf, 5 );
+
+ SSL_DEBUG_MSG( 3, ( "client hello v2, message type: %d",
+ buf[2] ) );
+ SSL_DEBUG_MSG( 3, ( "client hello v2, message len.: %d",
+ ( ( buf[0] & 0x7F ) << 8 ) | buf[1] ) );
+ SSL_DEBUG_MSG( 3, ( "client hello v2, max. version: [%d:%d]",
+ buf[3], buf[4] ) );
+
+ /*
+ * SSLv2 Client Hello
+ *
+ * Record layer:
+ * 0 . 1 message length
+ *
+ * SSL layer:
+ * 2 . 2 message type
+ * 3 . 4 protocol version
+ */
+ if( buf[2] != SSL_HS_CLIENT_HELLO ||
+ buf[3] != SSL_MAJOR_VERSION_3 )
+ {
+ SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+ return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+
+ n = ( ( buf[0] << 8 ) | buf[1] ) & 0x7FFF;
+
+ if( n < 17 || n > 512 )
+ {
+ SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+ return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+
+ ssl->major_ver = SSL_MAJOR_VERSION_3;
+ ssl->minor_ver = ( buf[4] <= SSL_MINOR_VERSION_3 )
+ ? buf[4] : SSL_MINOR_VERSION_3;
+
+ if( ssl->minor_ver < ssl->min_minor_ver )
+ {
+ SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum"
+ " [%d:%d] < [%d:%d]", ssl->major_ver, ssl->minor_ver,
+ ssl->min_major_ver, ssl->min_minor_ver ) );
+
+ ssl_send_alert_message( ssl, SSL_ALERT_LEVEL_FATAL,
+ SSL_ALERT_MSG_PROTOCOL_VERSION );
+ return( POLARSSL_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
+ }
+
+ ssl->max_major_ver = buf[3];
+ ssl->max_minor_ver = buf[4];
+
+ if( ( ret = ssl_fetch_input( ssl, 2 + n ) ) != 0 )
+ {
+ SSL_DEBUG_RET( 1, "ssl_fetch_input", ret );
+ return( ret );
+ }
+
+ ssl->handshake->update_checksum( ssl, buf + 2, n );
+
+ buf = ssl->in_msg;
+ n = ssl->in_left - 5;
+
+ /*
+ * 0 . 1 ciphersuitelist length
+ * 2 . 3 session id length
+ * 4 . 5 challenge length
+ * 6 . .. ciphersuitelist
+ * .. . .. session id
+ * .. . .. challenge
+ */
+ SSL_DEBUG_BUF( 4, "record contents", buf, n );
+
+ ciph_len = ( buf[0] << 8 ) | buf[1];
+ sess_len = ( buf[2] << 8 ) | buf[3];
+ chal_len = ( buf[4] << 8 ) | buf[5];
+
+ SSL_DEBUG_MSG( 3, ( "ciph_len: %d, sess_len: %d, chal_len: %d",
+ ciph_len, sess_len, chal_len ) );
+
+ /*
+ * Make sure each parameter length is valid
+ */
+ if( ciph_len < 3 || ( ciph_len % 3 ) != 0 )
+ {
+ SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+ return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+
+ if( sess_len > 32 )
+ {
+ SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+ return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+
+ if( chal_len < 8 || chal_len > 32 )
+ {
+ SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+ return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+
+ if( n != 6 + ciph_len + sess_len + chal_len )
+ {
+ SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+ return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+
+ SSL_DEBUG_BUF( 3, "client hello, ciphersuitelist",
+ buf + 6, ciph_len );
+ SSL_DEBUG_BUF( 3, "client hello, session id",
+ buf + 6 + ciph_len, sess_len );
+ SSL_DEBUG_BUF( 3, "client hello, challenge",
+ buf + 6 + ciph_len + sess_len, chal_len );
+
+ p = buf + 6 + ciph_len;
+ ssl->session_negotiate->length = sess_len;
+ memset( ssl->session_negotiate->id, 0, sizeof( ssl->session_negotiate->id ) );
+ memcpy( ssl->session_negotiate->id, p, ssl->session_negotiate->length );
+
+ p += sess_len;
+ memset( ssl->handshake->randbytes, 0, 64 );
+ memcpy( ssl->handshake->randbytes + 32 - chal_len, p, chal_len );
+
+ /*
+ * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV
+ */
+ for( i = 0, p = buf + 6; i < ciph_len; i += 3, p += 3 )
+ {
+ if( p[0] == 0 && p[1] == 0 && p[2] == SSL_EMPTY_RENEGOTIATION_INFO )
+ {
+ SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) );
+ if( ssl->renegotiation == SSL_RENEGOTIATION )
+ {
+ SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV during renegotiation" ) );
+
+ if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
+ return( ret );
+
+ return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+ ssl->secure_renegotiation = SSL_SECURE_RENEGOTIATION;
+ break;
+ }
+ }
+
+ for( i = 0; ssl->ciphersuites[i] != 0; i++ )
+ {
+ for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 )
+ {
+ if( p[0] == 0 &&
+ p[1] == 0 &&
+ p[2] == ssl->ciphersuites[i] )
+ goto have_ciphersuite_v2;
+ }
+ }
+
+ SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) );
+
+ return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN );
+
+have_ciphersuite_v2:
+ ssl->session_negotiate->ciphersuite = ssl->ciphersuites[i];
+ ssl_optimize_checksum( ssl, ssl->session_negotiate->ciphersuite );
+
+ /*
+ * SSLv2 Client Hello relevant renegotiation security checks
+ */
+ if( ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION &&
+ ssl->allow_legacy_renegotiation == SSL_LEGACY_BREAK_HANDSHAKE )
+ {
+ SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
+
+ if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
+ return( ret );
+
+ return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+
+ ssl->in_left = 0;
+ ssl->state++;
+
+ SSL_DEBUG_MSG( 2, ( "<= parse client hello v2" ) );
+
+ return( 0 );
+}
+#endif /* POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */
+
static int ssl_parse_client_hello( ssl_context *ssl )
{
int ret;
@@ -214,6 +424,11 @@
buf = ssl->in_hdr;
+#if defined(POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO)
+ if( ( buf[0] & 0x80 ) != 0 )
+ return ssl_parse_client_hello_v2( ssl );
+#endif
+
SSL_DEBUG_BUF( 4, "record header", buf, 5 );
SSL_DEBUG_MSG( 3, ( "client hello v3, message type: %d",
@@ -443,6 +658,16 @@
have_ciphersuite:
ssl->session_negotiate->ciphersuite = ssl->ciphersuites[i];
+ ssl->transform_negotiate->ciphersuite_info =
+ ssl_ciphersuite_from_id( ssl->ciphersuites[i] );
+
+ if( ssl->transform_negotiate->ciphersuite_info == NULL )
+ {
+ SSL_DEBUG_MSG( 1, ( "ciphersuite info for %02x not found",
+ ssl->ciphersuites[i] ) );
+ return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
+ }
+
ssl_optimize_checksum( ssl, ssl->session_negotiate->ciphersuite );
ext = buf + 44 + sess_len + ciph_len + comp_len;
@@ -796,18 +1021,8 @@
SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
- if( ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_DES_CBC_SHA &&
- ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA &&
- ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_AES_128_CBC_SHA &&
- ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_AES_256_CBC_SHA &&
- ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 &&
- ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 &&
- ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA &&
- ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA &&
- ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 &&
- ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 &&
- ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 &&
- ssl->session_negotiate->ciphersuite != TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 )
+ if( ssl->transform_negotiate->ciphersuite_info->key_exchange !=
+ POLARSSL_KEY_EXCHANGE_DHE_RSA )
{
SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) );
ssl->state++;
@@ -1073,18 +1288,8 @@
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
}
- if( ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_DES_CBC_SHA ||
- ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA ||
- ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_AES_128_CBC_SHA ||
- ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_AES_256_CBC_SHA ||
- ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 ||
- ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 ||
- ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA ||
- ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA ||
- ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 ||
- ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 ||
- ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 ||
- ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 )
+ if( ssl->transform_negotiate->ciphersuite_info->key_exchange ==
+ POLARSSL_KEY_EXCHANGE_DHE_RSA )
{
#if !defined(POLARSSL_DHM_C)
SSL_DEBUG_MSG( 1, ( "support for dhm is not available" ) );
@@ -1293,121 +1498,113 @@
}
/*
- * SSL handshake -- server side
+ * SSL handshake -- server side -- single step
*/
-int ssl_handshake_server( ssl_context *ssl )
+int ssl_handshake_server_step( ssl_context *ssl )
{
int ret = 0;
- SSL_DEBUG_MSG( 2, ( "=> handshake server" ) );
+ if( ssl->state == SSL_HANDSHAKE_OVER )
+ return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
- while( ssl->state != SSL_HANDSHAKE_OVER )
+ SSL_DEBUG_MSG( 2, ( "server state: %d", ssl->state ) );
+
+ if( ( ret = ssl_flush_output( ssl ) ) != 0 )
+ return( ret );
+
+ switch( ssl->state )
{
- SSL_DEBUG_MSG( 2, ( "server state: %d", ssl->state ) );
-
- if( ( ret = ssl_flush_output( ssl ) ) != 0 )
+ case SSL_HELLO_REQUEST:
+ ssl->state = SSL_CLIENT_HELLO;
break;
- switch( ssl->state )
- {
- case SSL_HELLO_REQUEST:
- ssl->state = SSL_CLIENT_HELLO;
- break;
-
- /*
- * <== ClientHello
- */
- case SSL_CLIENT_HELLO:
- ret = ssl_parse_client_hello( ssl );
- break;
-
- /*
- * ==> ServerHello
- * Certificate
- * ( ServerKeyExchange )
- * ( CertificateRequest )
- * ServerHelloDone
- */
- case SSL_SERVER_HELLO:
- ret = ssl_write_server_hello( ssl );
- break;
-
- case SSL_SERVER_CERTIFICATE:
- ret = ssl_write_certificate( ssl );
- break;
-
- case SSL_SERVER_KEY_EXCHANGE:
- ret = ssl_write_server_key_exchange( ssl );
- break;
-
- case SSL_CERTIFICATE_REQUEST:
- ret = ssl_write_certificate_request( ssl );
- break;
-
- case SSL_SERVER_HELLO_DONE:
- ret = ssl_write_server_hello_done( ssl );
- break;
-
- /*
- * <== ( Certificate/Alert )
- * ClientKeyExchange
- * ( CertificateVerify )
- * ChangeCipherSpec
- * Finished
- */
- case SSL_CLIENT_CERTIFICATE:
- ret = ssl_parse_certificate( ssl );
- break;
-
- case SSL_CLIENT_KEY_EXCHANGE:
- ret = ssl_parse_client_key_exchange( ssl );
- break;
-
- case SSL_CERTIFICATE_VERIFY:
- ret = ssl_parse_certificate_verify( ssl );
- break;
-
- case SSL_CLIENT_CHANGE_CIPHER_SPEC:
- ret = ssl_parse_change_cipher_spec( ssl );
- break;
-
- case SSL_CLIENT_FINISHED:
- ret = ssl_parse_finished( ssl );
- break;
-
- /*
- * ==> ChangeCipherSpec
- * Finished
- */
- case SSL_SERVER_CHANGE_CIPHER_SPEC:
- ret = ssl_write_change_cipher_spec( ssl );
- break;
-
- case SSL_SERVER_FINISHED:
- ret = ssl_write_finished( ssl );
- break;
-
- case SSL_FLUSH_BUFFERS:
- SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
- ssl->state = SSL_HANDSHAKE_WRAPUP;
- break;
-
- case SSL_HANDSHAKE_WRAPUP:
- ssl_handshake_wrapup( ssl );
- break;
-
- default:
- SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
- return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
- }
-
- if( ret != 0 )
+ /*
+ * <== ClientHello
+ */
+ case SSL_CLIENT_HELLO:
+ ret = ssl_parse_client_hello( ssl );
break;
+
+ /*
+ * ==> ServerHello
+ * Certificate
+ * ( ServerKeyExchange )
+ * ( CertificateRequest )
+ * ServerHelloDone
+ */
+ case SSL_SERVER_HELLO:
+ ret = ssl_write_server_hello( ssl );
+ break;
+
+ case SSL_SERVER_CERTIFICATE:
+ ret = ssl_write_certificate( ssl );
+ break;
+
+ case SSL_SERVER_KEY_EXCHANGE:
+ ret = ssl_write_server_key_exchange( ssl );
+ break;
+
+ case SSL_CERTIFICATE_REQUEST:
+ ret = ssl_write_certificate_request( ssl );
+ break;
+
+ case SSL_SERVER_HELLO_DONE:
+ ret = ssl_write_server_hello_done( ssl );
+ break;
+
+ /*
+ * <== ( Certificate/Alert )
+ * ClientKeyExchange
+ * ( CertificateVerify )
+ * ChangeCipherSpec
+ * Finished
+ */
+ case SSL_CLIENT_CERTIFICATE:
+ ret = ssl_parse_certificate( ssl );
+ break;
+
+ case SSL_CLIENT_KEY_EXCHANGE:
+ ret = ssl_parse_client_key_exchange( ssl );
+ break;
+
+ case SSL_CERTIFICATE_VERIFY:
+ ret = ssl_parse_certificate_verify( ssl );
+ break;
+
+ case SSL_CLIENT_CHANGE_CIPHER_SPEC:
+ ret = ssl_parse_change_cipher_spec( ssl );
+ break;
+
+ case SSL_CLIENT_FINISHED:
+ ret = ssl_parse_finished( ssl );
+ break;
+
+ /*
+ * ==> ChangeCipherSpec
+ * Finished
+ */
+ case SSL_SERVER_CHANGE_CIPHER_SPEC:
+ ret = ssl_write_change_cipher_spec( ssl );
+ break;
+
+ case SSL_SERVER_FINISHED:
+ ret = ssl_write_finished( ssl );
+ break;
+
+ case SSL_FLUSH_BUFFERS:
+ SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
+ ssl->state = SSL_HANDSHAKE_WRAPUP;
+ break;
+
+ case SSL_HANDSHAKE_WRAPUP:
+ ssl_handshake_wrapup( ssl );
+ break;
+
+ default:
+ SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
+ return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
}
- SSL_DEBUG_MSG( 2, ( "<= handshake server" ) );
-
return( ret );
}
-
#endif
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index e0a64ab..08880be 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1,7 +1,7 @@
/*
* SSLv3/TLSv1 shared functions
*
- * Copyright (C) 2006-2012, Brainspark B.V.
+ * Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
@@ -57,8 +57,12 @@
#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,
+ size_t keylen,
const unsigned char *iv_enc, const unsigned char *iv_dec,
- const unsigned char *mac_enc, const unsigned char *mac_dec) = NULL;
+ size_t ivlen,
+ const unsigned char *mac_enc, const unsigned char *mac_dec,
+ size_t maclen) = NULL;
+int (*ssl_hw_record_activate)(ssl_context *ssl, int direction) = 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;
@@ -298,13 +302,34 @@
unsigned char keyblk[256];
unsigned char *key1;
unsigned char *key2;
+ unsigned char *mac_enc;
+ unsigned char *mac_dec;
unsigned int iv_copy_len;
+ const cipher_info_t *cipher_info;
+ const md_info_t *md_info;
+
ssl_session *session = ssl->session_negotiate;
ssl_transform *transform = ssl->transform_negotiate;
ssl_handshake_params *handshake = ssl->handshake;
SSL_DEBUG_MSG( 2, ( "=> derive keys" ) );
+ cipher_info = cipher_info_from_type( transform->ciphersuite_info->cipher );
+ if( cipher_info == NULL )
+ {
+ SSL_DEBUG_MSG( 1, ( "cipher info for %d not found",
+ transform->ciphersuite_info->cipher ) );
+ return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
+ }
+
+ md_info = md_info_from_type( transform->ciphersuite_info->mac );
+ if( md_info == NULL )
+ {
+ SSL_DEBUG_MSG( 1, ( "md info for %d not found",
+ transform->ciphersuite_info->mac ) );
+ return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
+ }
+
/*
* Set appropriate PRF function and other SSL / TLS / TLS1.2 functions
*/
@@ -394,130 +419,38 @@
/*
* Determine the appropriate key, IV and MAC length.
*/
- switch( session->ciphersuite )
+
+ if( cipher_info->mode == POLARSSL_MODE_GCM )
{
-#if defined(POLARSSL_ARC4_C)
- case TLS_RSA_WITH_RC4_128_MD5:
- transform->keylen = 16; transform->minlen = 16;
- transform->ivlen = 0; transform->maclen = 16;
- break;
+ transform->keylen = cipher_info->key_length;
+ transform->keylen /= 8;
+ transform->minlen = 1;
+ transform->ivlen = 12;
+ transform->fixed_ivlen = 4;
+ transform->maclen = 0;
+ }
+ else
+ {
+ if( md_info->type != POLARSSL_MD_NONE )
+ {
+ md_init_ctx( &transform->md_ctx_enc, md_info );
+ md_init_ctx( &transform->md_ctx_dec, md_info );
- case TLS_RSA_WITH_RC4_128_SHA:
- transform->keylen = 16; transform->minlen = 20;
- transform->ivlen = 0; transform->maclen = 20;
- break;
-#endif
+ transform->maclen = md_get_size( md_info );
+ }
-#if defined(POLARSSL_DES_C)
- case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
- case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
- transform->keylen = 24; transform->minlen = 24;
- transform->ivlen = 8; transform->maclen = 20;
- break;
-#endif
+ transform->keylen = cipher_info->key_length;
+ transform->keylen /= 8;
+ transform->ivlen = cipher_info->iv_size;
-#if defined(POLARSSL_AES_C)
- case TLS_RSA_WITH_AES_128_CBC_SHA:
- case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
- transform->keylen = 16; transform->minlen = 32;
- transform->ivlen = 16; transform->maclen = 20;
- break;
-
- case TLS_RSA_WITH_AES_256_CBC_SHA:
- case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
- transform->keylen = 32; transform->minlen = 32;
- transform->ivlen = 16; transform->maclen = 20;
- break;
-
-#if defined(POLARSSL_SHA2_C)
- case TLS_RSA_WITH_AES_128_CBC_SHA256:
- case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
- transform->keylen = 16; transform->minlen = 32;
- transform->ivlen = 16; transform->maclen = 32;
- break;
-
- case TLS_RSA_WITH_AES_256_CBC_SHA256:
- case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
- transform->keylen = 32; transform->minlen = 32;
- transform->ivlen = 16; transform->maclen = 32;
- break;
-#endif
-#if defined(POLARSSL_GCM_C)
- case TLS_RSA_WITH_AES_128_GCM_SHA256:
- case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
- transform->keylen = 16; transform->minlen = 1;
- transform->ivlen = 12; transform->maclen = 0;
- transform->fixed_ivlen = 4;
- break;
-
- case TLS_RSA_WITH_AES_256_GCM_SHA384:
- case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
- transform->keylen = 32; transform->minlen = 1;
- transform->ivlen = 12; transform->maclen = 0;
- transform->fixed_ivlen = 4;
- break;
-#endif
-#endif
-
-#if defined(POLARSSL_CAMELLIA_C)
- case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA:
- case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA:
- transform->keylen = 16; transform->minlen = 32;
- transform->ivlen = 16; transform->maclen = 20;
- break;
-
- case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA:
- case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA:
- transform->keylen = 32; transform->minlen = 32;
- transform->ivlen = 16; transform->maclen = 20;
- break;
-
-#if defined(POLARSSL_SHA2_C)
- case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- transform->keylen = 16; transform->minlen = 32;
- transform->ivlen = 16; transform->maclen = 32;
- break;
-
- case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- transform->keylen = 32; transform->minlen = 32;
- transform->ivlen = 16; transform->maclen = 32;
- break;
-#endif
-#endif
-
-#if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES)
-#if defined(POLARSSL_CIPHER_NULL_CIPHER)
- case TLS_RSA_WITH_NULL_MD5:
- transform->keylen = 0; transform->minlen = 0;
- transform->ivlen = 0; transform->maclen = 16;
- break;
-
- case TLS_RSA_WITH_NULL_SHA:
- transform->keylen = 0; transform->minlen = 0;
- transform->ivlen = 0; transform->maclen = 20;
- break;
-
- case TLS_RSA_WITH_NULL_SHA256:
- transform->keylen = 0; transform->minlen = 0;
- transform->ivlen = 0; transform->maclen = 32;
- break;
-#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
-
-#if defined(POLARSSL_DES_C)
- case TLS_RSA_WITH_DES_CBC_SHA:
- case TLS_DHE_RSA_WITH_DES_CBC_SHA:
- transform->keylen = 8; transform->minlen = 8;
- transform->ivlen = 8; transform->maclen = 20;
- break;
-#endif
-#endif /* defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES) */
-
- default:
- SSL_DEBUG_MSG( 1, ( "ciphersuite %s is not available",
- ssl_get_ciphersuite_name( session->ciphersuite ) ) );
- return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
+ transform->minlen = transform->keylen;
+ if( transform->minlen < transform->maclen )
+ {
+ if( cipher_info->mode == POLARSSL_MODE_STREAM )
+ transform->minlen = transform->maclen;
+ else
+ transform->minlen += transform->keylen;
+ }
}
SSL_DEBUG_MSG( 3, ( "keylen: %d, minlen: %d, ivlen: %d, maclen: %d",
@@ -532,9 +465,8 @@
key1 = keyblk + transform->maclen * 2;
key2 = keyblk + transform->maclen * 2 + transform->keylen;
- memcpy( transform->mac_enc, keyblk, transform->maclen );
- memcpy( transform->mac_dec, keyblk + transform->maclen,
- transform->maclen );
+ mac_enc = keyblk;
+ mac_dec = keyblk + transform->maclen;
/*
* This is not used in TLS v1.1.
@@ -550,9 +482,8 @@
key1 = keyblk + transform->maclen * 2 + transform->keylen;
key2 = keyblk + transform->maclen * 2;
- memcpy( transform->mac_dec, keyblk, transform->maclen );
- memcpy( transform->mac_enc, keyblk + transform->maclen,
- transform->maclen );
+ mac_enc = keyblk + transform->maclen;
+ mac_dec = keyblk;
/*
* This is not used in TLS v1.1.
@@ -564,6 +495,17 @@
iv_copy_len );
}
+ if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
+ {
+ memcpy( transform->mac_enc, mac_enc, transform->maclen );
+ memcpy( transform->mac_dec, mac_dec, transform->maclen );
+ }
+ else
+ {
+ md_hmac_starts( &transform->md_ctx_enc, mac_enc, transform->maclen );
+ md_hmac_starts( &transform->md_ctx_dec, mac_dec, transform->maclen );
+ }
+
#if defined(POLARSSL_SSL_HW_RECORD_ACCEL)
if( ssl_hw_record_init != NULL)
{
@@ -571,9 +513,11 @@
SSL_DEBUG_MSG( 2, ( "going for ssl_hw_record_init()" ) );
- if( ( ret = ssl_hw_record_init( ssl, key1, key2, transform->iv_enc,
- transform->iv_dec, transform->mac_enc,
- transform->mac_dec ) ) != 0 )
+ if( ( ret = ssl_hw_record_init( ssl, key1, key2, transform->keylen,
+ transform->iv_enc, transform->iv_dec,
+ iv_copy_len,
+ mac_enc, mac_dec,
+ transform->maclen ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_hw_record_init", ret );
return POLARSSL_ERR_SSL_HW_ACCEL_FAILED;
@@ -581,11 +525,10 @@
}
#endif
- switch( session->ciphersuite )
+ switch( cipher_info->type )
{
#if defined(POLARSSL_ARC4_C)
- case TLS_RSA_WITH_RC4_128_MD5:
- case TLS_RSA_WITH_RC4_128_SHA:
+ case POLARSSL_CIPHER_ARC4_128:
arc4_setup( (arc4_context *) transform->ctx_enc, key1,
transform->keylen );
arc4_setup( (arc4_context *) transform->ctx_dec, key2,
@@ -594,79 +537,51 @@
#endif
#if defined(POLARSSL_DES_C)
- case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
- case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
- des3_set3key_enc( (des3_context *) transform->ctx_enc, key1 );
- des3_set3key_dec( (des3_context *) transform->ctx_dec, key2 );
- break;
+ case POLARSSL_CIPHER_DES_EDE3_CBC:
+ des3_set3key_enc( (des3_context *) transform->ctx_enc, key1 );
+ des3_set3key_dec( (des3_context *) transform->ctx_dec, key2 );
+ break;
#endif
#if defined(POLARSSL_AES_C)
- case TLS_RSA_WITH_AES_128_CBC_SHA:
- case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
- case TLS_RSA_WITH_AES_128_CBC_SHA256:
- case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
- aes_setkey_enc( (aes_context *) transform->ctx_enc, key1, 128 );
- aes_setkey_dec( (aes_context *) transform->ctx_dec, key2, 128 );
+ case POLARSSL_CIPHER_AES_128_CBC:
+ case POLARSSL_CIPHER_AES_256_CBC:
+ aes_setkey_enc( (aes_context*) transform->ctx_enc, key1,
+ cipher_info->key_length );
+ aes_setkey_dec( (aes_context*) transform->ctx_dec, key2,
+ cipher_info->key_length );
break;
-
- case TLS_RSA_WITH_AES_256_CBC_SHA:
- case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
- case TLS_RSA_WITH_AES_256_CBC_SHA256:
- case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
- aes_setkey_enc( (aes_context *) transform->ctx_enc, key1, 256 );
- aes_setkey_dec( (aes_context *) transform->ctx_dec, key2, 256 );
- break;
-
-#if defined(POLARSSL_GCM_C)
- case TLS_RSA_WITH_AES_128_GCM_SHA256:
- case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
- gcm_init( (gcm_context *) transform->ctx_enc, key1, 128 );
- gcm_init( (gcm_context *) transform->ctx_dec, key2, 128 );
- break;
-
- case TLS_RSA_WITH_AES_256_GCM_SHA384:
- case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
- gcm_init( (gcm_context *) transform->ctx_enc, key1, 256 );
- gcm_init( (gcm_context *) transform->ctx_dec, key2, 256 );
- break;
-#endif
#endif
#if defined(POLARSSL_CAMELLIA_C)
- case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA:
- case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA:
- case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- camellia_setkey_enc( (camellia_context *) transform->ctx_enc, key1, 128 );
- camellia_setkey_dec( (camellia_context *) transform->ctx_dec, key2, 128 );
- break;
-
- case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA:
- case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA:
- case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- camellia_setkey_enc( (camellia_context *) transform->ctx_enc, key1, 256 );
- camellia_setkey_dec( (camellia_context *) transform->ctx_dec, key2, 256 );
+ case POLARSSL_CIPHER_CAMELLIA_128_CBC:
+ case POLARSSL_CIPHER_CAMELLIA_256_CBC:
+ camellia_setkey_enc( (camellia_context*) transform->ctx_enc, key1,
+ cipher_info->key_length );
+ camellia_setkey_dec( (camellia_context*) transform->ctx_dec, key2,
+ cipher_info->key_length );
break;
#endif
-#if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES)
-#if defined(POLARSSL_CIPHER_NULL_CIPHER)
- case TLS_RSA_WITH_NULL_MD5:
- case TLS_RSA_WITH_NULL_SHA:
- case TLS_RSA_WITH_NULL_SHA256:
- break;
-#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
-
#if defined(POLARSSL_DES_C)
- case TLS_RSA_WITH_DES_CBC_SHA:
- case TLS_DHE_RSA_WITH_DES_CBC_SHA:
+ case POLARSSL_CIPHER_DES_CBC:
des_setkey_enc( (des_context *) transform->ctx_enc, key1 );
des_setkey_dec( (des_context *) transform->ctx_dec, key2 );
break;
#endif
-#endif /* defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES) */
+
+#if defined(POLARSSL_GCM_C)
+ case POLARSSL_CIPHER_AES_128_GCM:
+ case POLARSSL_CIPHER_AES_256_GCM:
+ gcm_init( (gcm_context *) transform->ctx_enc, key1,
+ cipher_info->key_length );
+ gcm_init( (gcm_context *) transform->ctx_dec, key2,
+ cipher_info->key_length );
+ break;
+#endif
+
+ case POLARSSL_CIPHER_NULL:
+ break;
default:
return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
@@ -793,91 +708,42 @@
/*
* SSLv3.0 MAC functions
*/
-static void ssl_mac_md5( unsigned char *secret,
- unsigned char *buf, size_t len,
- unsigned char *ctr, int type )
+static void ssl_mac( md_context_t *md_ctx, unsigned char *secret,
+ unsigned char *buf, size_t len,
+ unsigned char *ctr, int type )
{
unsigned char header[11];
unsigned char padding[48];
- md5_context md5;
+ int padlen = 0;
+ int md_size = md_get_size( md_ctx->md_info );
+ int md_type = md_get_type( md_ctx->md_info );
+
+ if( md_type == POLARSSL_MD_MD5 )
+ padlen = 48;
+ else if( md_type == POLARSSL_MD_SHA1 )
+ padlen = 40;
+ else if( md_type == POLARSSL_MD_SHA256 )
+ padlen = 32;
memcpy( header, ctr, 8 );
header[ 8] = (unsigned char) type;
header[ 9] = (unsigned char)( len >> 8 );
header[10] = (unsigned char)( len );
- memset( padding, 0x36, 48 );
- md5_starts( &md5 );
- md5_update( &md5, secret, 16 );
- md5_update( &md5, padding, 48 );
- md5_update( &md5, header, 11 );
- md5_update( &md5, buf, len );
- md5_finish( &md5, buf + len );
+ memset( padding, 0x36, padlen );
+ md_starts( md_ctx );
+ md_update( md_ctx, secret, md_size );
+ md_update( md_ctx, padding, padlen );
+ md_update( md_ctx, header, 11 );
+ md_update( md_ctx, buf, len );
+ md_finish( md_ctx, buf + len );
- memset( padding, 0x5C, 48 );
- md5_starts( &md5 );
- md5_update( &md5, secret, 16 );
- md5_update( &md5, padding, 48 );
- md5_update( &md5, buf + len, 16 );
- md5_finish( &md5, buf + len );
-}
-
-static void ssl_mac_sha1( unsigned char *secret,
- unsigned char *buf, size_t len,
- unsigned char *ctr, int type )
-{
- unsigned char header[11];
- unsigned char padding[40];
- sha1_context sha1;
-
- memcpy( header, ctr, 8 );
- header[ 8] = (unsigned char) type;
- header[ 9] = (unsigned char)( len >> 8 );
- header[10] = (unsigned char)( len );
-
- memset( padding, 0x36, 40 );
- sha1_starts( &sha1 );
- sha1_update( &sha1, secret, 20 );
- sha1_update( &sha1, padding, 40 );
- sha1_update( &sha1, header, 11 );
- sha1_update( &sha1, buf, len );
- sha1_finish( &sha1, buf + len );
-
- memset( padding, 0x5C, 40 );
- sha1_starts( &sha1 );
- sha1_update( &sha1, secret, 20 );
- sha1_update( &sha1, padding, 40 );
- sha1_update( &sha1, buf + len, 20 );
- sha1_finish( &sha1, buf + len );
-}
-
-static void ssl_mac_sha2( unsigned char *secret,
- unsigned char *buf, size_t len,
- unsigned char *ctr, int type )
-{
- unsigned char header[11];
- unsigned char padding[32];
- sha2_context sha2;
-
- memcpy( header, ctr, 8 );
- header[ 8] = (unsigned char) type;
- header[ 9] = (unsigned char)( len >> 8 );
- header[10] = (unsigned char)( len );
-
- memset( padding, 0x36, 32 );
- sha2_starts( &sha2, 0 );
- sha2_update( &sha2, secret, 32 );
- sha2_update( &sha2, padding, 32 );
- sha2_update( &sha2, header, 11 );
- sha2_update( &sha2, buf, len );
- sha2_finish( &sha2, buf + len );
-
- memset( padding, 0x5C, 32 );
- sha2_starts( &sha2, 0 );
- sha2_update( &sha2, secret, 32 );
- sha2_update( &sha2, padding, 32 );
- sha2_update( &sha2, buf + len, 32 );
- sha2_finish( &sha2, buf + len );
+ memset( padding, 0x5C, padlen );
+ md_starts( md_ctx );
+ md_update( md_ctx, secret, md_size );
+ md_update( md_ctx, padding, padlen );
+ md_update( md_ctx, buf + len, md_size );
+ md_finish( md_ctx, buf + len );
}
/*
@@ -894,60 +760,19 @@
*/
if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
{
- if( ssl->transform_out->maclen == 16 )
- ssl_mac_md5( ssl->transform_out->mac_enc,
- ssl->out_msg, ssl->out_msglen,
- ssl->out_ctr, ssl->out_msgtype );
- else if( ssl->transform_out->maclen == 20 )
- ssl_mac_sha1( ssl->transform_out->mac_enc,
- ssl->out_msg, ssl->out_msglen,
- ssl->out_ctr, ssl->out_msgtype );
- else if( ssl->transform_out->maclen == 32 )
- ssl_mac_sha2( ssl->transform_out->mac_enc,
- ssl->out_msg, ssl->out_msglen,
- ssl->out_ctr, ssl->out_msgtype );
- else if( ssl->transform_out->maclen != 0 )
- {
- SSL_DEBUG_MSG( 1, ( "invalid MAC len: %d",
- ssl->transform_out->maclen ) );
- return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
- }
+ ssl_mac( &ssl->transform_out->md_ctx_enc,
+ ssl->transform_out->mac_enc,
+ ssl->out_msg, ssl->out_msglen,
+ ssl->out_ctr, ssl->out_msgtype );
}
else
{
- if( ssl->transform_out->maclen == 16 )
- {
- md5_context ctx;
- md5_hmac_starts( &ctx, ssl->transform_out->mac_enc, 16 );
- md5_hmac_update( &ctx, ssl->out_ctr, 13 );
- md5_hmac_update( &ctx, ssl->out_msg, ssl->out_msglen );
- md5_hmac_finish( &ctx, ssl->out_msg + ssl->out_msglen );
- memset( &ctx, 0, sizeof(md5_context));
- }
- else if( ssl->transform_out->maclen == 20 )
- {
- sha1_context ctx;
- sha1_hmac_starts( &ctx, ssl->transform_out->mac_enc, 20 );
- sha1_hmac_update( &ctx, ssl->out_ctr, 13 );
- sha1_hmac_update( &ctx, ssl->out_msg, ssl->out_msglen );
- sha1_hmac_finish( &ctx, ssl->out_msg + ssl->out_msglen );
- memset( &ctx, 0, sizeof(sha1_context));
- }
- else if( ssl->transform_out->maclen == 32 )
- {
- sha2_context ctx;
- sha2_hmac_starts( &ctx, ssl->transform_out->mac_enc, 32, 0 );
- sha2_hmac_update( &ctx, ssl->out_ctr, 13 );
- sha2_hmac_update( &ctx, ssl->out_msg, ssl->out_msglen );
- sha2_hmac_finish( &ctx, ssl->out_msg + ssl->out_msglen );
- memset( &ctx, 0, sizeof(sha2_context));
- }
- else if( ssl->transform_out->maclen != 0 )
- {
- SSL_DEBUG_MSG( 1, ( "invalid MAC len: %d",
- ssl->transform_out->maclen ) );
- return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
- }
+ md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_ctr, 13 );
+ md_hmac_update( &ssl->transform_out->md_ctx_enc,
+ ssl->out_msg, ssl->out_msglen );
+ md_hmac_finish( &ssl->transform_out->md_ctx_enc,
+ ssl->out_msg + ssl->out_msglen );
+ md_hmac_reset( &ssl->transform_out->md_ctx_enc );
}
SSL_DEBUG_BUF( 4, "computed mac",
@@ -955,7 +780,15 @@
ssl->out_msglen += ssl->transform_out->maclen;
- if( ssl->transform_out->ivlen == 0 )
+#if defined(POLARSSL_CIPHER_NULL_CIPHER)
+ if( ssl->transform_out->ciphersuite_info->cipher == POLARSSL_CIPHER_NULL )
+ {
+ padlen = 0;
+ }
+ else
+#endif /* POLARSSL_CIPHER_NULL_CIPHER */
+#if defined(POLARSSL_ARC4_C)
+ if( ssl->transform_out->ciphersuite_info->cipher == POLARSSL_CIPHER_ARC4_128 )
{
padlen = 0;
@@ -966,25 +799,15 @@
SSL_DEBUG_BUF( 4, "before encrypt: output payload",
ssl->out_msg, ssl->out_msglen );
-#if defined(POLARSSL_ARC4_C)
- if( ssl->session_out->ciphersuite == TLS_RSA_WITH_RC4_128_MD5 ||
- ssl->session_out->ciphersuite == TLS_RSA_WITH_RC4_128_SHA )
- {
- arc4_crypt( (arc4_context *) ssl->transform_out->ctx_enc,
- ssl->out_msglen, ssl->out_msg,
- ssl->out_msg );
- } else
-#endif
-#if defined(POLARSSL_CIPHER_NULL_CIPHER)
- if( ssl->session_out->ciphersuite == TLS_RSA_WITH_NULL_MD5 ||
- ssl->session_out->ciphersuite == TLS_RSA_WITH_NULL_SHA ||
- ssl->session_out->ciphersuite == TLS_RSA_WITH_NULL_SHA256 )
- {
- } else
-#endif
- return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
+ arc4_crypt( (arc4_context *) ssl->transform_out->ctx_enc,
+ ssl->out_msglen, ssl->out_msg,
+ ssl->out_msg );
}
- else if( ssl->transform_out->ivlen == 12 )
+ else
+#endif /* POLARSSL_ARC4_C */
+#if defined(POLARSSL_GCM_C)
+ if( ssl->transform_out->ciphersuite_info->cipher == POLARSSL_CIPHER_AES_128_GCM ||
+ ssl->transform_out->ciphersuite_info->cipher == POLARSSL_CIPHER_AES_256_GCM )
{
size_t enc_msglen;
unsigned char *enc_msg;
@@ -1004,68 +827,51 @@
SSL_DEBUG_BUF( 4, "additional data used for AEAD",
add_data, 13 );
-#if defined(POLARSSL_AES_C) && defined(POLARSSL_GCM_C)
-
- if( ssl->session_out->ciphersuite == TLS_RSA_WITH_AES_128_GCM_SHA256 ||
- ssl->session_out->ciphersuite == TLS_RSA_WITH_AES_256_GCM_SHA384 ||
- ssl->session_out->ciphersuite == TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 ||
- ssl->session_out->ciphersuite == TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 )
- {
- /*
- * Generate IV
- */
- ret = ssl->f_rng( ssl->p_rng,
- ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen,
- ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen );
- if( ret != 0 )
- return( ret );
-
- /*
- * Shift message for ivlen bytes and prepend IV
- */
- memmove( ssl->out_msg + ssl->transform_out->ivlen -
- ssl->transform_out->fixed_ivlen,
- ssl->out_msg, ssl->out_msglen );
- memcpy( ssl->out_msg,
+ /*
+ * Generate IV
+ */
+ ret = ssl->f_rng( ssl->p_rng,
ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen,
- ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen );
+ ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen );
+ if( ret != 0 )
+ return( ret );
- /*
- * Fix pointer positions and message length with added IV
- */
- enc_msg = ssl->out_msg + ssl->transform_out->ivlen -
- ssl->transform_out->fixed_ivlen;
- enc_msglen = ssl->out_msglen;
- ssl->out_msglen += ssl->transform_out->ivlen -
- ssl->transform_out->fixed_ivlen;
+ memcpy( ssl->out_iv,
+ ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen,
+ ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen );
- SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
- "including %d bytes of padding",
- ssl->out_msglen, 0 ) );
+ /*
+ * Fix pointer positions and message length with added IV
+ */
+ enc_msg = ssl->out_msg;
+ enc_msglen = ssl->out_msglen;
+ ssl->out_msglen += ssl->transform_out->ivlen -
+ ssl->transform_out->fixed_ivlen;
- SSL_DEBUG_BUF( 4, "before encrypt: output payload",
- ssl->out_msg, ssl->out_msglen );
+ SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
+ "including %d bytes of padding",
+ ssl->out_msglen, 0 ) );
- /*
- * Adjust for tag
- */
- ssl->out_msglen += 16;
-
- gcm_crypt_and_tag( (gcm_context *) ssl->transform_out->ctx_enc,
- GCM_ENCRYPT, enc_msglen,
- ssl->transform_out->iv_enc, ssl->transform_out->ivlen,
- add_data, 13,
- enc_msg, enc_msg,
- 16, enc_msg + enc_msglen );
+ SSL_DEBUG_BUF( 4, "before encrypt: output payload",
+ ssl->out_msg, ssl->out_msglen );
- SSL_DEBUG_BUF( 4, "after encrypt: tag",
- enc_msg + enc_msglen, 16 );
+ /*
+ * Adjust for tag
+ */
+ ssl->out_msglen += 16;
- } else
-#endif
- return( ret );
+ gcm_crypt_and_tag( (gcm_context *) ssl->transform_out->ctx_enc,
+ GCM_ENCRYPT, enc_msglen,
+ ssl->transform_out->iv_enc, ssl->transform_out->ivlen,
+ add_data, 13,
+ enc_msg, enc_msg,
+ 16, enc_msg + enc_msglen );
+
+ SSL_DEBUG_BUF( 4, "after encrypt: tag",
+ enc_msg + enc_msglen, 16 );
}
else
+#endif /* POLARSSL_GCM_C */
{
unsigned char *enc_msg;
size_t enc_msglen;
@@ -1097,18 +903,13 @@
if( ret != 0 )
return( ret );
- /*
- * Shift message for ivlen bytes and prepend IV
- */
- memmove( ssl->out_msg + ssl->transform_out->ivlen, ssl->out_msg,
- ssl->out_msglen );
- memcpy( ssl->out_msg, ssl->transform_out->iv_enc,
+ memcpy( ssl->out_iv, ssl->transform_out->iv_enc,
ssl->transform_out->ivlen );
/*
* Fix pointer positions and message length with added IV
*/
- enc_msg = ssl->out_msg + ssl->transform_out->ivlen;
+ enc_msg = ssl->out_msg;
enc_msglen = ssl->out_msglen;
ssl->out_msglen += ssl->transform_out->ivlen;
}
@@ -1118,62 +919,35 @@
ssl->out_msglen, ssl->transform_out->ivlen, padlen + 1 ) );
SSL_DEBUG_BUF( 4, "before encrypt: output payload",
- ssl->out_msg, ssl->out_msglen );
+ ssl->out_iv, ssl->out_msglen );
- switch( ssl->transform_out->ivlen )
+ switch( ssl->transform_out->ciphersuite_info->cipher )
{
-#if defined(POLARSSL_DES_C)
- case 8:
-#if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES)
- if( ssl->session_out->ciphersuite == TLS_RSA_WITH_DES_CBC_SHA ||
- ssl->session_out->ciphersuite == TLS_DHE_RSA_WITH_DES_CBC_SHA )
- {
- des_crypt_cbc( (des_context *) ssl->transform_out->ctx_enc,
- DES_ENCRYPT, enc_msglen,
- ssl->transform_out->iv_enc, enc_msg, enc_msg );
- }
- else
-#endif
- des3_crypt_cbc( (des3_context *) ssl->transform_out->ctx_enc,
- DES_ENCRYPT, enc_msglen,
+ case POLARSSL_CIPHER_DES_CBC:
+ des_crypt_cbc( (des_context *) ssl->transform_out->ctx_enc,
+ DES_ENCRYPT, enc_msglen,
+ ssl->transform_out->iv_enc, enc_msg, enc_msg );
+ break;
+
+ case POLARSSL_CIPHER_DES_EDE3_CBC:
+ des3_crypt_cbc( (des3_context *) ssl->transform_out->ctx_enc,
+ DES_ENCRYPT, enc_msglen,
+ ssl->transform_out->iv_enc, enc_msg, enc_msg );
+ break;
+
+ case POLARSSL_CIPHER_AES_128_CBC:
+ case POLARSSL_CIPHER_AES_256_CBC:
+ aes_crypt_cbc( (aes_context *) ssl->transform_out->ctx_enc,
+ AES_ENCRYPT, enc_msglen,
+ ssl->transform_out->iv_enc, enc_msg, enc_msg );
+ break;
+
+ case POLARSSL_CIPHER_CAMELLIA_128_CBC:
+ case POLARSSL_CIPHER_CAMELLIA_256_CBC:
+ camellia_crypt_cbc( (camellia_context *) ssl->transform_out->ctx_enc,
+ CAMELLIA_ENCRYPT, enc_msglen,
ssl->transform_out->iv_enc, enc_msg, enc_msg );
break;
-#endif
-
- case 16:
-#if defined(POLARSSL_AES_C)
- if ( ssl->session_out->ciphersuite == TLS_RSA_WITH_AES_128_CBC_SHA ||
- ssl->session_out->ciphersuite == TLS_DHE_RSA_WITH_AES_128_CBC_SHA ||
- ssl->session_out->ciphersuite == TLS_RSA_WITH_AES_256_CBC_SHA ||
- ssl->session_out->ciphersuite == TLS_DHE_RSA_WITH_AES_256_CBC_SHA ||
- ssl->session_out->ciphersuite == TLS_RSA_WITH_AES_128_CBC_SHA256 ||
- ssl->session_out->ciphersuite == TLS_RSA_WITH_AES_256_CBC_SHA256 ||
- ssl->session_out->ciphersuite == TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 ||
- ssl->session_out->ciphersuite == TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 )
- {
- aes_crypt_cbc( (aes_context *) ssl->transform_out->ctx_enc,
- AES_ENCRYPT, enc_msglen,
- ssl->transform_out->iv_enc, enc_msg, enc_msg);
- break;
- }
-#endif
-
-#if defined(POLARSSL_CAMELLIA_C)
- if ( ssl->session_out->ciphersuite == TLS_RSA_WITH_CAMELLIA_128_CBC_SHA ||
- ssl->session_out->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA ||
- ssl->session_out->ciphersuite == TLS_RSA_WITH_CAMELLIA_256_CBC_SHA ||
- ssl->session_out->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA ||
- ssl->session_out->ciphersuite == TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 ||
- ssl->session_out->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 ||
- ssl->session_out->ciphersuite == TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 ||
- ssl->session_out->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 )
- {
- camellia_crypt_cbc( (camellia_context *) ssl->transform_out->ctx_enc,
- CAMELLIA_ENCRYPT, enc_msglen,
- ssl->transform_out->iv_enc, enc_msg, enc_msg );
- break;
- }
-#endif
default:
return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
@@ -1196,7 +970,7 @@
static int ssl_decrypt_buf( ssl_context *ssl )
{
- size_t i, padlen;
+ size_t i, padlen = 0, correct = 1;
unsigned char tmp[POLARSSL_SSL_MAX_MAC_SIZE];
SSL_DEBUG_MSG( 2, ( "=> decrypt buf" ) );
@@ -1208,28 +982,27 @@
return( POLARSSL_ERR_SSL_INVALID_MAC );
}
- if( ssl->transform_in->ivlen == 0 )
+#if defined(POLARSSL_CIPHER_NULL_CIPHER)
+ if( ssl->transform_in->ciphersuite_info->cipher == POLARSSL_CIPHER_NULL )
{
-#if defined(POLARSSL_ARC4_C)
padlen = 0;
- if( ssl->session_in->ciphersuite == TLS_RSA_WITH_RC4_128_MD5 ||
- ssl->session_in->ciphersuite == TLS_RSA_WITH_RC4_128_SHA )
- {
- arc4_crypt( (arc4_context *) ssl->transform_in->ctx_dec,
+ }
+ else
+#endif /* POLARSSL_CIPHER_NULL_CIPHER */
+#if defined(POLARSSL_ARC4_C)
+ if( ssl->transform_in->ciphersuite_info->cipher == POLARSSL_CIPHER_ARC4_128 )
+ {
+ padlen = 0;
+
+ arc4_crypt( (arc4_context *) ssl->transform_in->ctx_dec,
ssl->in_msglen, ssl->in_msg,
ssl->in_msg );
- } else
-#endif
-#if defined(POLARSSL_CIPHER_NULL_CIPHER)
- if( ssl->session_in->ciphersuite == TLS_RSA_WITH_NULL_MD5 ||
- ssl->session_in->ciphersuite == TLS_RSA_WITH_NULL_SHA ||
- ssl->session_in->ciphersuite == TLS_RSA_WITH_NULL_SHA256 )
- {
- } else
-#endif
- return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
}
- else if( ssl->transform_in->ivlen == 12 )
+ else
+#endif /* POLARSSL_ARC4_C */
+#if defined(POLARSSL_GCM_C)
+ if( ssl->transform_in->ciphersuite_info->cipher == POLARSSL_CIPHER_AES_128_GCM ||
+ ssl->transform_in->ciphersuite_info->cipher == POLARSSL_CIPHER_AES_256_GCM )
{
unsigned char *dec_msg;
unsigned char *dec_msg_result;
@@ -1239,69 +1012,60 @@
padlen = 0;
-#if defined(POLARSSL_AES_C) && defined(POLARSSL_GCM_C)
- if( ssl->session_in->ciphersuite == TLS_RSA_WITH_AES_128_GCM_SHA256 ||
- ssl->session_in->ciphersuite == TLS_RSA_WITH_AES_256_GCM_SHA384 ||
- ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 ||
- ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 )
+ dec_msglen = ssl->in_msglen - ( ssl->transform_in->ivlen -
+ ssl->transform_in->fixed_ivlen );
+ dec_msglen -= 16;
+ dec_msg = ssl->in_msg;
+ dec_msg_result = ssl->in_msg;
+ ssl->in_msglen = dec_msglen;
+
+ memcpy( add_data, ssl->in_ctr, 8 );
+ add_data[8] = ssl->in_msgtype;
+ add_data[9] = ssl->major_ver;
+ add_data[10] = ssl->minor_ver;
+ add_data[11] = ( ssl->in_msglen >> 8 ) & 0xFF;
+ add_data[12] = ssl->in_msglen & 0xFF;
+
+ SSL_DEBUG_BUF( 4, "additional data used for AEAD",
+ add_data, 13 );
+
+ memcpy( ssl->transform_in->iv_dec + ssl->transform_in->fixed_ivlen,
+ ssl->in_iv,
+ ssl->transform_in->ivlen - ssl->transform_in->fixed_ivlen );
+
+ SSL_DEBUG_BUF( 4, "IV used", ssl->transform_in->iv_dec,
+ ssl->transform_in->ivlen );
+ SSL_DEBUG_BUF( 4, "TAG used", dec_msg + dec_msglen, 16 );
+
+ ret = gcm_auth_decrypt( (gcm_context *) ssl->transform_in->ctx_dec,
+ dec_msglen,
+ ssl->transform_in->iv_dec,
+ ssl->transform_in->ivlen,
+ add_data, 13,
+ dec_msg + dec_msglen, 16,
+ dec_msg, dec_msg_result );
+
+ if( ret != 0 )
{
- dec_msglen = ssl->in_msglen - ( ssl->transform_in->ivlen -
- ssl->transform_in->fixed_ivlen );
- dec_msglen -= 16;
- dec_msg = ssl->in_msg + ( ssl->transform_in->ivlen -
- ssl->transform_in->fixed_ivlen );
- dec_msg_result = ssl->in_msg;
- ssl->in_msglen = dec_msglen;
+ SSL_DEBUG_MSG( 1, ( "AEAD decrypt failed on validation (ret = -0x%02x)",
+ -ret ) );
- memcpy( add_data, ssl->in_ctr, 8 );
- add_data[8] = ssl->in_msgtype;
- add_data[9] = ssl->major_ver;
- add_data[10] = ssl->minor_ver;
- add_data[11] = ( ssl->in_msglen >> 8 ) & 0xFF;
- add_data[12] = ssl->in_msglen & 0xFF;
-
- SSL_DEBUG_BUF( 4, "additional data used for AEAD",
- add_data, 13 );
-
- memcpy( ssl->transform_in->iv_dec + ssl->transform_in->fixed_ivlen,
- ssl->in_msg,
- ssl->transform_in->ivlen - ssl->transform_in->fixed_ivlen );
-
- SSL_DEBUG_BUF( 4, "IV used", ssl->transform_in->iv_dec,
- ssl->transform_in->ivlen );
- SSL_DEBUG_BUF( 4, "TAG used", dec_msg + dec_msglen, 16 );
-
- memcpy( ssl->transform_in->iv_dec + ssl->transform_in->fixed_ivlen,
- ssl->in_msg,
- ssl->transform_in->ivlen - ssl->transform_in->fixed_ivlen );
-
- ret = gcm_auth_decrypt( (gcm_context *) ssl->transform_in->ctx_dec,
- dec_msglen,
- ssl->transform_in->iv_dec,
- ssl->transform_in->ivlen,
- add_data, 13,
- dec_msg + dec_msglen, 16,
- dec_msg, dec_msg_result );
-
- if( ret != 0 )
- {
- SSL_DEBUG_MSG( 1, ( "AEAD decrypt failed on validation (ret = -0x%02x)",
- -ret ) );
-
- return( POLARSSL_ERR_SSL_INVALID_MAC );
- }
- } else
-#endif
- return( ret );
+ return( POLARSSL_ERR_SSL_INVALID_MAC );
+ }
}
else
+#endif /* POLARSSL_GCM_C */
{
+ /*
+ * Decrypt and check the padding
+ */
unsigned char *dec_msg;
unsigned char *dec_msg_result;
size_t dec_msglen;
+ size_t minlen = 0;
/*
- * Decrypt and check the padding
+ * Check immediate ciphertext sanity
*/
if( ssl->in_msglen % ssl->transform_in->ivlen != 0 )
{
@@ -1310,6 +1074,17 @@
return( POLARSSL_ERR_SSL_INVALID_MAC );
}
+ if( ssl->minor_ver >= SSL_MINOR_VERSION_2 )
+ minlen += ssl->transform_in->ivlen;
+
+ if( ssl->in_msglen < minlen + ssl->transform_in->ivlen ||
+ ssl->in_msglen < minlen + ssl->transform_in->maclen + 1 )
+ {
+ SSL_DEBUG_MSG( 1, ( "msglen (%d) < max( ivlen(%d), maclen (%d) + 1 ) ( + expl IV )",
+ ssl->in_msglen, ssl->transform_in->ivlen, ssl->transform_in->maclen ) );
+ return( POLARSSL_ERR_SSL_INVALID_MAC );
+ }
+
dec_msglen = ssl->in_msglen;
dec_msg = ssl->in_msg;
dec_msg_result = ssl->in_msg;
@@ -1319,68 +1094,40 @@
*/
if( ssl->minor_ver >= SSL_MINOR_VERSION_2 )
{
- dec_msg += ssl->transform_in->ivlen;
dec_msglen -= ssl->transform_in->ivlen;
ssl->in_msglen -= ssl->transform_in->ivlen;
for( i = 0; i < ssl->transform_in->ivlen; i++ )
- ssl->transform_in->iv_dec[i] = ssl->in_msg[i];
+ ssl->transform_in->iv_dec[i] = ssl->in_iv[i];
}
- switch( ssl->transform_in->ivlen )
+ switch( ssl->transform_in->ciphersuite_info->cipher )
{
-#if defined(POLARSSL_DES_C)
- case 8:
-#if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES)
- if( ssl->session_in->ciphersuite == TLS_RSA_WITH_DES_CBC_SHA ||
- ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_DES_CBC_SHA )
- {
- des_crypt_cbc( (des_context *) ssl->transform_in->ctx_dec,
- DES_DECRYPT, dec_msglen,
- ssl->transform_in->iv_dec, dec_msg, dec_msg_result );
- }
- else
-#endif
- des3_crypt_cbc( (des3_context *) ssl->transform_in->ctx_dec,
- DES_DECRYPT, dec_msglen,
- ssl->transform_in->iv_dec, dec_msg, dec_msg_result );
+ case POLARSSL_CIPHER_DES_CBC:
+ des_crypt_cbc( (des_context *) ssl->transform_in->ctx_dec,
+ DES_DECRYPT, dec_msglen,
+ ssl->transform_in->iv_dec, dec_msg, dec_msg_result );
break;
-#endif
- case 16:
-#if defined(POLARSSL_AES_C)
- if ( ssl->session_in->ciphersuite == TLS_RSA_WITH_AES_128_CBC_SHA ||
- ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_AES_128_CBC_SHA ||
- ssl->session_in->ciphersuite == TLS_RSA_WITH_AES_256_CBC_SHA ||
- ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_AES_256_CBC_SHA ||
- ssl->session_in->ciphersuite == TLS_RSA_WITH_AES_128_CBC_SHA256 ||
- ssl->session_in->ciphersuite == TLS_RSA_WITH_AES_256_CBC_SHA256 ||
- ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 ||
- ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 )
- {
- aes_crypt_cbc( (aes_context *) ssl->transform_in->ctx_dec,
- AES_DECRYPT, dec_msglen,
- ssl->transform_in->iv_dec, dec_msg, dec_msg_result );
- break;
- }
-#endif
+ case POLARSSL_CIPHER_DES_EDE3_CBC:
+ des3_crypt_cbc( (des3_context *) ssl->transform_in->ctx_dec,
+ DES_DECRYPT, dec_msglen,
+ ssl->transform_in->iv_dec, dec_msg, dec_msg_result );
+ break;
-#if defined(POLARSSL_CAMELLIA_C)
- if ( ssl->session_in->ciphersuite == TLS_RSA_WITH_CAMELLIA_128_CBC_SHA ||
- ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA ||
- ssl->session_in->ciphersuite == TLS_RSA_WITH_CAMELLIA_256_CBC_SHA ||
- ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA ||
- ssl->session_in->ciphersuite == TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 ||
- ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 ||
- ssl->session_in->ciphersuite == TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 ||
- ssl->session_in->ciphersuite == TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 )
- {
- camellia_crypt_cbc( (camellia_context *) ssl->transform_in->ctx_dec,
- CAMELLIA_DECRYPT, dec_msglen,
- ssl->transform_in->iv_dec, dec_msg, dec_msg_result );
- break;
- }
-#endif
+ case POLARSSL_CIPHER_AES_128_CBC:
+ case POLARSSL_CIPHER_AES_256_CBC:
+ aes_crypt_cbc( (aes_context *) ssl->transform_in->ctx_dec,
+ AES_DECRYPT, dec_msglen,
+ ssl->transform_in->iv_dec, dec_msg, dec_msg_result );
+ break;
+
+ case POLARSSL_CIPHER_CAMELLIA_128_CBC:
+ case POLARSSL_CIPHER_CAMELLIA_256_CBC:
+ camellia_crypt_cbc( (camellia_context *) ssl->transform_in->ctx_dec,
+ CAMELLIA_DECRYPT, dec_msglen,
+ ssl->transform_in->iv_dec, dec_msg, dec_msg_result );
+ break;
default:
return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
@@ -1388,31 +1135,51 @@
padlen = 1 + ssl->in_msg[ssl->in_msglen - 1];
+ if( ssl->in_msglen < ssl->transform_in->maclen + padlen )
+ {
+#if defined(POLARSSL_SSL_DEBUG_ALL)
+ SSL_DEBUG_MSG( 1, ( "msglen (%d) < maclen (%d) + padlen (%d)",
+ ssl->in_msglen, ssl->transform_in->maclen, padlen ) );
+#endif
+ padlen = 0;
+ correct = 0;
+ }
+
if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
{
if( padlen > ssl->transform_in->ivlen )
{
+#if defined(POLARSSL_SSL_DEBUG_ALL)
SSL_DEBUG_MSG( 1, ( "bad padding length: is %d, "
"should be no more than %d",
padlen, ssl->transform_in->ivlen ) );
- padlen = 0;
+#endif
+ correct = 0;
}
}
else
{
/*
- * TLSv1: always check the padding
+ * TLSv1+: always check the padding up to the first failure
+ * and fake check up to 256 bytes of padding
*/
+ size_t pad_count = 0, fake_pad_count = 0;
+ size_t padding_idx = ssl->in_msglen - padlen - 1;
+
for( i = 1; i <= padlen; i++ )
- {
- if( ssl->in_msg[ssl->in_msglen - i] != padlen - 1 )
- {
- SSL_DEBUG_MSG( 1, ( "bad padding byte: should be "
- "%02x, but is %02x", padlen - 1,
- ssl->in_msg[ssl->in_msglen - i] ) );
- padlen = 0;
- }
- }
+ pad_count += ( ssl->in_msg[padding_idx + i] == padlen - 1 );
+
+ for( ; i <= 256; i++ )
+ fake_pad_count += ( ssl->in_msg[padding_idx + i] == padlen - 1 );
+
+ correct &= ( pad_count == padlen ); /* Only 1 on correct padding */
+ correct &= ( pad_count + fake_pad_count < 512 ); /* Always 1 */
+
+#if defined(POLARSSL_SSL_DEBUG_ALL)
+ if( padlen > 0 && correct == 0)
+ SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) );
+#endif
+ padlen &= correct * 0x1FF;
}
}
@@ -1422,61 +1189,50 @@
/*
* Always compute the MAC (RFC4346, CBCTIME).
*/
- if( ssl->in_msglen < ssl->transform_in->maclen + padlen )
- {
- SSL_DEBUG_MSG( 1, ( "msglen (%d) < maclen (%d) + padlen (%d)",
- ssl->in_msglen, ssl->transform_in->maclen, padlen ) );
- return( POLARSSL_ERR_SSL_INVALID_MAC );
- }
-
ssl->in_msglen -= ( ssl->transform_in->maclen + padlen );
ssl->in_hdr[3] = (unsigned char)( ssl->in_msglen >> 8 );
ssl->in_hdr[4] = (unsigned char)( ssl->in_msglen );
- memcpy( tmp, ssl->in_msg + ssl->in_msglen, POLARSSL_SSL_MAX_MAC_SIZE );
+ memcpy( tmp, ssl->in_msg + ssl->in_msglen, ssl->transform_in->maclen );
if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
{
- if( ssl->transform_in->maclen == 16 )
- ssl_mac_md5( ssl->transform_in->mac_dec,
- ssl->in_msg, ssl->in_msglen,
- ssl->in_ctr, ssl->in_msgtype );
- else if( ssl->transform_in->maclen == 20 )
- ssl_mac_sha1( ssl->transform_in->mac_dec,
- ssl->in_msg, ssl->in_msglen,
- ssl->in_ctr, ssl->in_msgtype );
- else if( ssl->transform_in->maclen == 32 )
- ssl_mac_sha2( ssl->transform_in->mac_dec,
- ssl->in_msg, ssl->in_msglen,
- ssl->in_ctr, ssl->in_msgtype );
- else if( ssl->transform_in->maclen != 0 )
- {
- SSL_DEBUG_MSG( 1, ( "invalid MAC len: %d",
- ssl->transform_in->maclen ) );
- return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
- }
+ ssl_mac( &ssl->transform_in->md_ctx_dec,
+ ssl->transform_in->mac_dec,
+ ssl->in_msg, ssl->in_msglen,
+ ssl->in_ctr, ssl->in_msgtype );
}
else
{
- if( ssl->transform_in->maclen == 16 )
- md5_hmac( ssl->transform_in->mac_dec, 16,
- ssl->in_ctr, ssl->in_msglen + 13,
- ssl->in_msg + ssl->in_msglen );
- else if( ssl->transform_in->maclen == 20 )
- sha1_hmac( ssl->transform_in->mac_dec, 20,
- ssl->in_ctr, ssl->in_msglen + 13,
- ssl->in_msg + ssl->in_msglen );
- else if( ssl->transform_in->maclen == 32 )
- sha2_hmac( ssl->transform_in->mac_dec, 32,
- ssl->in_ctr, ssl->in_msglen + 13,
- ssl->in_msg + ssl->in_msglen, 0 );
- else if( ssl->transform_in->maclen != 0 )
- {
- SSL_DEBUG_MSG( 1, ( "invalid MAC len: %d",
- ssl->transform_in->maclen ) );
- return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
- }
+ /*
+ * Process MAC and always update for padlen afterwards to make
+ * total time independent of padlen
+ *
+ * extra_run compensates MAC check for padlen
+ *
+ * Known timing attacks:
+ * - Lucky Thirteen (http://www.isg.rhul.ac.uk/tls/TLStiming.pdf)
+ *
+ * We use ( ( Lx + 8 ) / 64 ) to handle 'negative Lx' values
+ * correctly. (We round down instead of up, so -56 is the correct
+ * value for our calculations instead of -55)
+ */
+ int j, extra_run = 0;
+ extra_run = ( 13 + ssl->in_msglen + padlen + 8 ) / 64 -
+ ( 13 + ssl->in_msglen + 8 ) / 64;
+
+ extra_run &= correct * 0xFF;
+
+ md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_ctr, 13 );
+ md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_msg,
+ ssl->in_msglen );
+ md_hmac_finish( &ssl->transform_in->md_ctx_dec,
+ ssl->in_msg + ssl->in_msglen );
+ for( j = 0; j < extra_run; j++ )
+ md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg );
+
+ md_hmac_reset( &ssl->transform_in->md_ctx_dec );
}
SSL_DEBUG_BUF( 4, "message mac", tmp, ssl->transform_in->maclen );
@@ -1486,16 +1242,16 @@
if( memcmp( tmp, ssl->in_msg + ssl->in_msglen,
ssl->transform_in->maclen ) != 0 )
{
+#if defined(POLARSSL_SSL_DEBUG_ALL)
SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
- return( POLARSSL_ERR_SSL_INVALID_MAC );
+#endif
+ correct = 0;
}
/*
- * Finally check the padding length; bad padding
- * will produce the same error as an invalid MAC.
+ * Finally check the correct flag
*/
- if( ssl->transform_in->ivlen != 0 && ssl->transform_in->ivlen != 12 &&
- padlen == 0 )
+ if( correct == 0 )
return( POLARSSL_ERR_SSL_INVALID_MAC );
if( ssl->in_msglen == 0 )
@@ -1680,22 +1436,7 @@
SSL_DEBUG_MSG( 2, ( "message length: %d, out_left: %d",
5 + ssl->out_msglen, ssl->out_left ) );
- if( ssl->out_msglen < ssl->out_left )
- {
- size_t header_left = ssl->out_left - ssl->out_msglen;
-
- buf = ssl->out_hdr + 5 - header_left;
- ret = ssl->f_send( ssl->p_send, buf, header_left );
-
- SSL_DEBUG_RET( 2, "ssl->f_send (header)", ret );
-
- if( ret <= 0 )
- return( ret );
-
- ssl->out_left -= ret;
- }
-
- buf = ssl->out_msg + ssl->out_msglen - ssl->out_left;
+ buf = ssl->out_hdr + 5 + ssl->out_msglen - ssl->out_left;
ret = ssl->f_send( ssl->p_send, buf, ssl->out_left );
SSL_DEBUG_RET( 2, "ssl->f_send", ret );
@@ -1755,7 +1496,9 @@
SSL_DEBUG_RET( 1, "ssl_hw_record_write", ret );
return POLARSSL_ERR_SSL_HW_ACCEL_FAILED;
}
- done = 1;
+
+ if( ret == 0 )
+ done = 1;
}
#endif
if( !done )
@@ -1786,10 +1529,8 @@
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 header sent to network",
- ssl->out_hdr, 5 );
SSL_DEBUG_BUF( 4, "output record sent to network",
- ssl->out_hdr + 32, ssl->out_msglen );
+ ssl->out_hdr, 5 + ssl->out_msglen );
}
if( ( ret = ssl_flush_output( ssl ) ) != 0 )
@@ -1809,6 +1550,9 @@
SSL_DEBUG_MSG( 2, ( "=> read record" ) );
+ SSL_DEBUG_BUF( 4, "input record from network",
+ ssl->in_hdr, 5 + ssl->in_msglen );
+
if( ssl->in_hslen != 0 &&
ssl->in_hslen < ssl->in_msglen )
{
@@ -1936,13 +1680,23 @@
SSL_DEBUG_RET( 1, "ssl_hw_record_read", ret );
return POLARSSL_ERR_SSL_HW_ACCEL_FAILED;
}
- done = 1;
+
+ if( ret == 0 )
+ done = 1;
}
#endif
if( !done && ssl->transform_in != NULL )
{
if( ( ret = ssl_decrypt_buf( ssl ) ) != 0 )
{
+#if defined(POLARSSL_SSL_ALERT_MESSAGES)
+ if( ret == POLARSSL_ERR_SSL_INVALID_MAC )
+ {
+ ssl_send_alert_message( ssl,
+ SSL_ALERT_LEVEL_FATAL,
+ SSL_ALERT_MSG_BAD_RECORD_MAC );
+ }
+#endif
SSL_DEBUG_RET( 1, "ssl_decrypt_buf", ret );
return( ret );
}
@@ -2710,6 +2464,17 @@
SSL_DEBUG_MSG( 2, ( "=> write finished" ) );
+ /*
+ * Set the out_msg pointer to the correct location based on IV length
+ */
+ if( ssl->minor_ver >= SSL_MINOR_VERSION_2 )
+ {
+ ssl->out_msg = ssl->out_iv + ssl->transform_negotiate->ivlen -
+ ssl->transform_negotiate->fixed_ivlen;
+ }
+ else
+ ssl->out_msg = ssl->out_iv;
+
ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->endpoint );
// TODO TLS/1.2 Hash length is determined by cipher suite (Page 63)
@@ -2744,6 +2509,17 @@
ssl->session_out = ssl->session_negotiate;
memset( ssl->out_ctr, 0, 8 );
+#if defined(POLARSSL_SSL_HW_RECORD_ACCEL)
+ if( ssl_hw_record_activate != NULL)
+ {
+ if( ( ret = ssl_hw_record_activate( ssl, SSL_CHANNEL_OUTBOUND ) ) != 0 )
+ {
+ SSL_DEBUG_RET( 1, "ssl_hw_record_activate", ret );
+ return( POLARSSL_ERR_SSL_HW_ACCEL_FAILED );
+ }
+ }
+#endif
+
if( ( ret = ssl_write_record( ssl ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_write_record", ret );
@@ -2773,6 +2549,28 @@
ssl->session_in = ssl->session_negotiate;
memset( ssl->in_ctr, 0, 8 );
+ /*
+ * Set the in_msg pointer to the correct location based on IV length
+ */
+ if( ssl->minor_ver >= SSL_MINOR_VERSION_2 )
+ {
+ ssl->in_msg = ssl->in_iv + ssl->transform_negotiate->ivlen -
+ ssl->transform_negotiate->fixed_ivlen;
+ }
+ else
+ ssl->in_msg = ssl->in_iv;
+
+#if defined(POLARSSL_SSL_HW_RECORD_ACCEL)
+ if( ssl_hw_record_activate != NULL)
+ {
+ if( ( ret = ssl_hw_record_activate( ssl, SSL_CHANNEL_INBOUND ) ) != 0 )
+ {
+ SSL_DEBUG_RET( 1, "ssl_hw_record_activate", ret );
+ return( POLARSSL_ERR_SSL_HW_ACCEL_FAILED );
+ }
+ }
+#endif
+
if( ( ret = ssl_read_record( ssl ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_read_record", ret );
@@ -2882,7 +2680,7 @@
ssl->min_major_ver = SSL_MAJOR_VERSION_3;
ssl->min_minor_ver = SSL_MINOR_VERSION_0;
- ssl->ciphersuites = ssl_default_ciphersuites;
+ ssl->ciphersuites = ssl_list_ciphersuites();
#if defined(POLARSSL_DHM_C)
if( ( ret = mpi_read_string( &ssl->dhm_P, 16,
@@ -2900,6 +2698,7 @@
*/
ssl->in_ctr = (unsigned char *) malloc( len );
ssl->in_hdr = ssl->in_ctr + 8;
+ ssl->in_iv = ssl->in_ctr + 13;
ssl->in_msg = ssl->in_ctr + 13;
if( ssl->in_ctr == NULL )
@@ -2910,7 +2709,8 @@
ssl->out_ctr = (unsigned char *) malloc( len );
ssl->out_hdr = ssl->out_ctr + 8;
- ssl->out_msg = ssl->out_ctr + 40;
+ ssl->out_iv = ssl->out_ctr + 13;
+ ssl->out_msg = ssl->out_ctr + 13;
if( ssl->out_ctr == NULL )
{
@@ -2949,6 +2749,7 @@
ssl->in_offt = NULL;
+ ssl->in_msg = ssl->in_ctr + 13;
ssl->in_msgtype = 0;
ssl->in_msglen = 0;
ssl->in_left = 0;
@@ -2956,6 +2757,7 @@
ssl->in_hslen = 0;
ssl->nb_zero = 0;
+ ssl->out_msg = ssl->out_ctr + 13;
ssl->out_msgtype = 0;
ssl->out_msglen = 0;
ssl->out_left = 0;
@@ -2970,7 +2772,7 @@
if( ssl_hw_record_reset != NULL)
{
SSL_DEBUG_MSG( 2, ( "going for ssl_hw_record_reset()" ) );
- if( ssl_hw_record_reset( ssl ) != 0 )
+ if( ( ret = ssl_hw_record_reset( ssl ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_hw_record_reset", ret );
return( POLARSSL_ERR_SSL_HW_ACCEL_FAILED );
@@ -2985,6 +2787,13 @@
ssl->transform = NULL;
}
+ if( ssl->session )
+ {
+ ssl_session_free( ssl->session );
+ free( ssl->session );
+ ssl->session = NULL;
+ }
+
if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
return( ret );
@@ -3191,220 +3000,11 @@
return( ssl->verify_result );
}
-const char *ssl_get_ciphersuite_name( const int ciphersuite_id )
-{
- switch( ciphersuite_id )
- {
-#if defined(POLARSSL_ARC4_C)
- case TLS_RSA_WITH_RC4_128_MD5:
- return( "TLS-RSA-WITH-RC4-128-MD5" );
-
- case TLS_RSA_WITH_RC4_128_SHA:
- return( "TLS-RSA-WITH-RC4-128-SHA" );
-#endif
-
-#if defined(POLARSSL_DES_C)
- case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
- return( "TLS-RSA-WITH-3DES-EDE-CBC-SHA" );
-
- case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
- return( "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA" );
-#endif
-
-#if defined(POLARSSL_AES_C)
- case TLS_RSA_WITH_AES_128_CBC_SHA:
- return( "TLS-RSA-WITH-AES-128-CBC-SHA" );
-
- case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
- return( "TLS-DHE-RSA-WITH-AES-128-CBC-SHA" );
-
- case TLS_RSA_WITH_AES_256_CBC_SHA:
- return( "TLS-RSA-WITH-AES-256-CBC-SHA" );
-
- case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
- return( "TLS-DHE-RSA-WITH-AES-256-CBC-SHA" );
-
-#if defined(POLARSSL_SHA2_C)
- case TLS_RSA_WITH_AES_128_CBC_SHA256:
- return( "TLS-RSA-WITH-AES-128-CBC-SHA256" );
-
- case TLS_RSA_WITH_AES_256_CBC_SHA256:
- return( "TLS-RSA-WITH-AES-256-CBC-SHA256" );
-
- case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
- return( "TLS-DHE-RSA-WITH-AES-128-CBC-SHA256" );
-
- case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
- return( "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256" );
-#endif
-
-#if defined(POLARSSL_GCM_C) && defined(POLARSSL_SHA2_C)
- case TLS_RSA_WITH_AES_128_GCM_SHA256:
- return( "TLS-RSA-WITH-AES-128-GCM-SHA256" );
-
- case TLS_RSA_WITH_AES_256_GCM_SHA384:
- return( "TLS-RSA-WITH-AES-256-GCM-SHA384" );
-#endif
-
-#if defined(POLARSSL_GCM_C) && defined(POLARSSL_SHA4_C)
- case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
- return( "TLS-DHE-RSA-WITH-AES-128-GCM-SHA256" );
-
- case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
- return( "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384" );
-#endif
-#endif /* POLARSSL_AES_C */
-
-#if defined(POLARSSL_CAMELLIA_C)
- case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA:
- return( "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA" );
-
- case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA:
- return( "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA" );
-
- case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA:
- return( "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA" );
-
- case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA:
- return( "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA" );
-
-#if defined(POLARSSL_SHA2_C)
- case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- return( "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256" );
-
- case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:
- return( "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256" );
-
- case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- return( "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256" );
-
- case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256:
- return( "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256" );
-#endif
-#endif
-
-#if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES)
-#if defined(POLARSSL_CIPHER_NULL_CIPHER)
- case TLS_RSA_WITH_NULL_MD5:
- return( "TLS-RSA-WITH-NULL-MD5" );
- case TLS_RSA_WITH_NULL_SHA:
- return( "TLS-RSA-WITH-NULL-SHA" );
- case TLS_RSA_WITH_NULL_SHA256:
- return( "TLS-RSA-WITH-NULL-SHA256" );
-#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
-
-#if defined(POLARSSL_DES_C)
- case TLS_RSA_WITH_DES_CBC_SHA:
- return( "TLS-RSA-WITH-DES-CBC-SHA" );
- case TLS_DHE_RSA_WITH_DES_CBC_SHA:
- return( "TLS-DHE-RSA-WITH-DES-CBC-SHA" );
-#endif
-#endif /* defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES) */
-
- default:
- break;
- }
-
- return( "unknown" );
-}
-
-int ssl_get_ciphersuite_id( const char *ciphersuite_name )
-{
-#if defined(POLARSSL_ARC4_C)
- if (0 == strcasecmp(ciphersuite_name, "TLS-RSA-WITH-RC4-128-MD5"))
- return( TLS_RSA_WITH_RC4_128_MD5 );
- if (0 == strcasecmp(ciphersuite_name, "TLS-RSA-WITH-RC4-128-SHA"))
- return( TLS_RSA_WITH_RC4_128_SHA );
-#endif
-
-#if defined(POLARSSL_DES_C)
- if (0 == strcasecmp(ciphersuite_name, "TLS-RSA-WITH-3DES-EDE-CBC-SHA"))
- return( TLS_RSA_WITH_3DES_EDE_CBC_SHA );
- if (0 == strcasecmp(ciphersuite_name, "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA"))
- return( TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA );
-#endif
-
-#if defined(POLARSSL_AES_C)
- if (0 == strcasecmp(ciphersuite_name, "TLS-RSA-WITH-AES-128-CBC-SHA"))
- return( TLS_RSA_WITH_AES_128_CBC_SHA );
- if (0 == strcasecmp(ciphersuite_name, "TLS-DHE-RSA-WITH-AES-128-CBC-SHA"))
- return( TLS_DHE_RSA_WITH_AES_128_CBC_SHA );
- if (0 == strcasecmp(ciphersuite_name, "TLS-RSA-WITH-AES-256-CBC-SHA"))
- return( TLS_RSA_WITH_AES_256_CBC_SHA );
- if (0 == strcasecmp(ciphersuite_name, "TLS-DHE-RSA-WITH-AES-256-CBC-SHA"))
- return( TLS_DHE_RSA_WITH_AES_256_CBC_SHA );
-
-#if defined(POLARSSL_SHA2_C)
- if (0 == strcasecmp(ciphersuite_name, "TLS-RSA-WITH-AES-128-CBC-SHA256"))
- return( TLS_RSA_WITH_AES_128_CBC_SHA256 );
- if (0 == strcasecmp(ciphersuite_name, "TLS-RSA-WITH-AES-256-CBC-SHA256"))
- return( TLS_RSA_WITH_AES_256_CBC_SHA256 );
- if (0 == strcasecmp(ciphersuite_name, "TLS-DHE-RSA-WITH-AES-128-CBC-SHA256"))
- return( TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 );
- if (0 == strcasecmp(ciphersuite_name, "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256"))
- return( TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 );
-#endif
-
-#if defined(POLARSSL_GCM_C) && defined(POLARSSL_SHA2_C)
- if (0 == strcasecmp(ciphersuite_name, "TLS-RSA-WITH-AES-128-GCM-SHA256"))
- return( TLS_RSA_WITH_AES_128_GCM_SHA256 );
- if (0 == strcasecmp(ciphersuite_name, "TLS-RSA-WITH-AES-256-GCM-SHA384"))
- return( TLS_RSA_WITH_AES_256_GCM_SHA384 );
-#endif
-
-#if defined(POLARSSL_GCM_C) && defined(POLARSSL_SHA2_C)
- if (0 == strcasecmp(ciphersuite_name, "TLS-DHE-RSA-WITH-AES-128-GCM-SHA256"))
- return( TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 );
- if (0 == strcasecmp(ciphersuite_name, "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384"))
- return( TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 );
-#endif
-#endif
-
-#if defined(POLARSSL_CAMELLIA_C)
- if (0 == strcasecmp(ciphersuite_name, "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA"))
- return( TLS_RSA_WITH_CAMELLIA_128_CBC_SHA );
- if (0 == strcasecmp(ciphersuite_name, "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA"))
- return( TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA );
- if (0 == strcasecmp(ciphersuite_name, "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA"))
- return( TLS_RSA_WITH_CAMELLIA_256_CBC_SHA );
- if (0 == strcasecmp(ciphersuite_name, "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA"))
- return( TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA );
-
-#if defined(POLARSSL_SHA2_C)
- if (0 == strcasecmp(ciphersuite_name, "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256"))
- return( TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 );
- if (0 == strcasecmp(ciphersuite_name, "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256"))
- return( TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 );
- if (0 == strcasecmp(ciphersuite_name, "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256"))
- return( TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 );
- if (0 == strcasecmp(ciphersuite_name, "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256"))
- return( TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 );
-#endif
-#endif
-
-#if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES)
-#if defined(POLARSSL_CIPHER_NULL_CIPHER)
- if (0 == strcasecmp(ciphersuite_name, "TLS-RSA-WITH-NULL-MD5"))
- return( TLS_RSA_WITH_NULL_MD5 );
- if (0 == strcasecmp(ciphersuite_name, "TLS-RSA-WITH-NULL-SHA"))
- return( TLS_RSA_WITH_NULL_SHA );
- if (0 == strcasecmp(ciphersuite_name, "TLS-RSA-WITH-NULL-SHA256"))
- return( TLS_RSA_WITH_NULL_SHA256 );
-#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
-
-#if defined(POLARSSL_DES_C)
- if (0 == strcasecmp(ciphersuite_name, "TLS-RSA-WITH-DES-CBC-SHA"))
- return( TLS_RSA_WITH_DES_CBC_SHA );
- if (0 == strcasecmp(ciphersuite_name, "TLS-DHE-RSA-WITH-DES-CBC-SHA"))
- return( TLS_DHE_RSA_WITH_DES_CBC_SHA );
-#endif
-#endif /* defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES) */
-
- return( 0 );
-}
-
const char *ssl_get_ciphersuite( const ssl_context *ssl )
{
+ if( ssl == NULL || ssl->session == NULL )
+ return NULL;
+
return ssl_get_ciphersuite_name( ssl->session->ciphersuite );
}
@@ -3438,98 +3038,42 @@
return ssl->session->peer_cert;
}
-const int ssl_default_ciphersuites[] =
+/*
+ * Perform a single step of the SSL handshake
+ */
+int ssl_handshake_step( ssl_context *ssl )
{
-#if defined(POLARSSL_DHM_C)
-#if defined(POLARSSL_AES_C)
-#if defined(POLARSSL_SHA2_C)
- TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
-#endif /* POLARSSL_SHA2_C */
-#if defined(POLARSSL_GCM_C) && defined(POLARSSL_SHA4_C)
- TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
-#endif
- TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
-#if defined(POLARSSL_SHA2_C)
- TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
-#endif
-#if defined(POLARSSL_GCM_C) && defined(POLARSSL_SHA2_C)
- TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
-#endif
- TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
-#endif
-#if defined(POLARSSL_CAMELLIA_C)
-#if defined(POLARSSL_SHA2_C)
- TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
-#endif /* POLARSSL_SHA2_C */
- TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
-#if defined(POLARSSL_SHA2_C)
- TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
-#endif /* POLARSSL_SHA2_C */
- TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
-#endif
-#if defined(POLARSSL_DES_C)
- TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
-#endif
+ int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
+
+#if defined(POLARSSL_SSL_CLI_C)
+ if( ssl->endpoint == SSL_IS_CLIENT )
+ ret = ssl_handshake_client_step( ssl );
#endif
-#if defined(POLARSSL_AES_C)
-#if defined(POLARSSL_SHA2_C)
- TLS_RSA_WITH_AES_256_CBC_SHA256,
-#endif /* POLARSSL_SHA2_C */
-#if defined(POLARSSL_GCM_C) && defined(POLARSSL_SHA4_C)
- TLS_RSA_WITH_AES_256_GCM_SHA384,
-#endif /* POLARSSL_SHA2_C */
- TLS_RSA_WITH_AES_256_CBC_SHA,
+#if defined(POLARSSL_SSL_SRV_C)
+ if( ssl->endpoint == SSL_IS_SERVER )
+ ret = ssl_handshake_server_step( ssl );
#endif
-#if defined(POLARSSL_CAMELLIA_C)
-#if defined(POLARSSL_SHA2_C)
- TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
-#endif /* POLARSSL_SHA2_C */
- TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
-#endif
-#if defined(POLARSSL_AES_C)
-#if defined(POLARSSL_SHA2_C)
- TLS_RSA_WITH_AES_128_CBC_SHA256,
-#endif /* POLARSSL_SHA2_C */
-#if defined(POLARSSL_GCM_C) && defined(POLARSSL_SHA2_C)
- TLS_RSA_WITH_AES_128_GCM_SHA256,
-#endif /* POLARSSL_SHA2_C */
- TLS_RSA_WITH_AES_128_CBC_SHA,
-#endif
-#if defined(POLARSSL_CAMELLIA_C)
-#if defined(POLARSSL_SHA2_C)
- TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
-#endif /* POLARSSL_SHA2_C */
- TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
-#endif
-#if defined(POLARSSL_DES_C)
- TLS_RSA_WITH_3DES_EDE_CBC_SHA,
-#endif
-#if defined(POLARSSL_ARC4_C)
- TLS_RSA_WITH_RC4_128_SHA,
- TLS_RSA_WITH_RC4_128_MD5,
-#endif
- 0
-};
+
+ return( ret );
+}
/*
* Perform the SSL handshake
*/
int ssl_handshake( ssl_context *ssl )
{
- int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
+ int ret = 0;
SSL_DEBUG_MSG( 2, ( "=> handshake" ) );
-#if defined(POLARSSL_SSL_CLI_C)
- if( ssl->endpoint == SSL_IS_CLIENT )
- ret = ssl_handshake_client( ssl );
-#endif
+ while( ssl->state != SSL_HANDSHAKE_OVER )
+ {
+ ret = ssl_handshake_step( ssl );
-#if defined(POLARSSL_SSL_SRV_C)
- if( ssl->endpoint == SSL_IS_SERVER )
- ret = ssl_handshake_server( ssl );
-#endif
+ if( ret != 0 )
+ break;
+ }
SSL_DEBUG_MSG( 2, ( "<= handshake" ) );
@@ -3833,6 +3377,12 @@
free( ssl->session_negotiate );
}
+ if( ssl->session )
+ {
+ ssl_session_free( ssl->session );
+ free( ssl->session );
+ }
+
if ( ssl->hostname != NULL)
{
memset( ssl->hostname, 0, ssl->hostname_len );
@@ -3850,7 +3400,7 @@
SSL_DEBUG_MSG( 2, ( "<= free" ) );
- /* Actually free after last debug message */
+ /* Actually clear after last debug message */
memset( ssl, 0, sizeof( ssl_context ) );
}
diff --git a/library/x509parse.c b/library/x509parse.c
index 493cf3a..bac0e93 100644
--- a/library/x509parse.c
+++ b/library/x509parse.c
@@ -42,12 +42,24 @@
#include "polarssl/asn1.h"
#include "polarssl/pem.h"
#include "polarssl/des.h"
+#if defined(POLARSSL_MD2_C)
#include "polarssl/md2.h"
+#endif
+#if defined(POLARSSL_MD4_C)
#include "polarssl/md4.h"
+#endif
+#if defined(POLARSSL_MD5_C)
#include "polarssl/md5.h"
+#endif
+#if defined(POLARSSL_SHA1_C)
#include "polarssl/sha1.h"
+#endif
+#if defined(POLARSSL_SHA2_C)
#include "polarssl/sha2.h"
+#endif
+#if defined(POLARSSL_SHA4_C)
#include "polarssl/sha4.h"
+#endif
#include "polarssl/dhm.h"
#include <string.h>
diff --git a/library/x509write.c b/library/x509write.c
index 9f5a910..026afe6 100644
--- a/library/x509write.c
+++ b/library/x509write.c
@@ -30,11 +30,24 @@
#include "polarssl/asn1write.h"
#include "polarssl/x509write.h"
#include "polarssl/x509.h"
-#include "polarssl/sha1.h"
-#include "polarssl/sha2.h"
-#include "polarssl/sha4.h"
+#if defined(POLARSSL_MD2_C)
+#include "polarssl/md2.h"
+#endif
+#if defined(POLARSSL_MD4_C)
#include "polarssl/md4.h"
+#endif
+#if defined(POLARSSL_MD5_C)
#include "polarssl/md5.h"
+#endif
+#if defined(POLARSSL_SHA1_C)
+#include "polarssl/sha1.h"
+#endif
+#if defined(POLARSSL_SHA2_C)
+#include "polarssl/sha2.h"
+#endif
+#if defined(POLARSSL_SHA4_C)
+#include "polarssl/sha4.h"
+#endif
int x509_write_pubkey_der( unsigned char *buf, size_t size, rsa_context *rsa )
{
diff --git a/programs/test/ssl_test.c b/programs/test/ssl_test.c
index 802fda0..e067652 100644
--- a/programs/test/ssl_test.c
+++ b/programs/test/ssl_test.c
@@ -1,7 +1,7 @@
/*
* SSL/TLS stress testing program
*
- * Copyright (C) 2006-2011, Brainspark B.V.
+ * Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
@@ -272,9 +272,8 @@
ssl_set_bio( &ssl, net_recv, &client_fd,
net_send, &client_fd );
- if( opt->force_ciphersuite[0] == DFL_FORCE_CIPHER )
- ssl_set_ciphersuites( &ssl, ssl_default_ciphersuites );
- else ssl_set_ciphersuites( &ssl, opt->force_ciphersuite );
+ if( opt->force_ciphersuite[0] != DFL_FORCE_CIPHER )
+ ssl_set_ciphersuites( &ssl, opt->force_ciphersuite );
if( opt->iomode == IOMODE_NONBLOCK )
net_set_nonblock( client_fd );
diff --git a/programs/util/strerror.c b/programs/util/strerror.c
index bb31b3d..e248201 100644
--- a/programs/util/strerror.c
+++ b/programs/util/strerror.c
@@ -38,13 +38,13 @@
#define USAGE \
"\n usage: strerror <errorcode>\n"
-#if !defined(POLARSSL_ERROR_C)
+#if !defined(POLARSSL_ERROR_C) && !defined(POLARSSL_ERROR_STRERROR_DUMMY)
int main( int argc, char *argv[] )
{
((void) argc);
((void) argv);
- printf("POLARSSL_ERROR_C not defined.\n");
+ printf("POLARSSL_ERROR_C and/or POLARSSL_ERROR_STRERRO_DUMMY not defined.\n");
return( 0 );
}
#else
diff --git a/programs/x509/cert_app.c b/programs/x509/cert_app.c
index 2fb0c85..c9f74dd 100644
--- a/programs/x509/cert_app.c
+++ b/programs/x509/cert_app.c
@@ -1,7 +1,7 @@
/*
* Certificate reading application
*
- * Copyright (C) 2006-2011, Brainspark B.V.
+ * Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
@@ -284,8 +284,6 @@
ssl_set_bio( &ssl, net_recv, &server_fd,
net_send, &server_fd );
- ssl_set_ciphersuites( &ssl, ssl_default_ciphersuites );
-
ssl_set_own_cert( &ssl, &clicert, &rsa );
ssl_set_hostname( &ssl, opt.server_name );
diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data
index f89bd9b..267527a 100644
--- a/tests/suites/test_suite_version.data
+++ b/tests/suites/test_suite_version.data
@@ -1,5 +1,5 @@
Check compiletime library version
-check_compiletime_version:"1.2.3"
+check_compiletime_version:"1.2.6"
Check runtime library version
-check_runtime_version:"1.2.3"
+check_runtime_version:"1.2.6"