> From: owner-openssl-us...@openssl.org On Behalf Of Hanxi Zhang > Sent: Tuesday, 15 January, 2013 15:33
> Hi forum, I would appreciate comments on if what I am trying > to do is feasible. > > Problem: I am using recent version of openssl to encrypt > large amount of data being transferred between client/server. > I have used the BIO interface to abstract the transport, such > that different protocols (TCP, UDP...) can be used > transparently to SSL. UDP can lose or reorder datagrams. SSL/TLS depends critically on TCP providing lossless inorder data. You can add sequencing, acknowledgement, and retries to UDP, but basically you have to re-implement TCP, so you might as well use TCP. There is a variant of TLS called DTLS (Datagram Transport Level Security) redesigned to work over UDP, and implemented by OpenSSL. Maybe you want that. (Assuming you control both ends.) > That worked fine but I found the transfer speed after the > encryption is about 5 times slower than no connection, when > using TCP on the 10 Gbps network. I assume you mean slower than no encryption and/or no SSL/TLS. Did you separate those? Try using SSL/TLS protocol without encryption, by selecting an "eNULL" ciphersuite such as NULL-SHA. (But this still does HMAC, which has some cost.) *If* encryption is the bottleneck, and you need encryption, changing transport won't help. Try measuring different algorithms, and possibly different compile options: OpenSSL has assembler for some algorithms on some targets but not all, and it can be included or not at build time. I believe (some of?) the x86 assembler auto-selects at runtime for CPU features like SSE2. Even for C, depending on your target and compiler there might be better optimizer options than the ones built-in to OpenSSL's Configure. You can measure just encrypt/decrypt (and hashes of the type used for HMAC) without any comms with commandline 'openssl speed'. Measure both your sender and receiver machines if nonidentical. > The underlying Linux OS is tuned such that TCP send buffer is > set to 4M bytes. > Framesize(s) probably matter as much as send buffer, but if you are getting good throughput for raw TCP through the same network stack that's presumably sorted. Once the handshake is completed SSL/TLS is basically streaming in both directions. > In order to improve the transfer throughput, I implemented an > "application data accumulator", i.e., in the writer/sender > callback function of BIO object, > Instead of sending out an SSL encrypted data chunk (about > 16k) right away, I accumulate them in a buffer, and only send > out the content in the buffer > when the buffer is about full or no SSL_write() has been > called for a while, for the last bit of data. > Your TCP stack is allowed to, and should already, combine send calls into TCP segments if that helps. Lookup "Nagle algorithm". > I found that when sending accumulated data for the first > time, the receiving side SSL complains "Bad record mac" and > resets the TCP connection. > Without in-depth knowledge about SSL/TLS, I wonder if what I > am trying to do will break some SSL data integrity check, and > is possible at all. > It shouldn't if you did it right. Regular SSL/TLS (not DTLS) is designed for TCP which isn't required to, and often doesn't, preserve "send" boundaries, so SSL/TLS has its own boundaries. As long as you deliver the same stream of bytes that was sent it should work. But as above using UDP might screw it up badly. Try limiting your buffer so you combine more than one record but only a few (say 32K or 48K). Do you still get an error? On the first bufferfull or a fixed one or a random one? Try writing a test driver that sends known data through your accumulating-BIO and check it comes out right. Include chunks of mostly about-16K but smaller ones now and then. ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager majord...@openssl.org