diff options
author | unknown <msvensson@shellback.(none)> | 2006-11-29 09:21:37 +0100 |
---|---|---|
committer | unknown <msvensson@shellback.(none)> | 2006-11-29 09:21:37 +0100 |
commit | eb6ab467cee34e31930ff8496f7eea4b636fabe6 (patch) | |
tree | 5d536b5e9188dd4985d4f225dd2cf252fbba06d2 | |
parent | be820c11d045345aaefea21ead49cfac60b1c31c (diff) | |
download | mariadb-git-eb6ab467cee34e31930ff8496f7eea4b636fabe6.tar.gz |
Import version 1.50 of yaSSL
extra/yassl/README:
Import patch yassl.diff
extra/yassl/examples/client/client.cpp:
Import patch yassl.diff
extra/yassl/examples/echoclient/echoclient.cpp:
Import patch yassl.diff
extra/yassl/examples/echoserver/echoserver.cpp:
Import patch yassl.diff
extra/yassl/examples/server/server.cpp:
Import patch yassl.diff
extra/yassl/include/factory.hpp:
Import patch yassl.diff
extra/yassl/include/openssl/ssl.h:
Import patch yassl.diff
extra/yassl/include/socket_wrapper.hpp:
Import patch yassl.diff
extra/yassl/include/yassl_error.hpp:
Import patch yassl.diff
extra/yassl/include/yassl_imp.hpp:
Import patch yassl.diff
extra/yassl/include/yassl_int.hpp:
Import patch yassl.diff
extra/yassl/include/yassl_types.hpp:
Import patch yassl.diff
extra/yassl/src/handshake.cpp:
Import patch yassl.diff
extra/yassl/src/make.bat:
Import patch yassl.diff
extra/yassl/src/socket_wrapper.cpp:
Import patch yassl.diff
extra/yassl/src/ssl.cpp:
Import patch yassl.diff
extra/yassl/src/yassl_error.cpp:
Import patch yassl.diff
extra/yassl/src/yassl_imp.cpp:
Import patch yassl.diff
extra/yassl/src/yassl_int.cpp:
Import patch yassl.diff
extra/yassl/taocrypt/benchmark/make.bat:
Import patch yassl.diff
extra/yassl/taocrypt/include/aes.hpp:
Import patch yassl.diff
extra/yassl/taocrypt/include/algebra.hpp:
Import patch yassl.diff
extra/yassl/taocrypt/include/arc4.hpp:
Import patch yassl.diff
extra/yassl/taocrypt/include/asn.hpp:
Import patch yassl.diff
extra/yassl/taocrypt/include/block.hpp:
Import patch yassl.diff
extra/yassl/taocrypt/include/blowfish.hpp:
Import patch yassl.diff
extra/yassl/taocrypt/include/des.hpp:
Import patch yassl.diff
extra/yassl/taocrypt/include/integer.hpp:
Import patch yassl.diff
extra/yassl/taocrypt/include/md5.hpp:
Import patch yassl.diff
extra/yassl/taocrypt/include/misc.hpp:
Import patch yassl.diff
extra/yassl/taocrypt/include/modes.hpp:
Import patch yassl.diff
extra/yassl/taocrypt/include/ripemd.hpp:
Import patch yassl.diff
extra/yassl/taocrypt/include/rsa.hpp:
Import patch yassl.diff
extra/yassl/taocrypt/include/sha.hpp:
Import patch yassl.diff
extra/yassl/taocrypt/include/twofish.hpp:
Import patch yassl.diff
extra/yassl/taocrypt/src/aes.cpp:
Import patch yassl.diff
extra/yassl/taocrypt/src/algebra.cpp:
Import patch yassl.diff
extra/yassl/taocrypt/src/arc4.cpp:
Import patch yassl.diff
extra/yassl/taocrypt/src/blowfish.cpp:
Import patch yassl.diff
extra/yassl/taocrypt/src/des.cpp:
Import patch yassl.diff
extra/yassl/taocrypt/src/integer.cpp:
Import patch yassl.diff
extra/yassl/taocrypt/src/make.bat:
Import patch yassl.diff
extra/yassl/taocrypt/src/md4.cpp:
Import patch yassl.diff
extra/yassl/taocrypt/src/md5.cpp:
Import patch yassl.diff
extra/yassl/taocrypt/src/misc.cpp:
Import patch yassl.diff
extra/yassl/taocrypt/src/random.cpp:
Import patch yassl.diff
extra/yassl/taocrypt/src/ripemd.cpp:
Import patch yassl.diff
extra/yassl/taocrypt/src/sha.cpp:
Import patch yassl.diff
extra/yassl/taocrypt/src/twofish.cpp:
Import patch yassl.diff
extra/yassl/taocrypt/test/make.bat:
Import patch yassl.diff
extra/yassl/taocrypt/test/test.cpp:
Import patch yassl.diff
extra/yassl/testsuite/make.bat:
Import patch yassl.diff
extra/yassl/testsuite/test.hpp:
Import patch yassl.diff
extra/yassl/include/openssl/prefix_ssl.h:
New prefic file for ssl.h generated
54 files changed, 1116 insertions, 482 deletions
diff --git a/extra/yassl/README b/extra/yassl/README index 2af4e98fe4c..fbeffd9db77 100644 --- a/extra/yassl/README +++ b/extra/yassl/README @@ -1,4 +1,56 @@ -yaSSL Release notes, version 1.4.0 (08/13/06) +yaSSL Release notes, version 1.5.0 (11/09/06) + + This release of yaSSL contains bug fixes, portability enhancements, + and full TLS 1.1 support. Use the functions: + + SSL_METHOD *TLSv1_1_server_method(void); + SSL_METHOD *TLSv1_1_client_method(void); + + or the SSLv23 versions (even though yaSSL doesn't support SSL 2.0 the v23 + means to pick the highest of SSL 3.0, TLS 1.0, or TLS 1.1. + + +See normal build instructions below under 1.0.6. +See libcurl build instructions below under 1.3.0. + + + +****************yaSSL Release notes, version 1.4.5 (10/15/06) + + + This release of yaSSL contains bug fixes, portability enhancements, + zlib compression support, removal of assembly instructions at runtime if + not supported, and initial TLS 1.1 support. + + + Compression Notes: yaSSL uses zlib for compression and the compression + should only be used if yaSSL is at both ends because the implementation + details aren't yet standard. If you'd like to turn compression on use + the SSL_set_compression() function on the client before calling + SSL_connect(). If both the client and server were built with zlib support + then the connection will use compression. If the client isn't built with + support then SSL_set_compression() will return an error (-1). + + To build yaSSL with zlib support on Unix simply have zlib support on your + system and configure will find it if it's in the standard locations. If + it's somewhere else use the option ./configure --with-zlib=DIR. If you'd + like to disable compression support in yaSSL use ./configure --without-zlib. + + To build yaSSL with zlib support on Windows: + + 1) download zlib from http://www.zlib.net/ + 2) follow the instructions in zlib from projects/visualc6/README.txt + for how to add the zlib project into the yaSSL workspace noting that + you'll need to add configuration support for "Win32 Debug" and + "Win32 Release" in note 3 under "To use:". + 3) define HAVE_LIBZ when building yaSSL + + +See normal build instructions below under 1.0.6. +See libcurl build instructions below under 1.3.0. + + +********************yaSSL Release notes, version 1.4.0 (08/13/06) This release of yaSSL contains bug fixes, portability enhancements, @@ -122,18 +174,6 @@ Choose (Re)Build All from the project workspace run Debug\testsuite.exe from yaSSL-Home\testsuite to test the build ---To enable ia32 assembly for TaoCrypt ciphers and message digests - - On MSVC this is always on - - On GCC **, use ./configure --enable-ia32-asm - - ** This isn't on by default because of the use of intel syntax and the - problem that olders versions of gas have with some addressing statements. - If you enable this and get assemler errors during compilation or can't - pass the TaoCrypt tests, please send todd@yassl.com a message and disable - this option in the meantime. - ***************** yaSSL Release notes, version 1.0.5 diff --git a/extra/yassl/examples/client/client.cpp b/extra/yassl/examples/client/client.cpp index d655011deb6..6c3cdf04dc1 100644 --- a/extra/yassl/examples/client/client.cpp +++ b/extra/yassl/examples/client/client.cpp @@ -5,6 +5,35 @@ //#define TEST_RESUME +void ClientError(SSL_CTX* ctx, SSL* ssl, SOCKET_T& sockfd, const char* msg) +{ + SSL_CTX_free(ctx); + SSL_free(ssl); + tcp_close(sockfd); + err_sys(msg); +} + + +#ifdef NON_BLOCKING + void NonBlockingSSL_Connect(SSL* ssl, SSL_CTX* ctx, SOCKET_T& sockfd) + { + int ret = SSL_connect(ssl); + while (ret =! SSL_SUCCESS && SSL_get_error(ssl, 0) == + SSL_ERROR_WANT_READ) { + printf("... client would block\n"); + #ifdef _WIN32 + Sleep(1000); + #else + sleep(1); + #endif + ret = SSL_connect(ssl); + } + if (ret != SSL_SUCCESS) + ClientError(ctx, ssl, sockfd, "SSL_connect failed"); + } +#endif + + void client_test(void* args) { #ifdef _WIN32 @@ -18,6 +47,9 @@ void client_test(void* args) set_args(argc, argv, *static_cast<func_args*>(args)); tcp_connect(sockfd); +#ifdef NON_BLOCKING + tcp_set_nonblocking(sockfd); +#endif SSL_METHOD* method = TLSv1_client_method(); SSL_CTX* ctx = SSL_CTX_new(method); @@ -27,13 +59,13 @@ void client_test(void* args) SSL_set_fd(ssl, sockfd); + +#ifdef NON_BLOCKING + NonBlockingSSL_Connect(ssl, ctx, sockfd); +#else if (SSL_connect(ssl) != SSL_SUCCESS) - { - SSL_CTX_free(ctx); - SSL_free(ssl); - tcp_close(sockfd); - err_sys("SSL_connect failed"); - } + ClientError(ctx, ssl, sockfd, "SSL_connect failed"); +#endif showPeer(ssl); const char* cipher = 0; @@ -49,16 +81,14 @@ void client_test(void* args) char msg[] = "hello yassl!"; if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg)) - { - SSL_CTX_free(ctx); - SSL_free(ssl); - tcp_close(sockfd); - err_sys("SSL_write failed"); - } + ClientError(ctx, ssl, sockfd, "SSL_write failed"); char reply[1024]; - reply[SSL_read(ssl, reply, sizeof(reply))] = 0; + int input = SSL_read(ssl, reply, sizeof(reply)); + if (input > 0) { + reply[input] = 0; printf("Server response: %s\n", reply); + } #ifdef TEST_RESUME SSL_SESSION* session = SSL_get_session(ssl); @@ -75,24 +105,17 @@ void client_test(void* args) SSL_set_session(sslResume, session); if (SSL_connect(sslResume) != SSL_SUCCESS) - { - SSL_CTX_free(ctx); - SSL_free(ssl); - tcp_close(sockfd); - err_sys("SSL resume failed"); - } + ClientError(ctx, sslResume, sockfd, "SSL_resume failed"); showPeer(sslResume); if (SSL_write(sslResume, msg, sizeof(msg)) != sizeof(msg)) - { - SSL_CTX_free(ctx); - SSL_free(ssl); - tcp_close(sockfd); - err_sys("SSL_write failed"); - } + ClientError(ctx, sslResume, sockfd, "SSL_write failed"); - reply[SSL_read(sslResume, reply, sizeof(reply))] = 0; + input = SSL_read(sslResume, reply, sizeof(reply)); + if (input > 0) { + reply[input] = 0; printf("Server response: %s\n", reply); + } SSL_shutdown(sslResume); SSL_free(sslResume); diff --git a/extra/yassl/examples/echoclient/echoclient.cpp b/extra/yassl/examples/echoclient/echoclient.cpp index 983254bf8a7..e2c33c7cda2 100644 --- a/extra/yassl/examples/echoclient/echoclient.cpp +++ b/extra/yassl/examples/echoclient/echoclient.cpp @@ -3,6 +3,15 @@ #include "../../testsuite/test.hpp" +void EchoClientError(SSL_CTX* ctx, SSL* ssl, SOCKET_T& sockfd, const char* msg) +{ + SSL_CTX_free(ctx); + SSL_free(ssl); + tcp_close(sockfd); + err_sys(msg); +} + + void echoclient_test(void* args) { #ifdef _WIN32 @@ -35,7 +44,7 @@ void echoclient_test(void* args) tcp_connect(sockfd); - SSL_METHOD* method = TLSv1_client_method(); + SSL_METHOD* method = SSLv23_client_method(); SSL_CTX* ctx = SSL_CTX_new(method); set_certs(ctx); SSL* ssl = SSL_new(ctx); @@ -43,12 +52,7 @@ void echoclient_test(void* args) SSL_set_fd(ssl, sockfd); if (SSL_connect(ssl) != SSL_SUCCESS) - { - SSL_CTX_free(ctx); - SSL_free(ssl); - tcp_close(sockfd); - err_sys("SSL_connect failed"); - } + EchoClientError(ctx, ssl, sockfd, "SSL_connect failed"); char send[1024]; char reply[1024]; @@ -57,12 +61,7 @@ void echoclient_test(void* args) int sendSz = strlen(send) + 1; if (SSL_write(ssl, send, sendSz) != sendSz) - { - SSL_CTX_free(ctx); - SSL_free(ssl); - tcp_close(sockfd); - err_sys("SSL_write failed"); - } + EchoClientError(ctx, ssl, sockfd, "SSL_write failed"); if (strncmp(send, "quit", 4) == 0) { fputs("sending server shutdown command: quit!\n", fout); diff --git a/extra/yassl/examples/echoserver/echoserver.cpp b/extra/yassl/examples/echoserver/echoserver.cpp index cd31fedddd8..92613744ba0 100644 --- a/extra/yassl/examples/echoserver/echoserver.cpp +++ b/extra/yassl/examples/echoserver/echoserver.cpp @@ -56,7 +56,7 @@ THREAD_RETURN YASSL_API echoserver_test(void* args) tcp_listen(sockfd); - SSL_METHOD* method = TLSv1_server_method(); + SSL_METHOD* method = SSLv23_server_method(); SSL_CTX* ctx = SSL_CTX_new(method); set_serverCerts(ctx); @@ -87,8 +87,12 @@ THREAD_RETURN YASSL_API echoserver_test(void* args) SSL* ssl = SSL_new(ctx); SSL_set_fd(ssl, clientfd); - if (SSL_accept(ssl) != SSL_SUCCESS) - EchoError(ctx, ssl, sockfd, clientfd, "SSL_accept failed"); + if (SSL_accept(ssl) != SSL_SUCCESS) { + printf("SSL_accept failed\n"); + SSL_free(ssl); + tcp_close(clientfd); + continue; + } char command[1024]; int echoSz(0); @@ -130,6 +134,7 @@ THREAD_RETURN YASSL_API echoserver_test(void* args) if (SSL_write(ssl, command, echoSz) != echoSz) EchoError(ctx, ssl, sockfd, clientfd, "SSL_write failed"); } + SSL_shutdown(ssl); SSL_free(ssl); tcp_close(clientfd); } diff --git a/extra/yassl/examples/server/server.cpp b/extra/yassl/examples/server/server.cpp index d0bf70cd634..75ce4224770 100644 --- a/extra/yassl/examples/server/server.cpp +++ b/extra/yassl/examples/server/server.cpp @@ -13,6 +13,26 @@ void ServerError(SSL_CTX* ctx, SSL* ssl, SOCKET_T& sockfd, const char* msg) } +#ifdef NON_BLOCKING + void NonBlockingSSL_Accept(SSL* ssl, SSL_CTX* ctx, SOCKET_T& clientfd) + { + int ret = SSL_accept(ssl); + while (ret != SSL_SUCCESS && SSL_get_error(ssl, 0) == + SSL_ERROR_WANT_READ) { + printf("... server would block\n"); + #ifdef _WIN32 + Sleep(1000); + #else + sleep(1); + #endif + ret = SSL_accept(ssl); + } + if (ret != SSL_SUCCESS) + ServerError(ctx, ssl, clientfd, "SSL_accept failed"); + } +#endif + + THREAD_RETURN YASSL_API server_test(void* args) { #ifdef _WIN32 @@ -33,7 +53,7 @@ THREAD_RETURN YASSL_API server_test(void* args) SSL_METHOD* method = TLSv1_server_method(); SSL_CTX* ctx = SSL_CTX_new(method); - //SSL_CTX_set_cipher_list(ctx, "RC4-SHA"); + //SSL_CTX_set_cipher_list(ctx, "RC4-SHA:RC4-MD5"); SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, 0); set_serverCerts(ctx); DH* dh = set_tmpDH(ctx); @@ -41,15 +61,22 @@ THREAD_RETURN YASSL_API server_test(void* args) SSL* ssl = SSL_new(ctx); SSL_set_fd(ssl, clientfd); +#ifdef NON_BLOCKING + NonBlockingSSL_Accept(ssl, ctx, clientfd); +#else if (SSL_accept(ssl) != SSL_SUCCESS) ServerError(ctx, ssl, clientfd, "SSL_accept failed"); +#endif showPeer(ssl); printf("Using Cipher Suite: %s\n", SSL_get_cipher(ssl)); char command[1024]; - command[SSL_read(ssl, command, sizeof(command))] = 0; + int input = SSL_read(ssl, command, sizeof(command)); + if (input > 0) { + command[input] = 0; printf("First client command: %s\n", command); + } char msg[] = "I hear you, fa shizzle!"; if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg)) @@ -57,6 +84,7 @@ THREAD_RETURN YASSL_API server_test(void* args) DH_free(dh); SSL_CTX_free(ctx); + SSL_shutdown(ssl); SSL_free(ssl); tcp_close(clientfd); @@ -82,3 +110,4 @@ THREAD_RETURN YASSL_API server_test(void* args) } #endif // NO_MAIN_DRIVER + diff --git a/extra/yassl/include/factory.hpp b/extra/yassl/include/factory.hpp index 04d742431dc..dc25cf0ee70 100644 --- a/extra/yassl/include/factory.hpp +++ b/extra/yassl/include/factory.hpp @@ -42,12 +42,7 @@ namespace STL = STL_NAMESPACE; -// VC60 workaround: it doesn't allow typename in some places -#if defined(_MSC_VER) && (_MSC_VER < 1300) - #define CPP_TYPENAME -#else - #define CPP_TYPENAME typename -#endif + namespace yaSSL { diff --git a/extra/yassl/include/openssl/prefix_ssl.h b/extra/yassl/include/openssl/prefix_ssl.h index aa3f799cf80..dc6e3ef81f0 100644 --- a/extra/yassl/include/openssl/prefix_ssl.h +++ b/extra/yassl/include/openssl/prefix_ssl.h @@ -52,6 +52,7 @@ #define SSL_set_session yaSSL_set_session #define SSL_get_session yaSSL_get_session #define SSL_SESSION_set_timeout yaSSL_SESSION_set_timeout +#define SSL_CTX_set_session_cache_mode yaSSL_CTX_set_session_cache_mode #define SSL_get_peer_certificate yaSSL_get_peer_certificate #define SSL_get_verify_result yaSSL_get_verify_result #define SSL_CTX_set_verify yaSSL_CTX_set_verify @@ -98,6 +99,8 @@ #define SSLv3_client_method yaSSLv3_client_method #define TLSv1_server_method yaTLSv1_server_method #define TLSv1_client_method yaTLSv1_client_method +#define TLSv1_1_server_method yaTLSv1_1_server_method +#define TLSv1_1_client_method yaTLSv1_1_client_method #define SSLv23_server_method yaSSLv23_server_method #define SSL_CTX_use_certificate_file yaSSL_CTX_use_certificate_file #define SSL_CTX_use_PrivateKey_file yaSSL_CTX_use_PrivateKey_file @@ -159,3 +162,4 @@ #define MD5_Init yaMD5_Init #define MD5_Update yaMD5_Update #define MD5_Final yaMD5_Final +#define SSL_set_compression yaSSL_set_compression diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h index 5e7290d2a7a..67c49a808fd 100644 --- a/extra/yassl/include/openssl/ssl.h +++ b/extra/yassl/include/openssl/ssl.h @@ -41,7 +41,7 @@ #include "rsa.h" -#define YASSL_VERSION "1.4.3" +#define YASSL_VERSION "1.5.0" #if defined(__cplusplus) @@ -228,6 +228,7 @@ void SSL_load_error_strings(void); int SSL_set_session(SSL *ssl, SSL_SESSION *session); SSL_SESSION* SSL_get_session(SSL* ssl); long SSL_SESSION_set_timeout(SSL_SESSION*, long); +long SSL_CTX_set_session_cache_mode(SSL_CTX* ctx, long mode); X509* SSL_get_peer_certificate(SSL*); long SSL_get_verify_result(SSL*); @@ -361,6 +362,8 @@ SSL_METHOD *SSLv3_server_method(void); SSL_METHOD *SSLv3_client_method(void); SSL_METHOD *TLSv1_server_method(void); SSL_METHOD *TLSv1_client_method(void); +SSL_METHOD *TLSv1_1_server_method(void); +SSL_METHOD *TLSv1_1_client_method(void); SSL_METHOD *SSLv23_server_method(void); int SSL_CTX_use_certificate_file(SSL_CTX*, const char*, int); @@ -531,6 +534,10 @@ void MD5_Final(unsigned char*, MD5_CTX*); #define SSL_DEFAULT_CIPHER_LIST "" /* default all */ +/* yaSSL adds */ +int SSL_set_compression(SSL*); /* turn on yaSSL zlib compression */ + + #if defined(__cplusplus) && !defined(YASSL_MYSQL_COMPATIBLE) diff --git a/extra/yassl/include/socket_wrapper.hpp b/extra/yassl/include/socket_wrapper.hpp index 9fc0d62f90e..bc82384d85e 100644 --- a/extra/yassl/include/socket_wrapper.hpp +++ b/extra/yassl/include/socket_wrapper.hpp @@ -70,8 +70,8 @@ typedef unsigned char byte; // Wraps Windows Sockets and BSD Sockets class Socket { socket_t socket_; // underlying socket descriptor - bool wouldBlock_; // for non-blocking data - bool blocking_; // is option set + bool wouldBlock_; // if non-blocking data, for last read + bool nonBlocking_; // is option set public: explicit Socket(socket_t s = INVALID_SOCKET); ~Socket(); @@ -85,7 +85,7 @@ public: bool wait(); bool WouldBlock() const; - bool IsBlocking() const; + bool IsNonBlocking() const; void closeSocket(); void shutDown(int how = SD_SEND); diff --git a/extra/yassl/include/yassl_error.hpp b/extra/yassl/include/yassl_error.hpp index 72b79b05dbd..f820e5811d9 100644 --- a/extra/yassl/include/yassl_error.hpp +++ b/extra/yassl/include/yassl_error.hpp @@ -56,7 +56,10 @@ enum YasslError { receive_error = 114, certificate_error = 115, privateKey_error = 116, - badVersion_error = 117 + badVersion_error = 117, + compress_error = 118, + decompress_error = 119, + pms_version_error = 120 // !!!! add error message to .cpp !!!! diff --git a/extra/yassl/include/yassl_imp.hpp b/extra/yassl/include/yassl_imp.hpp index 180d7fe7fe1..f51a902b2a5 100644 --- a/extra/yassl/include/yassl_imp.hpp +++ b/extra/yassl/include/yassl_imp.hpp @@ -132,7 +132,6 @@ class Data : public Message { public: Data(); Data(uint16 len, opaque* b); - Data(uint16 len, const opaque* w); friend output_buffer& operator<<(output_buffer&, const Data&); @@ -141,9 +140,9 @@ public: ContentType get_type() const; uint16 get_length() const; - const opaque* get_buffer() const; void set_length(uint16 l); opaque* set_buffer(); + void SetData(uint16, const opaque*); void Process(input_buffer&, SSL&); private: Data(const Data&); // hide copy @@ -232,11 +231,11 @@ public: void Process(input_buffer&, SSL&); const opaque* get_random() const; - friend void buildClientHello(SSL&, ClientHello&, CompressionMethod); + friend void buildClientHello(SSL&, ClientHello&); friend void ProcessOldClientHello(input_buffer& input, SSL& ssl); ClientHello(); - explicit ClientHello(ProtocolVersion pv); + ClientHello(ProtocolVersion pv, bool useCompression); private: ClientHello(const ClientHello&); // hide copy ClientHello& operator=(const ClientHello&); // and assign @@ -253,7 +252,7 @@ class ServerHello : public HandShakeBase { opaque cipher_suite_[SUITE_LEN]; CompressionMethod compression_method_; public: - explicit ServerHello(ProtocolVersion pv); + ServerHello(ProtocolVersion pv, bool useCompression); ServerHello(); friend input_buffer& operator>>(input_buffer&, ServerHello&); @@ -629,8 +628,11 @@ struct Connection { bool send_server_key_; // server key exchange? bool master_clean_; // master secret clean? bool TLS_; // TLSv1 or greater + bool TLSv1_1_; // TLSv1.1 or greater bool sessionID_Set_; // do we have a session - ProtocolVersion version_; + bool compression_; // zlib compression? + ProtocolVersion version_; // negotiated version + ProtocolVersion chVersion_; // client hello version RandomPool& random_; Connection(ProtocolVersion v, RandomPool& ran); @@ -640,6 +642,7 @@ struct Connection { void CleanPreMaster(); void CleanMaster(); void TurnOffTLS(); + void TurnOffTLS1_1(); private: Connection(const Connection&); // hide copy Connection& operator=(const Connection&); // and assign diff --git a/extra/yassl/include/yassl_int.hpp b/extra/yassl/include/yassl_int.hpp index 0edff289b61..4a3c0ba4e20 100644 --- a/extra/yassl/include/yassl_int.hpp +++ b/extra/yassl/include/yassl_int.hpp @@ -431,6 +431,7 @@ private: DH_Parms dhParms_; pem_password_cb passwordCb_; void* userData_; + bool sessionCacheOff_; Stats stats_; Mutex mutex_; // for Stats public: @@ -445,6 +446,7 @@ public: const Stats& GetStats() const; pem_password_cb GetPasswordCb() const; void* GetUserData() const; + bool GetSessionCacheOff() const; void setVerifyPeer(); void setVerifyNone(); @@ -453,6 +455,7 @@ public: bool SetDH(const DH&); void SetPasswordCb(pem_password_cb cb); void SetUserData(void*); + void SetSessionCacheOff(); void IncrementStats(StatsField); void AddCA(x509* ca); @@ -600,6 +603,7 @@ public: const Socket& getSocket() const; YasslError GetError() const; bool GetMultiProtocol() const; + bool CompressionOn() const; Crypto& useCrypto(); Security& useSecurity(); @@ -617,9 +621,12 @@ public: void set_preMaster(const opaque*, uint); void set_masterSecret(const opaque*); void SetError(YasslError); + int SetCompression(); + void UnSetCompression(); // helpers bool isTLS() const; + bool isTLSv1_1() const; void order_error(); void makeMasterSecret(); void makeTLSMasterSecret(); @@ -653,6 +660,10 @@ private: }; +// compression +int Compress(const byte*, int, input_buffer&); +int DeCompress(input_buffer&, int, input_buffer&); + // conversion functions void c32to24(uint32, uint24&); diff --git a/extra/yassl/include/yassl_types.hpp b/extra/yassl/include/yassl_types.hpp index e602ee180bf..646c71afddf 100644 --- a/extra/yassl/include/yassl_types.hpp +++ b/extra/yassl/include/yassl_types.hpp @@ -211,6 +211,7 @@ const int FINISHED_LABEL_SZ = 15; // TLS finished lable length const int SEED_LEN = RAN_LEN * 2; // TLS seed, client + server random const int DEFAULT_TIMEOUT = 500; // Default Session timeout in seconds const int MAX_RECORD_SIZE = 16384; // 2^14, max size by standard +const int COMPRESS_EXTRA = 1024; // extra compression possible addition typedef uint8 Cipher; // first byte is always 0x00 for SSLv3 & TLS @@ -222,7 +223,7 @@ typedef opaque* DistinguishedName; typedef bool IsExportable; -enum CompressionMethod { no_compression = 0 }; +enum CompressionMethod { no_compression = 0, zlib = 221 }; enum CipherType { stream, block }; diff --git a/extra/yassl/src/handshake.cpp b/extra/yassl/src/handshake.cpp index 25f36c4ea8c..c03d72ff2ef 100644 --- a/extra/yassl/src/handshake.cpp +++ b/extra/yassl/src/handshake.cpp @@ -40,9 +40,11 @@ namespace yaSSL { // Build a client hello message from cipher suites and compression method -void buildClientHello(SSL& ssl, ClientHello& hello, - CompressionMethod compression = no_compression) +void buildClientHello(SSL& ssl, ClientHello& hello) { + // store for pre master secret + ssl.useSecurity().use_connection().chVersion_ = hello.client_version_; + ssl.getCrypto().get_random().Fill(hello.random_, RAN_LEN); if (ssl.getSecurity().get_resuming()) { hello.id_len_ = ID_LEN; @@ -55,7 +57,6 @@ void buildClientHello(SSL& ssl, ClientHello& hello, memcpy(hello.cipher_suites_, ssl.getSecurity().get_parms().suites_, hello.suite_len_); hello.comp_len_ = 1; - hello.compression_methods_ = compression; hello.set_length(sizeof(ProtocolVersion) + RAN_LEN + @@ -83,7 +84,7 @@ void buildServerHello(SSL& ssl, ServerHello& hello) hello.cipher_suite_[0] = ssl.getSecurity().get_parms().suite_[0]; hello.cipher_suite_[1] = ssl.getSecurity().get_parms().suite_[1]; - hello.compression_method_ = no_compression; + hello.compression_method_ = hello.compression_method_; hello.set_length(sizeof(ProtocolVersion) + RAN_LEN + ID_LEN + sizeof(hello.id_len_) + SUITE_LEN + SIZEOF_ENUM); @@ -151,12 +152,18 @@ void buildHeaders(SSL& ssl, HandShakeHeader& hsHeader, // add handshake from buffer into md5 and sha hashes, exclude record header -void hashHandShake(SSL& ssl, const output_buffer& output) +void hashHandShake(SSL& ssl, const output_buffer& output, bool removeIV = false) { uint sz = output.get_size() - RECORD_HEADER; const opaque* buffer = output.get_buffer() + RECORD_HEADER; + if (removeIV) { // TLSv1_1 IV + uint blockSz = ssl.getCrypto().get_cipher().get_blockSize(); + sz -= blockSz; + buffer += blockSz; + } + ssl.useHashes().use_MD5().update(buffer, sz); ssl.useHashes().use_SHA().update(buffer, sz); } @@ -229,6 +236,18 @@ void decrypt_message(SSL& ssl, input_buffer& input, uint sz) ssl.useCrypto().use_cipher().decrypt(plain.get_buffer(), cipher, sz); memcpy(cipher, plain.get_buffer(), sz); ssl.useSecurity().use_parms().encrypt_size_ = sz; + + if (ssl.isTLSv1_1()) // IV + input.set_current(input.get_current() + + ssl.getCrypto().get_cipher().get_blockSize()); +} + + +// output operator for input_buffer +output_buffer& operator<<(output_buffer& output, const input_buffer& input) +{ + output.write(input.get_buffer(), input.get_size()); + return output; } @@ -239,9 +258,12 @@ void cipherFinished(SSL& ssl, Finished& fin, output_buffer& output) uint finishedSz = ssl.isTLS() ? TLS_FINISHED_SZ : FINISHED_SZ; uint sz = RECORD_HEADER + HANDSHAKE_HEADER + finishedSz + digestSz; uint pad = 0; + uint blockSz = ssl.getCrypto().get_cipher().get_blockSize(); + if (ssl.getSecurity().get_parms().cipher_type_ == block) { + if (ssl.isTLSv1_1()) + sz += blockSz; // IV sz += 1; // pad byte - uint blockSz = ssl.getCrypto().get_cipher().get_blockSize(); pad = (sz - RECORD_HEADER) % blockSz; pad = blockSz - pad; sz += pad; @@ -252,14 +274,21 @@ void cipherFinished(SSL& ssl, Finished& fin, output_buffer& output) buildHeaders(ssl, hsHeader, rlHeader, fin); rlHeader.length_ = sz - RECORD_HEADER; // record header includes mac // and pad, hanshake doesn't + input_buffer iv; + if (ssl.isTLSv1_1() && ssl.getSecurity().get_parms().cipher_type_== block){ + iv.allocate(blockSz); + ssl.getCrypto().get_random().Fill(iv.get_buffer(), blockSz); + iv.add_size(blockSz); + } + uint ivSz = iv.get_size(); output.allocate(sz); - output << rlHeader << hsHeader << fin; + output << rlHeader << iv << hsHeader << fin; - hashHandShake(ssl, output); + hashHandShake(ssl, output, ssl.isTLSv1_1() ? true : false); opaque digest[SHA_LEN]; // max size if (ssl.isTLS()) - TLS_hmac(ssl, digest, output.get_buffer() + RECORD_HEADER, - output.get_size() - RECORD_HEADER, handshake); + TLS_hmac(ssl, digest, output.get_buffer() + RECORD_HEADER + ivSz, + output.get_size() - RECORD_HEADER - ivSz, handshake); else hmac(ssl, digest, output.get_buffer() + RECORD_HEADER, output.get_size() - RECORD_HEADER, handshake); @@ -282,9 +311,12 @@ void buildMessage(SSL& ssl, output_buffer& output, const Message& msg) uint digestSz = ssl.getCrypto().get_digest().get_digestSize(); uint sz = RECORD_HEADER + msg.get_length() + digestSz; uint pad = 0; + uint blockSz = ssl.getCrypto().get_cipher().get_blockSize(); + if (ssl.getSecurity().get_parms().cipher_type_ == block) { + if (ssl.isTLSv1_1()) // IV + sz += blockSz; sz += 1; // pad byte - uint blockSz = ssl.getCrypto().get_cipher().get_blockSize(); pad = (sz - RECORD_HEADER) % blockSz; pad = blockSz - pad; sz += pad; @@ -294,13 +326,21 @@ void buildMessage(SSL& ssl, output_buffer& output, const Message& msg) buildHeader(ssl, rlHeader, msg); rlHeader.length_ = sz - RECORD_HEADER; // record header includes mac // and pad, hanshake doesn't + input_buffer iv; + if (ssl.isTLSv1_1() && ssl.getSecurity().get_parms().cipher_type_== block){ + iv.allocate(blockSz); + ssl.getCrypto().get_random().Fill(iv.get_buffer(), blockSz); + iv.add_size(blockSz); + } + + uint ivSz = iv.get_size(); output.allocate(sz); - output << rlHeader << msg; + output << rlHeader << iv << msg; opaque digest[SHA_LEN]; // max size if (ssl.isTLS()) - TLS_hmac(ssl, digest, output.get_buffer() + RECORD_HEADER, - output.get_size() - RECORD_HEADER, msg.get_type()); + TLS_hmac(ssl, digest, output.get_buffer() + RECORD_HEADER + ivSz, + output.get_size() - RECORD_HEADER - ivSz, msg.get_type()); else hmac(ssl, digest, output.get_buffer() + RECORD_HEADER, output.get_size() - RECORD_HEADER, msg.get_type()); @@ -456,6 +496,10 @@ void buildSHA_CertVerify(SSL& ssl, byte* digest) // some clients still send sslv2 client hello void ProcessOldClientHello(input_buffer& input, SSL& ssl) { + if (input.get_remaining() < 2) { + ssl.SetError(bad_input); + return; + } byte b0 = input[AUTO]; byte b1 = input[AUTO]; @@ -721,6 +765,7 @@ int DoProcessReply(SSL& ssl) // each message in record, can be more than 1 if not encrypted if (ssl.getSecurity().get_parms().pending_ == false) // cipher on decrypt_message(ssl, buffer, hdr.length_); + mySTL::auto_ptr<Message> msg(mf.CreateObject(hdr.type_)); if (!msg.get()) { ssl.SetError(factory_error); @@ -744,13 +789,13 @@ void processReply(SSL& ssl) if (DoProcessReply(ssl)) // didn't complete process - if (!ssl.getSocket().IsBlocking()) { - // keep trying now + if (!ssl.getSocket().IsNonBlocking()) { + // keep trying now, blocking ok while (!ssl.GetError()) if (DoProcessReply(ssl) == 0) break; } else - // user will have try again later + // user will have try again later, non blocking ssl.SetError(YasslError(SSL_ERROR_WANT_READ)); } @@ -761,7 +806,8 @@ void sendClientHello(SSL& ssl) ssl.verifyState(serverNull); if (ssl.GetError()) return; - ClientHello ch(ssl.getSecurity().get_connection().version_); + ClientHello ch(ssl.getSecurity().get_connection().version_, + ssl.getSecurity().get_connection().compression_); RecordLayerHeader rlHeader; HandShakeHeader hsHeader; output_buffer out; @@ -859,6 +905,7 @@ void sendFinished(SSL& ssl, ConnectionEnd side, BufferOutput buffer) buildFinished(ssl, ssl.useHashes().use_verify(), client); // client } else { + if (!ssl.getSecurity().GetContext()->GetSessionCacheOff()) GetSessions().add(ssl); // store session if (side == client_end) buildFinished(ssl, ssl.useHashes().use_verify(), server); // server @@ -885,7 +932,20 @@ int sendData(SSL& ssl, const void* buffer, int sz) for (;;) { int len = min(sz - sent, MAX_RECORD_SIZE); output_buffer out; - const Data data(len, static_cast<const opaque*>(buffer) + sent); + input_buffer tmp; + + Data data; + + if (ssl.CompressionOn()) { + if (Compress(static_cast<const opaque*>(buffer) + sent, len, + tmp) == -1) { + ssl.SetError(compress_error); + return -1; + } + data.SetData(tmp.get_size(), tmp.get_buffer()); + } + else + data.SetData(len, static_cast<const opaque*>(buffer) + sent); buildMessage(ssl, out, data); ssl.Send(out.get_buffer(), out.get_size()); @@ -947,7 +1007,8 @@ void sendServerHello(SSL& ssl, BufferOutput buffer) ssl.verifyState(clientHelloComplete); if (ssl.GetError()) return; - ServerHello sh(ssl.getSecurity().get_connection().version_); + ServerHello sh(ssl.getSecurity().get_connection().version_, + ssl.getSecurity().get_connection().compression_); RecordLayerHeader rlHeader; HandShakeHeader hsHeader; mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer); diff --git a/extra/yassl/src/make.bat b/extra/yassl/src/make.bat index 148427a6f41..dde305721a7 100644 --- a/extra/yassl/src/make.bat +++ b/extra/yassl/src/make.bat @@ -1,7 +1,7 @@ REM quick and dirty build file for testing different MSDEVs setlocal -set myFLAGS= /I../include /I../mySTL /I../taocrypt/include /W3 /c /ZI +set myFLAGS= /I../include /I../taocrypt/mySTL /I../taocrypt/include /W3 /c /ZI cl %myFLAGS% buffer.cpp cl %myFLAGS% cert_wrapper.cpp diff --git a/extra/yassl/src/socket_wrapper.cpp b/extra/yassl/src/socket_wrapper.cpp index 70944831884..f281b81a24a 100644 --- a/extra/yassl/src/socket_wrapper.cpp +++ b/extra/yassl/src/socket_wrapper.cpp @@ -63,7 +63,7 @@ namespace yaSSL { Socket::Socket(socket_t s) - : socket_(s), wouldBlock_(false), blocking_(false) + : socket_(s), wouldBlock_(false), nonBlocking_(false) {} @@ -148,8 +148,8 @@ uint Socket::receive(byte* buf, unsigned int sz, int flags) if (recvd == -1) { if (get_lastError() == SOCKET_EWOULDBLOCK || get_lastError() == SOCKET_EAGAIN) { - wouldBlock_ = true; - blocking_ = true; // socket can block, only way to tell for win32 + wouldBlock_ = true; // would have blocked this time only + nonBlocking_ = true; // socket nonblocking, win32 only way to tell return 0; } } @@ -191,9 +191,9 @@ bool Socket::WouldBlock() const } -bool Socket::IsBlocking() const +bool Socket::IsNonBlocking() const { - return blocking_; + return nonBlocking_; } diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp index a008ea7228b..e0e27502f3d 100644 --- a/extra/yassl/src/ssl.cpp +++ b/extra/yassl/src/ssl.cpp @@ -184,10 +184,22 @@ SSL_METHOD* TLSv1_client_method() } +SSL_METHOD* TLSv1_1_server_method() +{ + return NEW_YS SSL_METHOD(server_end, ProtocolVersion(3,2)); +} + + +SSL_METHOD* TLSv1_1_client_method() +{ + return NEW_YS SSL_METHOD(client_end, ProtocolVersion(3,2)); +} + + SSL_METHOD* SSLv23_server_method() { // compatibility only, no version 2 support, but does SSL 3 and TLS 1 - return NEW_YS SSL_METHOD(server_end, ProtocolVersion(3,1), true); + return NEW_YS SSL_METHOD(server_end, ProtocolVersion(3,2), true); } @@ -196,7 +208,7 @@ SSL_METHOD* SSLv23_client_method() // compatibility only, no version 2 support, but does SSL 3 and TLS 1 // though it sends TLS1 hello not SSLv2 so SSLv3 only servers will decline // TODO: maybe add support to send SSLv2 hello ??? - return NEW_YS SSL_METHOD(client_end, ProtocolVersion(3,1), true); + return NEW_YS SSL_METHOD(client_end, ProtocolVersion(3,2), true); } @@ -407,7 +419,6 @@ int SSL_shutdown(SSL* ssl) Alert alert(warning, close_notify); sendAlert(*ssl, alert); ssl->useLog().ShowTCP(ssl->getSocket().get_fd(), true); - ssl->useSocket().closeSocket(); GetErrors().Remove(); @@ -415,8 +426,21 @@ int SSL_shutdown(SSL* ssl) } +/* on by default but allow user to turn off */ +long SSL_CTX_set_session_cache_mode(SSL_CTX* ctx, long mode) +{ + if (mode == SSL_SESS_CACHE_OFF) + ctx->SetSessionCacheOff(); + + return SSL_SUCCESS; +} + + SSL_SESSION* SSL_get_session(SSL* ssl) { + if (ssl->getSecurity().GetContext()->GetSessionCacheOff()) + return 0; + return GetSessions().lookup( ssl->getSecurity().get_connection().sessionID_); } @@ -424,6 +448,9 @@ SSL_SESSION* SSL_get_session(SSL* ssl) int SSL_set_session(SSL* ssl, SSL_SESSION* session) { + if (ssl->getSecurity().GetContext()->GetSessionCacheOff()) + return SSL_FAILURE; + ssl->set_session(session); return SSL_SUCCESS; } @@ -512,6 +539,19 @@ int SSL_get_error(SSL* ssl, int /*previous*/) } + +/* turn on yaSSL zlib compression + returns 0 for success, else error (not built in) + only need to turn on for client, becuase server on by default if built in + but calling for server will tell you whether it's available or not +*/ +int SSL_set_compression(SSL* ssl) +{ + return ssl->SetCompression(); +} + + + X509* SSL_get_peer_certificate(SSL* ssl) { return ssl->getCrypto().get_certManager().get_peerX509(); @@ -1359,6 +1399,56 @@ int SSL_pending(SSL* ssl) } +void SSL_CTX_set_default_passwd_cb(SSL_CTX* ctx, pem_password_cb cb) +{ + ctx->SetPasswordCb(cb); +} + + +int SSLeay_add_ssl_algorithms() // compatibility only +{ + return 1; +} + + +void ERR_remove_state(unsigned long) +{ + GetErrors().Remove(); +} + + +int ERR_GET_REASON(int l) +{ + return l & 0xfff; +} + + +unsigned long err_helper(bool peek = false) +{ + int ysError = GetErrors().Lookup(peek); + + // translate cert error for libcurl, it uses OpenSSL hex code + switch (ysError) { + case TaoCrypt::SIG_OTHER_E: + return CERTFICATE_ERROR; + break; + default : + return 0; + } +} + + +unsigned long ERR_peek_error() +{ + return err_helper(true); +} + + +unsigned long ERR_get_error() +{ + return err_helper(); +} + // functions for stunnel @@ -1477,13 +1567,6 @@ int SSL_pending(SSL* ssl) } - long SSL_CTX_set_session_cache_mode(SSL_CTX*, long) - { - // TDOD: - return SSL_SUCCESS; - } - - long SSL_CTX_set_timeout(SSL_CTX*, long) { // TDOD: @@ -1498,12 +1581,6 @@ int SSL_pending(SSL* ssl) } - void SSL_CTX_set_default_passwd_cb(SSL_CTX* ctx, pem_password_cb cb) - { - ctx->SetPasswordCb(cb); - } - - int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX*, const char*, int) { // TDOD: @@ -1555,49 +1632,6 @@ int SSL_pending(SSL* ssl) } - int SSLeay_add_ssl_algorithms() // compatibility only - { - return 1; - } - - - void ERR_remove_state(unsigned long) - { - GetErrors().Remove(); - } - - - int ERR_GET_REASON(int l) - { - return l & 0xfff; - } - - unsigned long err_helper(bool peek = false) - { - int ysError = GetErrors().Lookup(peek); - - // translate cert error for libcurl, it uses OpenSSL hex code - switch (ysError) { - case TaoCrypt::SIG_OTHER_E: - return CERTFICATE_ERROR; - break; - default : - return 0; - } - } - - - unsigned long ERR_peek_error() - { - return err_helper(true); - } - - - unsigned long ERR_get_error() - { - return err_helper(); - } - // end stunnel needs diff --git a/extra/yassl/src/yassl_error.cpp b/extra/yassl/src/yassl_error.cpp index 3531c0a2c74..25c595f40bc 100644 --- a/extra/yassl/src/yassl_error.cpp +++ b/extra/yassl/src/yassl_error.cpp @@ -133,6 +133,18 @@ void SetErrorString(YasslError error, char* buffer) strncpy(buffer, "protocl version mismatch", max); break; + case compress_error : + strncpy(buffer, "compression error", max); + break; + + case decompress_error : + strncpy(buffer, "decompression error", max); + break; + + case pms_version_error : + strncpy(buffer, "bad PreMasterSecret version error", max); + break; + // openssl errors case SSL_ERROR_WANT_READ : strncpy(buffer, "the read operation would block", max); diff --git a/extra/yassl/src/yassl_imp.cpp b/extra/yassl/src/yassl_imp.cpp index bd07f8b70f2..bf10c4b8932 100644 --- a/extra/yassl/src/yassl_imp.cpp +++ b/extra/yassl/src/yassl_imp.cpp @@ -87,7 +87,7 @@ void EncryptedPreMasterSecret::build(SSL& ssl) opaque tmp[SECRET_LEN]; memset(tmp, 0, sizeof(tmp)); ssl.getCrypto().get_random().Fill(tmp, SECRET_LEN); - ProtocolVersion pv = ssl.getSecurity().get_connection().version_; + ProtocolVersion pv = ssl.getSecurity().get_connection().chVersion_; tmp[0] = pv.major_; tmp[1] = pv.minor_; ssl.set_preMaster(tmp, SECRET_LEN); @@ -233,6 +233,10 @@ void EncryptedPreMasterSecret::read(SSL& ssl, input_buffer& input) rsa.decrypt(preMasterSecret, secret_, length_, ssl.getCrypto().get_random()); + ProtocolVersion pv = ssl.getSecurity().get_connection().chVersion_; + if (pv.major_ != preMasterSecret[0] || pv.minor_ != preMasterSecret[1]) + ssl.SetError(pms_version_error); // continue deriving for timing attack + ssl.set_preMaster(preMasterSecret, SECRET_LEN); ssl.makeMasterSecret(); } @@ -437,6 +441,7 @@ Parameters::Parameters(ConnectionEnd ce, const Ciphers& ciphers, ProtocolVersion pv, bool haveDH) : entity_(ce) { pending_ = true; // suite not set yet + strncpy(cipher_name_, "NONE", 5); if (ciphers.setSuites_) { // use user set list suites_size_ = ciphers.suiteSz_; @@ -445,6 +450,7 @@ Parameters::Parameters(ConnectionEnd ce, const Ciphers& ciphers, } else SetSuites(pv, ce == server_end && !haveDH); // defaults + } @@ -613,14 +619,18 @@ output_buffer& operator<<(output_buffer& output, const HandShakeHeader& hdr) void HandShakeHeader::Process(input_buffer& input, SSL& ssl) { ssl.verifyState(*this); + if (ssl.GetError()) return; const HandShakeFactory& hsf = ssl.getFactory().getHandShake(); mySTL::auto_ptr<HandShakeBase> hs(hsf.CreateObject(type_)); if (!hs.get()) { ssl.SetError(factory_error); return; } - hashHandShake(ssl, input, c24to32(length_)); + uint len = c24to32(length_); + hashHandShake(ssl, input, len); + + hs->set_length(len); input >> *hs; hs->Process(input, ssl); } @@ -849,11 +859,17 @@ void Alert::Process(input_buffer& input, SSL& ssl) opaque mac[SHA_LEN]; input.read(mac, digestSz); + if (ssl.getSecurity().get_parms().cipher_type_ == block) { + int ivExtra = 0; opaque fill; - int padSz = ssl.getSecurity().get_parms().encrypt_size_ - aSz - - digestSz; + + if (ssl.isTLSv1_1()) + ivExtra = ssl.getCrypto().get_cipher().get_blockSize(); + int padSz = ssl.getSecurity().get_parms().encrypt_size_ - ivExtra - + aSz - digestSz; for (int i = 0; i < padSz; i++) fill = input[AUTO]; + } // verify if (memcmp(mac, verify, digestSz)) { @@ -879,9 +895,13 @@ Data::Data(uint16 len, opaque* b) {} -Data::Data(uint16 len, const opaque* w) - : length_(len), buffer_(0), write_buffer_(w) -{} +void Data::SetData(uint16 len, const opaque* buffer) +{ + assert(write_buffer_ == 0); + + length_ = len; + write_buffer_ = buffer; +} input_buffer& Data::set(input_buffer& in) { @@ -907,17 +927,12 @@ uint16 Data::get_length() const } -const opaque* Data::get_buffer() const -{ - return write_buffer_; -} - - void Data::set_length(uint16 l) { length_ = l; } + opaque* Data::set_buffer() { return buffer_; @@ -937,27 +952,42 @@ void Data::Process(input_buffer& input, SSL& ssl) { int msgSz = ssl.getSecurity().get_parms().encrypt_size_; int pad = 0, padByte = 0; + int ivExtra = 0; + if (ssl.getSecurity().get_parms().cipher_type_ == block) { - pad = *(input.get_buffer() + input.get_current() + msgSz - 1); + if (ssl.isTLSv1_1()) // IV + ivExtra = ssl.getCrypto().get_cipher().get_blockSize(); + pad = *(input.get_buffer() + input.get_current() + msgSz -ivExtra - 1); padByte = 1; } int digestSz = ssl.getCrypto().get_digest().get_digestSize(); - int dataSz = msgSz - digestSz - pad - padByte; + int dataSz = msgSz - ivExtra - digestSz - pad - padByte; opaque verify[SHA_LEN]; + const byte* rawData = input.get_buffer() + input.get_current(); + // read data - if (dataSz) { + if (dataSz) { // could be compressed + if (ssl.CompressionOn()) { + input_buffer tmp; + if (DeCompress(input, dataSz, tmp) == -1) { + ssl.SetError(decompress_error); + return; + } + ssl.addData(NEW_YS input_buffer(tmp.get_size(), + tmp.get_buffer(), tmp.get_size())); + } + else { input_buffer* data; ssl.addData(data = NEW_YS input_buffer(dataSz)); input.read(data->get_buffer(), dataSz); data->add_size(dataSz); + } if (ssl.isTLS()) - TLS_hmac(ssl, verify, data->get_buffer(), dataSz, application_data, - true); + TLS_hmac(ssl, verify, rawData, dataSz, application_data, true); else - hmac(ssl, verify, data->get_buffer(), dataSz, application_data, - true); + hmac(ssl, verify, rawData, dataSz, application_data, true); } // read mac and fill @@ -1220,6 +1250,13 @@ void ServerHello::Process(input_buffer&, SSL& ssl) if (ssl.isTLS() && server_version_.minor_ < 1) // downgrade to SSLv3 ssl.useSecurity().use_connection().TurnOffTLS(); + else if (ssl.isTLSv1_1() && server_version_.minor_ == 1) + // downdrage to TLSv1 + ssl.useSecurity().use_connection().TurnOffTLS1_1(); + } + else if (ssl.isTLSv1_1() && server_version_.minor_ < 2) { + ssl.SetError(badVersion_error); + return; } else if (ssl.isTLS() && server_version_.minor_ < 1) { ssl.SetError(badVersion_error); @@ -1252,6 +1289,10 @@ void ServerHello::Process(input_buffer&, SSL& ssl) ssl.useSecurity().set_resuming(false); ssl.useLog().Trace("server denied resumption"); } + + if (ssl.CompressionOn() && !compression_method_) + ssl.UnSetCompression(); // server isn't supporting yaSSL zlib request + ssl.useStates().useClient() = serverHelloComplete; } @@ -1263,8 +1304,9 @@ ServerHello::ServerHello() } -ServerHello::ServerHello(ProtocolVersion pv) - : server_version_(pv) +ServerHello::ServerHello(ProtocolVersion pv, bool useCompression) + : server_version_(pv), + compression_method_(useCompression ? zlib : no_compression) { memset(random_, 0, RAN_LEN); memset(session_id_, 0, ID_LEN); @@ -1341,6 +1383,8 @@ opaque* ClientKeyBase::get_clientKey() const // input operator for Client Hello input_buffer& operator>>(input_buffer& input, ClientHello& hello) { + uint begin = input.get_current(); // could have extensions at end + // Protocol hello.client_version_.major_ = input[AUTO]; hello.client_version_.minor_ = input[AUTO]; @@ -1361,8 +1405,19 @@ input_buffer& operator>>(input_buffer& input, ClientHello& hello) // Compression hello.comp_len_ = input[AUTO]; - while (hello.comp_len_--) // ignore for now - hello.compression_methods_ = CompressionMethod(input[AUTO]); + hello.compression_methods_ = no_compression; + while (hello.comp_len_--) { + CompressionMethod cm = CompressionMethod(input[AUTO]); + if (cm == zlib) + hello.compression_methods_ = zlib; + } + + uint read = input.get_current() - begin; + uint expected = hello.get_length(); + + // ignore client hello extensions for now + if (read < expected) + input.set_current(input.get_current() + expected - read); return input; } @@ -1400,6 +1455,13 @@ output_buffer& operator<<(output_buffer& output, const ClientHello& hello) // Client Hello processing handler void ClientHello::Process(input_buffer&, SSL& ssl) { + // store version for pre master secret + ssl.useSecurity().use_connection().chVersion_ = client_version_; + + if (client_version_.major_ != 3) { + ssl.SetError(badVersion_error); + return; + } if (ssl.GetMultiProtocol()) { // SSLv23 support if (ssl.isTLS() && client_version_.minor_ < 1) { // downgrade to SSLv3 @@ -1407,20 +1469,29 @@ void ClientHello::Process(input_buffer&, SSL& ssl) ProtocolVersion pv = ssl.getSecurity().get_connection().version_; ssl.useSecurity().use_parms().SetSuites(pv); // reset w/ SSL suites } + else if (ssl.isTLSv1_1() && client_version_.minor_ == 1) + // downgrade to TLSv1, but use same suites + ssl.useSecurity().use_connection().TurnOffTLS1_1(); + } + else if (ssl.isTLSv1_1() && client_version_.minor_ < 2) { + ssl.SetError(badVersion_error); + return; } else if (ssl.isTLS() && client_version_.minor_ < 1) { ssl.SetError(badVersion_error); return; } - else if (!ssl.isTLS() && (client_version_.major_ == 3 && - client_version_.minor_ >= 1)) { + else if (!ssl.isTLS() && client_version_.minor_ >= 1) { ssl.SetError(badVersion_error); return; } + ssl.set_random(random_, client_end); while (id_len_) { // trying to resume - SSL_SESSION* session = GetSessions().lookup(session_id_); + SSL_SESSION* session = 0; + if (!ssl.getSecurity().GetContext()->GetSessionCacheOff()) + session = GetSessions().lookup(session_id_); if (!session) { ssl.useLog().Trace("session lookup failed"); break; @@ -1444,6 +1515,9 @@ void ClientHello::Process(input_buffer&, SSL& ssl) ssl.matchSuite(cipher_suites_, suite_len_); ssl.set_pending(ssl.getSecurity().get_parms().suite_[1]); + if (compression_methods_ == zlib) + ssl.SetCompression(); + ssl.useStates().useServer() = clientHelloComplete; } @@ -1478,8 +1552,9 @@ ClientHello::ClientHello() } -ClientHello::ClientHello(ProtocolVersion pv) - : client_version_(pv) +ClientHello::ClientHello(ProtocolVersion pv, bool useCompression) + : client_version_(pv), + compression_methods_(useCompression ? zlib : no_compression) { memset(random_, 0, RAN_LEN); } @@ -1943,8 +2018,13 @@ void Finished::Process(input_buffer& input, SSL& ssl) int digestSz = ssl.getCrypto().get_digest().get_digestSize(); input.read(mac, digestSz); + uint ivExtra = 0; + if (ssl.getSecurity().get_parms().cipher_type_ == block) + if (ssl.isTLSv1_1()) + ivExtra = ssl.getCrypto().get_cipher().get_blockSize(); + opaque fill; - int padSz = ssl.getSecurity().get_parms().encrypt_size_ - + int padSz = ssl.getSecurity().get_parms().encrypt_size_ - ivExtra - HANDSHAKE_HEADER - finishedSz - digestSz; for (int i = 0; i < padSz; i++) fill = input[AUTO]; @@ -2018,7 +2098,9 @@ void clean(volatile opaque* p, uint sz, RandomPool& ran) Connection::Connection(ProtocolVersion v, RandomPool& ran) : pre_master_secret_(0), sequence_number_(0), peer_sequence_number_(0), pre_secret_len_(0), send_server_key_(false), master_clean_(false), - TLS_(v.major_ >= 3 && v.minor_ >= 1), version_(v), random_(ran) + TLS_(v.major_ >= 3 && v.minor_ >= 1), + TLSv1_1_(v.major_ >= 3 && v.minor_ >= 2), compression_(false), + version_(v), random_(ran) { memset(sessionID_, 0, sizeof(sessionID_)); } @@ -2043,6 +2125,13 @@ void Connection::TurnOffTLS() } +void Connection::TurnOffTLS1_1() +{ + TLSv1_1_ = false; + version_.minor_ = 1; +} + + // wipeout master secret void Connection::CleanMaster() { diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp index 5288acb2bcd..1a407ca8ba5 100644 --- a/extra/yassl/src/yassl_int.cpp +++ b/extra/yassl/src/yassl_int.cpp @@ -38,6 +38,11 @@ #endif +#ifdef HAVE_LIBZ + #include "zlib.h" +#endif + + #ifdef YASSL_PURE_C void* operator new(size_t sz, yaSSL::new_t) @@ -727,6 +732,32 @@ void SSL::set_preMaster(const opaque* pre, uint sz) } +// set yaSSL zlib type compression +int SSL::SetCompression() +{ +#ifdef HAVE_LIBZ + secure_.use_connection().compression_ = true; + return 0; +#else + return -1; // not built in +#endif +} + + +// unset yaSSL zlib type compression +void SSL::UnSetCompression() +{ + secure_.use_connection().compression_ = false; +} + + +// is yaSSL zlib compression on +bool SSL::CompressionOn() const +{ + return secure_.get_connection().compression_; +} + + // store master secret void SSL::set_masterSecret(const opaque* sec) { @@ -1109,6 +1140,11 @@ void SSL::verifyState(const RecordLayerHeader& rlHeader) { if (GetError()) return; + if (rlHeader.version_.major_ != 3 || rlHeader.version_.minor_ > 2) { + SetError(badVersion_error); + return; + } + if (states_.getRecord() == recordNotReady || (rlHeader.type_ == application_data && // data and handshake states_.getHandShake() != handShakeReady) ) // isn't complete yet @@ -1247,6 +1283,9 @@ void SSL::matchSuite(const opaque* peer, uint length) void SSL::set_session(SSL_SESSION* s) { + if (getSecurity().GetContext()->GetSessionCacheOff()) + return; + if (s && GetSessions().lookup(s->GetID(), &secure_.use_resume())) { secure_.set_resuming(true); crypto_.use_certManager().setPeerX509(s->GetPeerX509()); @@ -1344,6 +1383,12 @@ bool SSL::isTLS() const } +bool SSL::isTLSv1_1() const +{ + return secure_.get_connection().TLSv1_1_; +} + + void SSL::addData(input_buffer* data) { buffers_.useData().push_back(data); @@ -1703,7 +1748,7 @@ bool SSL_METHOD::multipleProtocol() const SSL_CTX::SSL_CTX(SSL_METHOD* meth) : method_(meth), certificate_(0), privateKey_(0), passwordCb_(0), - userData_(0) + userData_(0), sessionCacheOff_(false) {} @@ -1784,12 +1829,24 @@ void* SSL_CTX::GetUserData() const } +bool SSL_CTX::GetSessionCacheOff() const +{ + return sessionCacheOff_; +} + + void SSL_CTX::SetUserData(void* data) { userData_ = data; } +void SSL_CTX::SetSessionCacheOff() +{ + sessionCacheOff_ = true; +} + + void SSL_CTX::setVerifyPeer() { method_->setVerifyPeer(); @@ -2312,9 +2369,110 @@ ASN1_STRING* StringHolder::GetString() } +#ifdef HAVE_LIBZ + + void* myAlloc(void* /* opaque */, unsigned int item, unsigned int size) + { + return NEW_YS unsigned char[item * size]; + } + + + void myFree(void* /* opaque */, void* memory) + { + unsigned char* ptr = static_cast<unsigned char*>(memory); + yaSSL::ysArrayDelete(ptr); + } + + + // put size in front of compressed data + int Compress(const byte* in, int sz, input_buffer& buffer) + { + byte tmp[LENGTH_SZ]; + z_stream c_stream; /* compression stream */ + + buffer.allocate(sz + sizeof(uint16) + COMPRESS_EXTRA); + + c_stream.zalloc = myAlloc; + c_stream.zfree = myFree; + c_stream.opaque = (voidpf)0; + + c_stream.next_in = const_cast<byte*>(in); + c_stream.avail_in = sz; + c_stream.next_out = buffer.get_buffer() + sizeof(tmp); + c_stream.avail_out = buffer.get_capacity() - sizeof(tmp); + + if (deflateInit(&c_stream, 8) != Z_OK) return -1; + int err = deflate(&c_stream, Z_FINISH); + deflateEnd(&c_stream); + if (err != Z_OK && err != Z_STREAM_END) return -1; + + c16toa(sz, tmp); + memcpy(buffer.get_buffer(), tmp, sizeof(tmp)); + buffer.add_size(c_stream.total_out + sizeof(tmp)); + + return 0; + } + + + // get uncompressed size in front + int DeCompress(input_buffer& in, int sz, input_buffer& out) + { + byte tmp[LENGTH_SZ]; + + in.read(tmp, sizeof(tmp)); + + uint16 len; + ato16(tmp, len); + + out.allocate(len); + + z_stream d_stream; /* decompression stream */ + + d_stream.zalloc = myAlloc; + d_stream.zfree = myFree; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = in.get_buffer() + in.get_current(); + d_stream.avail_in = sz - sizeof(tmp); + d_stream.next_out = out.get_buffer(); + d_stream.avail_out = out.get_capacity(); + + if (inflateInit(&d_stream) != Z_OK) return -1; + int err = inflate(&d_stream, Z_FINISH); + inflateEnd(&d_stream); + if (err != Z_OK && err != Z_STREAM_END) return -1; + + out.add_size(d_stream.total_out); + in.set_current(in.get_current() + sz - sizeof(tmp)); + + return 0; + } + + +#else // LIBZ + + // these versions should never get called + int Compress(const byte* in, int sz, input_buffer& buffer) + { + assert(0); + return -1; + } + + + int DeCompress(input_buffer& in, int sz, input_buffer& out) + { + assert(0); + return -1; + } + + +#endif // LIBZ + + } // namespace + extern "C" void yaSSL_CleanUp() { TaoCrypt::CleanUp(); diff --git a/extra/yassl/taocrypt/benchmark/make.bat b/extra/yassl/taocrypt/benchmark/make.bat index 4ebe4b32417..bf1383f5e97 100644 --- a/extra/yassl/taocrypt/benchmark/make.bat +++ b/extra/yassl/taocrypt/benchmark/make.bat @@ -1,7 +1,7 @@ REM quick and dirty build file for testing different MSDEVs setlocal -set myFLAGS= /I../include /I../../mySTL /c /W3 /G6 /O2 +set myFLAGS= /I../include /I../mySTL /c /W3 /G6 /O2 cl %myFLAGS% benchmark.cpp diff --git a/extra/yassl/taocrypt/include/aes.hpp b/extra/yassl/taocrypt/include/aes.hpp index cb70f5c0e7e..5c53fc39411 100644 --- a/extra/yassl/taocrypt/include/aes.hpp +++ b/extra/yassl/taocrypt/include/aes.hpp @@ -34,6 +34,12 @@ #include "modes.hpp" +#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) + #define DO_AES_ASM +#endif + + + namespace TaoCrypt { @@ -46,15 +52,14 @@ public: enum { BLOCK_SIZE = AES_BLOCK_SIZE }; AES(CipherDir DIR, Mode MODE) - : Mode_BASE(BLOCK_SIZE), dir_(DIR), mode_(MODE) {} + : Mode_BASE(BLOCK_SIZE, DIR, MODE) {} +#ifdef DO_AES_ASM void Process(byte*, const byte*, word32); +#endif void SetKey(const byte* key, word32 sz, CipherDir fake = ENCRYPTION); void SetIV(const byte* iv) { memcpy(r_, iv, BLOCK_SIZE); } private: - CipherDir dir_; - Mode mode_; - static const word32 rcon_[]; word32 rounds_; diff --git a/extra/yassl/taocrypt/include/algebra.hpp b/extra/yassl/taocrypt/include/algebra.hpp index 07fc405f093..9cfbcf06ece 100644 --- a/extra/yassl/taocrypt/include/algebra.hpp +++ b/extra/yassl/taocrypt/include/algebra.hpp @@ -75,7 +75,8 @@ public: typedef Integer Element; AbstractRing() : AbstractGroup() {m_mg.m_pRing = this;} - AbstractRing(const AbstractRing &source) {m_mg.m_pRing = this;} + AbstractRing(const AbstractRing &source) : AbstractGroup() + {m_mg.m_pRing = this;} AbstractRing& operator=(const AbstractRing &source) {return *this;} virtual bool IsUnit(const Element &a) const =0; diff --git a/extra/yassl/taocrypt/include/arc4.hpp b/extra/yassl/taocrypt/include/arc4.hpp index 05b0921f5a1..ddd5082f557 100644 --- a/extra/yassl/taocrypt/include/arc4.hpp +++ b/extra/yassl/taocrypt/include/arc4.hpp @@ -46,7 +46,6 @@ public: ARC4() {} void Process(byte*, const byte*, word32); - void AsmProcess(byte*, const byte*, word32); void SetKey(const byte*, word32); private: byte x_; @@ -55,6 +54,8 @@ private: ARC4(const ARC4&); // hide copy const ARC4 operator=(const ARC4&); // and assign + + void AsmProcess(byte*, const byte*, word32); }; } // namespace diff --git a/extra/yassl/taocrypt/include/asn.hpp b/extra/yassl/taocrypt/include/asn.hpp index dbee54be6f1..1151f3c944e 100644 --- a/extra/yassl/taocrypt/include/asn.hpp +++ b/extra/yassl/taocrypt/include/asn.hpp @@ -34,7 +34,11 @@ #include "misc.hpp" #include "block.hpp" #include "error.hpp" -#include STL_LIST_FILE +#ifdef USE_SYS_STL + #include <list> +#else + #include "list.hpp" +#endif namespace STL = STL_NAMESPACE; diff --git a/extra/yassl/taocrypt/include/block.hpp b/extra/yassl/taocrypt/include/block.hpp index a931158a83d..0cf27d0b6b5 100644 --- a/extra/yassl/taocrypt/include/block.hpp +++ b/extra/yassl/taocrypt/include/block.hpp @@ -34,7 +34,12 @@ #include "misc.hpp" #include <string.h> // memcpy #include <stddef.h> // ptrdiff_t -#include STL_ALGORITHM_FILE + +#ifdef USE_SYS_STL + #include <algorithm> +#else + #include "algorithm.hpp" +#endif namespace STL = STL_NAMESPACE; diff --git a/extra/yassl/taocrypt/include/blowfish.hpp b/extra/yassl/taocrypt/include/blowfish.hpp index 40953624232..4d6ad1b034b 100644 --- a/extra/yassl/taocrypt/include/blowfish.hpp +++ b/extra/yassl/taocrypt/include/blowfish.hpp @@ -32,12 +32,21 @@ #include "misc.hpp" #include "modes.hpp" -#include STL_ALGORITHM_FILE +#ifdef USE_SYS_STL + #include <algorithm> +#else + #include "algorithm.hpp" +#endif namespace STL = STL_NAMESPACE; +#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) + #define DO_BLOWFISH_ASM +#endif + + namespace TaoCrypt { enum { BLOWFISH_BLOCK_SIZE = 8 }; @@ -49,15 +58,14 @@ public: enum { BLOCK_SIZE = BLOWFISH_BLOCK_SIZE, ROUNDS = 16 }; Blowfish(CipherDir DIR, Mode MODE) - : Mode_BASE(BLOCK_SIZE), dir_(DIR), mode_(MODE) {} + : Mode_BASE(BLOCK_SIZE, DIR, MODE) {} +#ifdef DO_BLOWFISH_ASM void Process(byte*, const byte*, word32); +#endif void SetKey(const byte* key, word32 sz, CipherDir fake = ENCRYPTION); void SetIV(const byte* iv) { memcpy(r_, iv, BLOCK_SIZE); } private: - CipherDir dir_; - Mode mode_; - static const word32 p_init_[ROUNDS + 2]; static const word32 s_init_[4 * 256]; diff --git a/extra/yassl/taocrypt/include/des.hpp b/extra/yassl/taocrypt/include/des.hpp index 48bb1e9119d..19273821f98 100644 --- a/extra/yassl/taocrypt/include/des.hpp +++ b/extra/yassl/taocrypt/include/des.hpp @@ -34,6 +34,12 @@ #include "misc.hpp" #include "modes.hpp" + +#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) + #define DO_DES_ASM +#endif + + namespace TaoCrypt { @@ -53,13 +59,9 @@ protected: class DES : public Mode_BASE, public BasicDES { public: DES(CipherDir DIR, Mode MODE) - : Mode_BASE(DES_BLOCK_SIZE), dir_(DIR), mode_(MODE) {} + : Mode_BASE(DES_BLOCK_SIZE, DIR, MODE) {} - void Process(byte*, const byte*, word32); private: - CipherDir dir_; - Mode mode_; - void ProcessAndXorBlock(const byte*, const byte*, byte*) const; DES(const DES&); // hide copy @@ -71,14 +73,10 @@ private: class DES_EDE2 : public Mode_BASE { public: DES_EDE2(CipherDir DIR, Mode MODE) - : Mode_BASE(DES_BLOCK_SIZE), dir_(DIR), mode_(MODE) {} + : Mode_BASE(DES_BLOCK_SIZE, DIR, MODE) {} void SetKey(const byte*, word32, CipherDir dir); - void Process(byte*, const byte*, word32); private: - CipherDir dir_; - Mode mode_; - BasicDES des1_; BasicDES des2_; @@ -94,15 +92,14 @@ private: class DES_EDE3 : public Mode_BASE { public: DES_EDE3(CipherDir DIR, Mode MODE) - : Mode_BASE(DES_BLOCK_SIZE), dir_(DIR), mode_(MODE) {} + : Mode_BASE(DES_BLOCK_SIZE, DIR, MODE) {} void SetKey(const byte*, word32, CipherDir dir); void SetIV(const byte* iv) { memcpy(r_, iv, DES_BLOCK_SIZE); } +#ifdef DO_DES_ASM void Process(byte*, const byte*, word32); +#endif private: - CipherDir dir_; - Mode mode_; - BasicDES des1_; BasicDES des2_; BasicDES des3_; diff --git a/extra/yassl/taocrypt/include/integer.hpp b/extra/yassl/taocrypt/include/integer.hpp index 70b4dc79e73..751c79102c4 100644 --- a/extra/yassl/taocrypt/include/integer.hpp +++ b/extra/yassl/taocrypt/include/integer.hpp @@ -45,7 +45,11 @@ #include "random.hpp" #include "file.hpp" #include <string.h> -#include STL_ALGORITHM_FILE +#ifdef USE_SYS_STL + #include <algorithm> +#else + #include "algorithm.hpp" +#endif #ifdef TAOCRYPT_X86ASM_AVAILABLE @@ -67,7 +71,8 @@ #endif // SSE2 intrinsics work in GCC 3.3 or later -#if defined(__SSE2__) && (__GNUC_MAJOR__ > 3 || __GNUC_MINOR__ > 2) +#if defined(__SSE2__) && (__GNUC__ == 4 || __GNUC_MAJOR__ > 3 || \ + __GNUC_MINOR__ > 2) #define SSE2_INTRINSICS_AVAILABLE #endif @@ -106,7 +111,6 @@ namespace TaoCrypt { #endif }; - template class TAOCRYPT_DLL AlignedAllocator<word>; typedef Block<word, AlignedAllocator<word> > AlignedWordBlock; #else typedef WordBlock AlignedWordBlock; diff --git a/extra/yassl/taocrypt/include/md5.hpp b/extra/yassl/taocrypt/include/md5.hpp index 30d14d54fbf..f607a922155 100644 --- a/extra/yassl/taocrypt/include/md5.hpp +++ b/extra/yassl/taocrypt/include/md5.hpp @@ -31,6 +31,11 @@ #include "hash.hpp" + +#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) + #define DO_MD5_ASM +#endif + namespace TaoCrypt { @@ -49,7 +54,9 @@ public: MD5(const MD5&); MD5& operator= (const MD5&); +#ifdef DO_MD5_ASM void Update(const byte*, word32); +#endif void Init(); void Swap(MD5&); diff --git a/extra/yassl/taocrypt/include/misc.hpp b/extra/yassl/taocrypt/include/misc.hpp index 3d2d4c62466..cc20b60d528 100644 --- a/extra/yassl/taocrypt/include/misc.hpp +++ b/extra/yassl/taocrypt/include/misc.hpp @@ -151,6 +151,17 @@ void CleanUp(); #endif +#ifdef TAOCRYPT_X86ASM_AVAILABLE + bool HaveCpuId(); + bool IsPentium(); + void CpuId(word32 input, word32 *output); + + extern bool isMMX; +#endif + + + + // Turn on ia32 ASM for Ciphers and Message Digests // Seperate define since these are more complex, use member offsets // and user may want to turn off while leaving Big Integer optos on @@ -200,17 +211,9 @@ void CleanUp(); #ifdef USE_SYS_STL // use system STL - #define STL_VECTOR_FILE <vector> - #define STL_LIST_FILE <list> - #define STL_ALGORITHM_FILE <algorithm> - #define STL_MEMORY_FILE <memory> #define STL_NAMESPACE std #else // use mySTL - #define STL_VECTOR_FILE "vector.hpp" - #define STL_LIST_FILE "list.hpp" - #define STL_ALGORITHM_FILE "algorithm.hpp" - #define STL_MEMORY_FILE "memory.hpp" #define STL_NAMESPACE mySTL #endif diff --git a/extra/yassl/taocrypt/include/modes.hpp b/extra/yassl/taocrypt/include/modes.hpp index 65b7318661e..d77f855385c 100644 --- a/extra/yassl/taocrypt/include/modes.hpp +++ b/extra/yassl/taocrypt/include/modes.hpp @@ -38,6 +38,7 @@ namespace TaoCrypt { enum Mode { ECB, CBC }; + // BlockCipher abstraction template<CipherDir DIR, class T, Mode MODE> class BlockCipher { @@ -63,14 +64,16 @@ class Mode_BASE : public virtual_base { public: enum { MaxBlockSz = 16 }; - explicit Mode_BASE(int sz) + explicit Mode_BASE(int sz, CipherDir dir, Mode mode) : blockSz_(sz), reg_(reinterpret_cast<byte*>(r_)), - tmp_(reinterpret_cast<byte*>(t_)) + tmp_(reinterpret_cast<byte*>(t_)), dir_(dir), mode_(mode) { assert(sz <= MaxBlockSz); } virtual ~Mode_BASE() {} + virtual void Process(byte*, const byte*, word32); + void SetIV(const byte* iv) { memcpy(reg_, iv, blockSz_); } protected: int blockSz_; @@ -80,6 +83,9 @@ protected: word32 r_[MaxBlockSz / sizeof(word32)]; // align reg_ on word32 word32 t_[MaxBlockSz / sizeof(word32)]; // align tmp_ on word32 + CipherDir dir_; + Mode mode_; + void ECB_Process(byte*, const byte*, word32); void CBC_Encrypt(byte*, const byte*, word32); void CBC_Decrypt(byte*, const byte*, word32); @@ -92,6 +98,18 @@ private: }; +inline void Mode_BASE::Process(byte* out, const byte* in, word32 sz) +{ + if (mode_ == ECB) + ECB_Process(out, in, sz); + else if (mode_ == CBC) + if (dir_ == ENCRYPTION) + CBC_Encrypt(out, in, sz); + else + CBC_Decrypt(out, in, sz); +} + + // ECB Process blocks inline void Mode_BASE::ECB_Process(byte* out, const byte* in, word32 sz) { diff --git a/extra/yassl/taocrypt/include/ripemd.hpp b/extra/yassl/taocrypt/include/ripemd.hpp index 2e594b7604d..5d443769662 100644 --- a/extra/yassl/taocrypt/include/ripemd.hpp +++ b/extra/yassl/taocrypt/include/ripemd.hpp @@ -31,6 +31,11 @@ #include "hash.hpp" + +#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) + #define DO_RIPEMD_ASM +#endif + namespace TaoCrypt { @@ -49,7 +54,9 @@ public: RIPEMD160(const RIPEMD160&); RIPEMD160& operator= (const RIPEMD160&); +#ifdef DO_RIPEMD_ASM void Update(const byte*, word32); +#endif void Init(); void Swap(RIPEMD160&); private: diff --git a/extra/yassl/taocrypt/include/rsa.hpp b/extra/yassl/taocrypt/include/rsa.hpp index 1b531b9d0c0..c33e21b76a3 100644 --- a/extra/yassl/taocrypt/include/rsa.hpp +++ b/extra/yassl/taocrypt/include/rsa.hpp @@ -239,7 +239,8 @@ bool RSA_Encryptor<Pad>::SSL_Verify(const byte* message, word32 sz, const byte* sig) { ByteBlock plain(PK_Lengths(key_.GetModulus()).FixedMaxPlaintextLength()); - SSL_Decrypt(key_, sig, plain.get_buffer()); + if (SSL_Decrypt(key_, sig, plain.get_buffer()) != sz) + return false; // not right justified or bad padding if ( (memcmp(plain.get_buffer(), message, sz)) == 0) return true; diff --git a/extra/yassl/taocrypt/include/sha.hpp b/extra/yassl/taocrypt/include/sha.hpp index 2d65932dc17..510c516b1a4 100644 --- a/extra/yassl/taocrypt/include/sha.hpp +++ b/extra/yassl/taocrypt/include/sha.hpp @@ -31,6 +31,11 @@ #include "hash.hpp" + +#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) + #define DO_SHA_ASM +#endif + namespace TaoCrypt { @@ -46,7 +51,9 @@ public: word32 getDigestSize() const { return DIGEST_SIZE; } word32 getPadSize() const { return PAD_SIZE; } +#ifdef DO_SHA_ASM void Update(const byte* data, word32 len); +#endif void Init(); SHA(const SHA&); diff --git a/extra/yassl/taocrypt/include/twofish.hpp b/extra/yassl/taocrypt/include/twofish.hpp index ba144d2defb..8cad4923262 100644 --- a/extra/yassl/taocrypt/include/twofish.hpp +++ b/extra/yassl/taocrypt/include/twofish.hpp @@ -32,12 +32,20 @@ #include "misc.hpp" #include "modes.hpp" -#include STL_ALGORITHM_FILE +#ifdef USE_SYS_STL + #include <algorithm> +#else + #include "algorithm.hpp" +#endif namespace STL = STL_NAMESPACE; +#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) + #define DO_TWOFISH_ASM +#endif + namespace TaoCrypt { enum { TWOFISH_BLOCK_SIZE = 16 }; @@ -49,15 +57,14 @@ public: enum { BLOCK_SIZE = TWOFISH_BLOCK_SIZE }; Twofish(CipherDir DIR, Mode MODE) - : Mode_BASE(BLOCK_SIZE), dir_(DIR), mode_(MODE) {} + : Mode_BASE(BLOCK_SIZE, DIR, MODE) {} +#ifdef DO_TWOFISH_ASM void Process(byte*, const byte*, word32); +#endif void SetKey(const byte* key, word32 sz, CipherDir fake = ENCRYPTION); void SetIV(const byte* iv) { memcpy(r_, iv, BLOCK_SIZE); } private: - CipherDir dir_; - Mode mode_; - static const byte q_[2][256]; static const word32 mds_[4][256]; diff --git a/extra/yassl/taocrypt/src/aes.cpp b/extra/yassl/taocrypt/src/aes.cpp index 574a88a736c..2940f06c074 100644 --- a/extra/yassl/taocrypt/src/aes.cpp +++ b/extra/yassl/taocrypt/src/aes.cpp @@ -34,33 +34,19 @@ #include "aes.hpp" -#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) - #define DO_AES_ASM -#endif - - namespace TaoCrypt { -#if !defined(DO_AES_ASM) - -// Generic Version -void AES::Process(byte* out, const byte* in, word32 sz) -{ - if (mode_ == ECB) - ECB_Process(out, in, sz); - else if (mode_ == CBC) - if (dir_ == ENCRYPTION) - CBC_Encrypt(out, in, sz); - else - CBC_Decrypt(out, in, sz); -} - -#else +#if defined(DO_AES_ASM) // ia32 optimized version void AES::Process(byte* out, const byte* in, word32 sz) { + if (!isMMX) { + Mode_BASE::Process(out, in, sz); + return; + } + word32 blocks = sz / BLOCK_SIZE; if (mode_ == ECB) diff --git a/extra/yassl/taocrypt/src/algebra.cpp b/extra/yassl/taocrypt/src/algebra.cpp index 375cd6cd524..76c4e99323d 100644 --- a/extra/yassl/taocrypt/src/algebra.cpp +++ b/extra/yassl/taocrypt/src/algebra.cpp @@ -29,7 +29,11 @@ #include "runtime.hpp" #include "algebra.hpp" -#include STL_VECTOR_FILE +#ifdef USE_SYS_STL + #include <vector> +#else + #include "vector.hpp" +#endif namespace STL = STL_NAMESPACE; diff --git a/extra/yassl/taocrypt/src/arc4.cpp b/extra/yassl/taocrypt/src/arc4.cpp index ea1e084014c..90b5170c59e 100644 --- a/extra/yassl/taocrypt/src/arc4.cpp +++ b/extra/yassl/taocrypt/src/arc4.cpp @@ -80,12 +80,18 @@ inline unsigned int MakeByte(word32& x, word32& y, byte* s) } // namespace -#ifndef DO_ARC4_ASM void ARC4::Process(byte* out, const byte* in, word32 length) { if (length == 0) return; +#ifdef DO_ARC4_ASM + if (isMMX) { + AsmProcess(out, in, length); + return; + } +#endif + byte *const s = state_; word32 x = x_; word32 y = y_; @@ -100,13 +106,16 @@ void ARC4::Process(byte* out, const byte* in, word32 length) y_ = y; } -#else // DO_ARC4_ASM +#ifdef DO_ARC4_ASM + #ifdef _MSC_VER __declspec(naked) +#else + __attribute__ ((noinline)) #endif -void ARC4::Process(byte* out, const byte* in, word32 length) +void ARC4::AsmProcess(byte* out, const byte* in, word32 length) { #ifdef __GNUC__ #define AS1(x) asm(#x); diff --git a/extra/yassl/taocrypt/src/blowfish.cpp b/extra/yassl/taocrypt/src/blowfish.cpp index 40ae1a17e6c..d736292fb19 100644 --- a/extra/yassl/taocrypt/src/blowfish.cpp +++ b/extra/yassl/taocrypt/src/blowfish.cpp @@ -37,34 +37,21 @@ -#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) - #define DO_BLOWFISH_ASM -#endif - namespace TaoCrypt { -#if !defined(DO_BLOWFISH_ASM) - -// Generic Version -void Blowfish::Process(byte* out, const byte* in, word32 sz) -{ - if (mode_ == ECB) - ECB_Process(out, in, sz); - else if (mode_ == CBC) - if (dir_ == ENCRYPTION) - CBC_Encrypt(out, in, sz); - else - CBC_Decrypt(out, in, sz); -} - -#else +#if defined(DO_BLOWFISH_ASM) // ia32 optimized version void Blowfish::Process(byte* out, const byte* in, word32 sz) { + if (!isMMX) { + Mode_BASE::Process(out, in, sz); + return; + } + word32 blocks = sz / BLOCK_SIZE; if (mode_ == ECB) diff --git a/extra/yassl/taocrypt/src/des.cpp b/extra/yassl/taocrypt/src/des.cpp index 2628e142bae..94428ac587e 100644 --- a/extra/yassl/taocrypt/src/des.cpp +++ b/extra/yassl/taocrypt/src/des.cpp @@ -34,16 +34,16 @@ #include "runtime.hpp" #include "des.hpp" -#include STL_ALGORITHM_FILE +#ifdef USE_SYS_STL + #include <algorithm> +#else + #include "algorithm.hpp" +#endif namespace STL = STL_NAMESPACE; -#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) - #define DO_DES_ASM -#endif - namespace TaoCrypt { @@ -357,18 +357,6 @@ void BasicDES::RawProcessBlock(word32& lIn, word32& rIn) const } -void DES::Process(byte* out, const byte* in, word32 sz) -{ - if (mode_ == ECB) - ECB_Process(out, in, sz); - else if (mode_ == CBC) - if (dir_ == ENCRYPTION) - CBC_Encrypt(out, in, sz); - else - CBC_Decrypt(out, in, sz); -} - - typedef BlockGetAndPut<word32, BigEndian> Block; @@ -386,17 +374,6 @@ void DES::ProcessAndXorBlock(const byte* in, const byte* xOr, byte* out) const } -void DES_EDE2::Process(byte* out, const byte* in, word32 sz) -{ - if (mode_ == ECB) - ECB_Process(out, in, sz); - else if (mode_ == CBC) - if (dir_ == ENCRYPTION) - CBC_Encrypt(out, in, sz); - else - CBC_Decrypt(out, in, sz); -} - void DES_EDE2::SetKey(const byte* key, word32 sz, CipherDir dir) { des1_.SetKey(key, sz, dir); @@ -429,25 +406,16 @@ void DES_EDE3::SetKey(const byte* key, word32 sz, CipherDir dir) -#if !defined(DO_DES_ASM) - -// Generic Version -void DES_EDE3::Process(byte* out, const byte* in, word32 sz) -{ - if (mode_ == ECB) - ECB_Process(out, in, sz); - else if (mode_ == CBC) - if (dir_ == ENCRYPTION) - CBC_Encrypt(out, in, sz); - else - CBC_Decrypt(out, in, sz); -} - -#else +#if defined(DO_DES_ASM) // ia32 optimized version void DES_EDE3::Process(byte* out, const byte* in, word32 sz) { + if (!isMMX) { + Mode_BASE::Process(out, in, sz); + return; + } + word32 blocks = sz / DES_BLOCK_SIZE; if (mode_ == CBC) diff --git a/extra/yassl/taocrypt/src/integer.cpp b/extra/yassl/taocrypt/src/integer.cpp index 500160cfe37..1ed69ce34dc 100644 --- a/extra/yassl/taocrypt/src/integer.cpp +++ b/extra/yassl/taocrypt/src/integer.cpp @@ -55,12 +55,15 @@ extern "C" word myUMULH(word, word); #pragma intrinsic (myUMULH) #endif +#ifdef __GNUC__ + #include <signal.h> + #include <setjmp.h> +#endif + #ifdef SSE2_INTRINSICS_AVAILABLE #ifdef __GNUC__ #include <xmmintrin.h> - #include <signal.h> - #include <setjmp.h> #ifdef TAOCRYPT_MEMALIGN_AVAILABLE #include <malloc.h> #else @@ -1015,44 +1018,20 @@ void Portable::Multiply8Bottom(word *R, const word *A, const word *B) // ************** x86 feature detection *************** -static bool s_sse2Enabled = true; - -static void CpuId(word32 input, word32 *output) -{ -#ifdef __GNUC__ - __asm__ - ( - // save ebx in case -fPIC is being used - "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx" - : "=a" (output[0]), "=D" (output[1]), "=c" (output[2]), "=d"(output[3]) - : "a" (input) - ); -#else - __asm - { - mov eax, input - cpuid - mov edi, output - mov [edi], eax - mov [edi+4], ebx - mov [edi+8], ecx - mov [edi+12], edx - } -#endif -} #ifdef SSE2_INTRINSICS_AVAILABLE + #ifndef _MSC_VER -static jmp_buf s_env; -static void SigIllHandler(int) -{ + static jmp_buf s_env; + static void SigIllHandler(int) + { longjmp(s_env, 1); -} + } #endif static bool HasSSE2() { - if (!s_sse2Enabled) + if (!IsPentium()) return false; word32 cpuid[4]; @@ -1081,23 +1060,22 @@ static bool HasSSE2() if (setjmp(s_env)) result = false; else - __asm __volatile ("xorps %xmm0, %xmm0"); + __asm __volatile ("xorpd %xmm0, %xmm0"); signal(SIGILL, oldHandler); return result; #endif } -#endif +#endif // SSE2_INTRINSICS_AVAILABLE + static bool IsP4() { - word32 cpuid[4]; - - CpuId(0, cpuid); - STL::swap(cpuid[2], cpuid[3]); - if (memcmp(cpuid+1, "GenuineIntel", 12) != 0) + if (!IsPentium()) return false; + word32 cpuid[4]; + CpuId(1, cpuid); return ((cpuid[0] >> 8) & 0xf) == 0xf; } @@ -1147,7 +1125,12 @@ static PMul s_pMul4, s_pMul8, s_pMul8B; static void SetPentiumFunctionPointers() { - if (IsP4()) + if (!IsPentium()) + { + s_pAdd = &Portable::Add; + s_pSub = &Portable::Subtract; + } + else if (IsP4()) { s_pAdd = &P4Optimized::Add; s_pSub = &P4Optimized::Subtract; @@ -1159,7 +1142,13 @@ static void SetPentiumFunctionPointers() } #ifdef SSE2_INTRINSICS_AVAILABLE - if (HasSSE2()) + if (!IsPentium()) + { + s_pMul4 = &Portable::Multiply4; + s_pMul8 = &Portable::Multiply8; + s_pMul8B = &Portable::Multiply8Bottom; + } + else if (HasSSE2()) { s_pMul4 = &P4Optimized::Multiply4; s_pMul8 = &P4Optimized::Multiply8; @@ -1177,11 +1166,6 @@ static void SetPentiumFunctionPointers() static const char s_RunAtStartupSetPentiumFunctionPointers = (SetPentiumFunctionPointers(), 0); -void DisableSSE2() -{ - s_sse2Enabled = false; - SetPentiumFunctionPointers(); -} class LowLevel : public PentiumOptimized { @@ -3984,6 +3968,9 @@ Integer CRT(const Integer &xp, const Integer &p, const Integer &xq, template hword DivideThreeWordsByTwo<hword, Word>(hword*, hword, hword, Word*); #endif template word DivideThreeWordsByTwo<word, DWord>(word*, word, word, DWord*); +#ifdef SSE2_INTRINSICS_AVAILABLE +template class AlignedAllocator<word>; +#endif #endif diff --git a/extra/yassl/taocrypt/src/make.bat b/extra/yassl/taocrypt/src/make.bat index ecf7e8f8469..0aa1350f7d8 100644 --- a/extra/yassl/taocrypt/src/make.bat +++ b/extra/yassl/taocrypt/src/make.bat @@ -1,7 +1,7 @@ REM quick and dirty build file for testing different MSDEVs setlocal -set myFLAGS= /I../include /I../../mySTL /c /W3 /G6 /O2 +set myFLAGS= /I../include /I../mySTL /c /W3 /G6 /O2 cl %myFLAGS% aes.cpp cl %myFLAGS% aestables.cpp @@ -21,6 +21,7 @@ cl %myFLAGS% file.cpp cl %myFLAGS% hash.cpp cl %myFLAGS% integer.cpp cl %myFLAGS% md2.cpp +cl %myFLAGS% md4.cpp cl %myFLAGS% md5.cpp cl %myFLAGS% misc.cpp @@ -33,5 +34,5 @@ cl %myFLAGS% template_instnt.cpp cl %myFLAGS% tftables.cpp cl %myFLAGS% twofish.cpp -link.exe -lib /out:taocrypt.lib aes.obj aestables.obj algebra.obj arc4.obj asn.obj bftables.obj blowfish.obj coding.obj des.obj dh.obj dsa.obj file.obj hash.obj integer.obj md2.obj md5.obj misc.obj random.obj ripemd.obj rsa.obj sha.obj template_instnt.obj tftables.obj twofish.obj +link.exe -lib /out:taocrypt.lib aes.obj aestables.obj algebra.obj arc4.obj asn.obj bftables.obj blowfish.obj coding.obj des.obj dh.obj dsa.obj file.obj hash.obj integer.obj md2.obj md4.obj md5.obj misc.obj random.obj ripemd.obj rsa.obj sha.obj template_instnt.obj tftables.obj twofish.obj diff --git a/extra/yassl/taocrypt/src/md4.cpp b/extra/yassl/taocrypt/src/md4.cpp index 0dee8bf40cb..1efda04fbb8 100644 --- a/extra/yassl/taocrypt/src/md4.cpp +++ b/extra/yassl/taocrypt/src/md4.cpp @@ -28,7 +28,11 @@ #include "runtime.hpp" #include "md4.hpp" -#include STL_ALGORITHM_FILE +#ifdef USE_SYS_STL + #include <algorithm> +#else + #include "algorithm.hpp" +#endif namespace STL = STL_NAMESPACE; diff --git a/extra/yassl/taocrypt/src/md5.cpp b/extra/yassl/taocrypt/src/md5.cpp index 2bddc7fe308..bf485d11b95 100644 --- a/extra/yassl/taocrypt/src/md5.cpp +++ b/extra/yassl/taocrypt/src/md5.cpp @@ -28,15 +28,16 @@ #include "runtime.hpp" #include "md5.hpp" -#include STL_ALGORITHM_FILE +#ifdef USE_SYS_STL + #include <algorithm> +#else + #include "algorithm.hpp" +#endif namespace STL = STL_NAMESPACE; -#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) - #define DO_MD5_ASM -#endif namespace TaoCrypt { @@ -84,10 +85,17 @@ void MD5::Swap(MD5& other) } -// Update digest with data of size len, do in blocks +#ifdef DO_MD5_ASM + +// Update digest with data of size len void MD5::Update(const byte* data, word32 len) { - byte* local = (byte*)buffer_; + if (!isMMX) { + HASHwithTransform::Update(data, len); + return; + } + + byte* local = reinterpret_cast<byte*>(buffer_); // remove buffered data if possible if (buffLen_) { @@ -99,27 +107,14 @@ void MD5::Update(const byte* data, word32 len) len -= add; if (buffLen_ == BLOCK_SIZE) { - ByteReverseIf(local, local, BLOCK_SIZE, LittleEndianOrder); Transform(); AddLength(BLOCK_SIZE); buffLen_ = 0; } } - // do block size transforms or all at once for asm + // at once for asm if (buffLen_ == 0) { - #ifndef DO_MD5_ASM - while (len >= BLOCK_SIZE) { - memcpy(&local[0], data, BLOCK_SIZE); - - data += BLOCK_SIZE; - len -= BLOCK_SIZE; - - ByteReverseIf(local, local, BLOCK_SIZE, LittleEndianOrder); - Transform(); - AddLength(BLOCK_SIZE); - } - #else word32 times = len / BLOCK_SIZE; if (times) { AsmTransform(data, times); @@ -128,7 +123,6 @@ void MD5::Update(const byte* data, word32 len) len -= add; data += add; } - #endif } // cache any data left @@ -139,7 +133,6 @@ void MD5::Update(const byte* data, word32 len) } -#ifdef DO_MD5_ASM /* diff --git a/extra/yassl/taocrypt/src/misc.cpp b/extra/yassl/taocrypt/src/misc.cpp index 084a263a4ae..7ab05582e95 100644 --- a/extra/yassl/taocrypt/src/misc.cpp +++ b/extra/yassl/taocrypt/src/misc.cpp @@ -30,6 +30,20 @@ #include "misc.hpp" +#ifdef __GNUC__ + #include <signal.h> + #include <setjmp.h> +#endif + +#ifdef USE_SYS_STL + #include <algorithm> +#else + #include "algorithm.hpp" +#endif + +namespace STL = STL_NAMESPACE; + + #ifdef YASSL_PURE_C void* operator new(size_t sz, TaoCrypt::new_t) @@ -156,5 +170,129 @@ unsigned long Crop(unsigned long value, unsigned int size) } + +#ifdef TAOCRYPT_X86ASM_AVAILABLE + +#ifndef _MSC_VER + static jmp_buf s_env; + static void SigIllHandler(int) + { + longjmp(s_env, 1); + } +#endif + + +bool HaveCpuId() +{ +#ifdef _MSC_VER + __try + { + __asm + { + mov eax, 0 + cpuid + } + } + __except (1) + { + return false; + } + return true; +#else + typedef void (*SigHandler)(int); + + SigHandler oldHandler = signal(SIGILL, SigIllHandler); + if (oldHandler == SIG_ERR) + return false; + + bool result = true; + if (setjmp(s_env)) + result = false; + else + __asm__ __volatile + ( + // save ebx in case -fPIC is being used + "push %%ebx; mov $0, %%eax; cpuid; pop %%ebx" + : + : + : "%eax", "%ecx", "%edx" + ); + + signal(SIGILL, oldHandler); + return result; +#endif +} + + +void CpuId(word32 input, word32 *output) +{ +#ifdef __GNUC__ + __asm__ + ( + // save ebx in case -fPIC is being used + "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx" + : "=a" (output[0]), "=D" (output[1]), "=c" (output[2]), "=d"(output[3]) + : "a" (input) + ); +#else + __asm + { + mov eax, input + cpuid + mov edi, output + mov [edi], eax + mov [edi+4], ebx + mov [edi+8], ecx + mov [edi+12], edx + } +#endif +} + + +bool IsPentium() +{ + if (!HaveCpuId()) + return false; + + word32 cpuid[4]; + + CpuId(0, cpuid); + STL::swap(cpuid[2], cpuid[3]); + if (memcmp(cpuid+1, "GenuineIntel", 12) != 0) + return false; + + CpuId(1, cpuid); + byte family = ((cpuid[0] >> 8) & 0xf); + if (family < 5) + return false; + + return true; +} + + + +static bool IsMmx() +{ + if (!IsPentium()) + return false; + + word32 cpuid[4]; + + CpuId(1, cpuid); + if ((cpuid[3] & (1 << 23)) == 0) + return false; + + return true; +} + + +bool isMMX = IsMmx(); + + +#endif // TAOCRYPT_X86ASM_AVAILABLE + + + + } // namespace diff --git a/extra/yassl/taocrypt/src/random.cpp b/extra/yassl/taocrypt/src/random.cpp index c7bb6ae9549..3fab1ddba23 100644 --- a/extra/yassl/taocrypt/src/random.cpp +++ b/extra/yassl/taocrypt/src/random.cpp @@ -50,8 +50,11 @@ namespace TaoCrypt { RandomNumberGenerator::RandomNumberGenerator() { byte key[32]; + byte junk[256]; + seed_.GenerateSeed(key, sizeof(key)); cipher_.SetKey(key, sizeof(key)); + GenerateBlock(junk, sizeof(junk)); // rid initial state } diff --git a/extra/yassl/taocrypt/src/ripemd.cpp b/extra/yassl/taocrypt/src/ripemd.cpp index 03c09edde84..98bfe4b2645 100644 --- a/extra/yassl/taocrypt/src/ripemd.cpp +++ b/extra/yassl/taocrypt/src/ripemd.cpp @@ -28,15 +28,16 @@ #include "runtime.hpp" #include "ripemd.hpp" -#include STL_ALGORITHM_FILE +#ifdef USE_SYS_STL + #include <algorithm> +#else + #include "algorithm.hpp" +#endif namespace STL = STL_NAMESPACE; -#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) - #define DO_RIPEMD_ASM -#endif namespace TaoCrypt { @@ -86,10 +87,17 @@ void RIPEMD160::Swap(RIPEMD160& other) } -// Update digest with data of size len, do in blocks +#ifdef DO_RIPEMD_ASM + +// Update digest with data of size len void RIPEMD160::Update(const byte* data, word32 len) { - byte* local = (byte*)buffer_; + if (!isMMX) { + HASHwithTransform::Update(data, len); + return; + } + + byte* local = reinterpret_cast<byte*>(buffer_); // remove buffered data if possible if (buffLen_) { @@ -101,27 +109,14 @@ void RIPEMD160::Update(const byte* data, word32 len) len -= add; if (buffLen_ == BLOCK_SIZE) { - ByteReverseIf(local, local, BLOCK_SIZE, LittleEndianOrder); Transform(); AddLength(BLOCK_SIZE); buffLen_ = 0; } } - // do block size transforms or all at once for asm + // all at once for asm if (buffLen_ == 0) { - #ifndef DO_RIPEMD_ASM - while (len >= BLOCK_SIZE) { - memcpy(&local[0], data, BLOCK_SIZE); - - data += BLOCK_SIZE; - len -= BLOCK_SIZE; - - ByteReverseIf(local, local, BLOCK_SIZE, LittleEndianOrder); - Transform(); - AddLength(BLOCK_SIZE); - } - #else word32 times = len / BLOCK_SIZE; if (times) { AsmTransform(data, times); @@ -130,7 +125,6 @@ void RIPEMD160::Update(const byte* data, word32 len) len -= add; data += add; } - #endif } // cache any data left @@ -140,6 +134,8 @@ void RIPEMD160::Update(const byte* data, word32 len) } } +#endif // DO_RIPEMD_ASM + // for all #define F(x, y, z) (x ^ y ^ z) diff --git a/extra/yassl/taocrypt/src/sha.cpp b/extra/yassl/taocrypt/src/sha.cpp index 280d42fb3d4..b1273d9da8f 100644 --- a/extra/yassl/taocrypt/src/sha.cpp +++ b/extra/yassl/taocrypt/src/sha.cpp @@ -28,16 +28,16 @@ #include "runtime.hpp" #include <string.h> #include "sha.hpp" -#include STL_ALGORITHM_FILE +#ifdef USE_SYS_STL + #include <algorithm> +#else + #include "algorithm.hpp" +#endif namespace STL = STL_NAMESPACE; -#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) - #define DO_SHA_ASM -#endif - namespace TaoCrypt { @@ -108,10 +108,18 @@ void SHA::Swap(SHA& other) } -// Update digest with data of size len, do in blocks + +#ifdef DO_SHA_ASM + +// Update digest with data of size len void SHA::Update(const byte* data, word32 len) { - byte* local = (byte*)buffer_; + if (!isMMX) { + HASHwithTransform::Update(data, len); + return; + } + + byte* local = reinterpret_cast<byte*>(buffer_); // remove buffered data if possible if (buffLen_) { @@ -123,27 +131,15 @@ void SHA::Update(const byte* data, word32 len) len -= add; if (buffLen_ == BLOCK_SIZE) { - ByteReverseIf(local, local, BLOCK_SIZE, BigEndianOrder); + ByteReverse(local, local, BLOCK_SIZE); Transform(); AddLength(BLOCK_SIZE); buffLen_ = 0; } } - // do block size transforms or all at once for asm + // all at once for asm if (buffLen_ == 0) { - #ifndef DO_SHA_ASM - while (len >= BLOCK_SIZE) { - memcpy(&local[0], data, BLOCK_SIZE); - - data += BLOCK_SIZE; - len -= BLOCK_SIZE; - - ByteReverseIf(local, local, BLOCK_SIZE, BigEndianOrder); - Transform(); - AddLength(BLOCK_SIZE); - } - #else word32 times = len / BLOCK_SIZE; if (times) { AsmTransform(data, times); @@ -152,7 +148,6 @@ void SHA::Update(const byte* data, word32 len) len -= add; data += add; } - #endif } // cache any data left @@ -162,6 +157,8 @@ void SHA::Update(const byte* data, word32 len) } } +#endif // DO_SHA_ASM + void SHA::Transform() { diff --git a/extra/yassl/taocrypt/src/twofish.cpp b/extra/yassl/taocrypt/src/twofish.cpp index a16a8f0d169..bb385331519 100644 --- a/extra/yassl/taocrypt/src/twofish.cpp +++ b/extra/yassl/taocrypt/src/twofish.cpp @@ -35,33 +35,20 @@ #include "twofish.hpp" -#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) - #define DO_TWOFISH_ASM -#endif - namespace TaoCrypt { -#if !defined(DO_TWOFISH_ASM) - -// Generic Version -void Twofish::Process(byte* out, const byte* in, word32 sz) -{ - if (mode_ == ECB) - ECB_Process(out, in, sz); - else if (mode_ == CBC) - if (dir_ == ENCRYPTION) - CBC_Encrypt(out, in, sz); - else - CBC_Decrypt(out, in, sz); -} - -#else +#if defined(DO_TWOFISH_ASM) // ia32 optimized version void Twofish::Process(byte* out, const byte* in, word32 sz) { + if (!isMMX) { + Mode_BASE::Process(out, in, sz); + return; + } + word32 blocks = sz / BLOCK_SIZE; if (mode_ == ECB) diff --git a/extra/yassl/taocrypt/test/make.bat b/extra/yassl/taocrypt/test/make.bat index 5f01db68d0d..7b53e9abc90 100644 --- a/extra/yassl/taocrypt/test/make.bat +++ b/extra/yassl/taocrypt/test/make.bat @@ -1,7 +1,7 @@ REM quick and dirty build file for testing different MSDEVs setlocal -set myFLAGS= /I../include /I../../mySTL /c /W3 /G6 /O2 +set myFLAGS= /I../include /I../mySTL /c /W3 /G6 /O2 cl %myFLAGS% test.cpp diff --git a/extra/yassl/taocrypt/test/test.cpp b/extra/yassl/taocrypt/test/test.cpp index 28ef73dfac8..9e3ef709a78 100644 --- a/extra/yassl/taocrypt/test/test.cpp +++ b/extra/yassl/taocrypt/test/test.cpp @@ -247,6 +247,8 @@ void taocrypt_test(void* args) args.argv = argv; taocrypt_test(&args); + TaoCrypt::CleanUp(); + return args.return_code; } diff --git a/extra/yassl/testsuite/make.bat b/extra/yassl/testsuite/make.bat index 1bc7ce0513d..ea2677db481 100644 --- a/extra/yassl/testsuite/make.bat +++ b/extra/yassl/testsuite/make.bat @@ -1,7 +1,7 @@ REM quick and dirty build file for testing different MSDEVs setlocal -set myFLAGS= /I../include /I../taocrypt/include /I../mySTL /c /W3 /G6 /O2 /MT /D"WIN32" /D"NO_MAIN_DRIVER" +set myFLAGS= /I../include /I../taocrypt/include /I../taocrypt/mySTL /c /W3 /G6 /O2 /MT /D"WIN32" /D"NO_MAIN_DRIVER" cl %myFLAGS% testsuite.cpp cl %myFLAGS% ../examples/client/client.cpp diff --git a/extra/yassl/testsuite/test.hpp b/extra/yassl/testsuite/test.hpp index b23b36f0ba2..b2fed37f4e5 100644 --- a/extra/yassl/testsuite/test.hpp +++ b/extra/yassl/testsuite/test.hpp @@ -9,6 +9,8 @@ #include <stdlib.h> #include <assert.h> +//#define NON_BLOCKING // test server and client example (not echos) + #ifdef _WIN32 #include <winsock2.h> #include <process.h> @@ -23,16 +25,17 @@ #include <sys/types.h> #include <sys/socket.h> #include <pthread.h> +#ifdef NON_BLOCKING + #include <fcntl.h> +#endif #define SOCKET_T int #endif /* _WIN32 */ -#if !defined(_SOCKLEN_T) && defined(_WIN32) +#if !defined(_SOCKLEN_T) && \ + (defined(_WIN32) || defined(__NETWARE__) || defined(__APPLE__)) typedef int socklen_t; #endif -#if !defined(_SOCKLEN_T) && defined(__NETWARE__) - typedef size_t socklen_t; -#endif // Check type of third arg to accept @@ -262,6 +265,20 @@ inline void set_args(int& argc, char**& argv, func_args& args) } +inline void tcp_set_nonblocking(SOCKET_T& sockfd) +{ +#ifdef NON_BLOCKING + #ifdef _WIN32 + unsigned long blocking = 1; + int ret = ioctlsocket(sockfd, FIONBIO, &blocking); + #else + int flags = fcntl(sockfd, F_GETFL, 0); + int ret = fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); + #endif +#endif +} + + inline void tcp_socket(SOCKET_T& sockfd, sockaddr_in& addr) { sockfd = socket(AF_INET, SOCK_STREAM, 0); @@ -289,8 +306,7 @@ inline void tcp_connect(SOCKET_T& sockfd) sockaddr_in addr; tcp_socket(sockfd, addr); - if (connect(sockfd, (const sockaddr*)&addr, sizeof(addr)) != 0) - { + if (connect(sockfd, (const sockaddr*)&addr, sizeof(addr)) != 0) { tcp_close(sockfd); err_sys("tcp connect failed"); } @@ -302,19 +318,18 @@ inline void tcp_listen(SOCKET_T& sockfd) sockaddr_in addr; tcp_socket(sockfd, addr); - if (bind(sockfd, (const sockaddr*)&addr, sizeof(addr)) != 0) - { + if (bind(sockfd, (const sockaddr*)&addr, sizeof(addr)) != 0) { tcp_close(sockfd); err_sys("tcp bind failed"); } - if (listen(sockfd, 3) != 0) - { + if (listen(sockfd, 3) != 0) { tcp_close(sockfd); err_sys("tcp listen failed"); } } + inline void tcp_accept(SOCKET_T& sockfd, SOCKET_T& clientfd, func_args& args) { tcp_listen(sockfd); @@ -333,11 +348,14 @@ inline void tcp_accept(SOCKET_T& sockfd, SOCKET_T& clientfd, func_args& args) clientfd = accept(sockfd, (sockaddr*)&client, (ACCEPT_THIRD_T)&client_len); - if (clientfd == -1) - { + if (clientfd == -1) { tcp_close(sockfd); err_sys("tcp accept failed"); } + +#ifdef NON_BLOCKING + tcp_set_nonblocking(clientfd); +#endif } @@ -363,25 +381,30 @@ inline void showPeer(SSL* ssl) inline DH* set_tmpDH(SSL_CTX* ctx) { - static unsigned char dh512_p[] = + static unsigned char dh1024_p[] = { - 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75, - 0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F, - 0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3, - 0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12, - 0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C, - 0x47,0x74,0xE8,0x33, + 0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3, + 0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E, + 0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59, + 0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2, + 0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD, + 0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF, + 0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02, + 0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C, + 0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7, + 0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50, + 0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B, }; - static unsigned char dh512_g[] = + static unsigned char dh1024_g[] = { 0x02, }; DH* dh; if ( (dh = DH_new()) ) { - dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), 0); - dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), 0); + dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), 0); + dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), 0); } if (!dh->p || !dh->g) { DH_free(dh); |