wolfSSL Manual

Chapter 3: Getting Started



3.1 General Description



wolfSSL, formerly CyaSSL, is about 10 times smaller than yaSSL and up to 20 times smaller than OpenSSL when using the compile options described in Chapter 2. User benchmarking and feedback also reports dramatically better performance from wolfSSL vs. OpenSSL in the vast majority of standard SSL operations.


For instructions on the build process please see Chapter 2.



3.2 Testsuite



The testsuite program is designed to test the ability of wolfSSL and its cryptography library, wolfCrypt, to run on the system.  


wolfSSL needs all examples and tests to be run from the wolfSSL home directory.  This is because it finds certs and keys from ./certs.  To run testsuite, execute:


./testsuite/testsuite.test


or


make test    (when using autoconf)


On *nix or Windows the examples and testsuite will check to see if the current directory is the source directory and if so, attempt to change to the wolfSSL home directory.  This should work in most setup cases, if not, just use the first method above and specify the full path.


On a successful run you should see output like this, with additional output for unit tests and cipher suite tests:


MD5      test passed!

MD4      test passed!

SHA      test passed!

SHA-256  test passed!

HMAC-MD5 test passed!

HMAC-SHA test passed!

HMAC-SHA256 test passed!

ARC4     test passed!

DES      test passed!

DES3     test passed!

AES      test passed!

RANDOM   test passed!

RSA      test passed!

DH       test passed!

DSA      test passed!

PWDBASED test passed!

OPENSSL  test passed!

peer's cert info:

issuer : /C=US/ST=Oregon/L=Portland/O=wolfSSL/OU=Programming/CN=[email protected]

subject: /C=US/ST=Oregon/L=Portland/O=wolfSSL/OU=Programming/CN=[email protected]

serial number:87:4a:75:be:91:66:d8:3d

SSL version is TLSv1.2

SSL cipher suite is TLS_DHE_RSA_WITH_AES_256_CBC_SHA256

peer's cert info:

issuer : /C=US/ST=Montana/L=Bozeman/O=Sawtooth/OU=Consulting/CN=[email protected]

subject: /C=US/ST=Montana/L=Bozeman/O=wolfSSL/OU=Support/CN=[email protected]

serial number:02

SSL version is TLSv1.2

SSL cipher suite is TLS_DHE_RSA_WITH_AES_256_CBC_SHA256

Client message: hello wolfssl!

Server response: I hear you fa shizzle!

sending server shutdown command: quit!

client sent quit command: shutting down!

6cd8940c5e7229f9357cc15b202b593befbbc8ea  input

6cd8940c5e7229f9357cc15b202b593befbbc8ea  output


All tests passed!


This indicates that everything is configured and built correctly. If any of the tests fail, make sure the build system was set up correctly. Likely culprits include having the wrong endianness or not properly setting the 64-bit type. If you've set anything to the non-default settings try removing those, rebuilding wolfSSL, and then re-testing.



3.3 Client Example



You can use the client example found in examples/client to test wolfSSL against any SSL server. To see a list of available command line runtime options, run the client with the “--help” argument:


./examples/client/client --help

client 3.4.6 NOTE: All files relative to wolfSSL home dir

-?          Help, print this usage

-h <host>   Host to connect to, default 127.0.0.1

-p <num>    Port to connect on, not 0, default 11111

-v <num>    SSL version [0-3], SSLv3(0) - TLS1.2(3)), default 3

-l <str>    Cipher list

-c <file>   Certificate file,           default ./certs/client-cert.pem

-k <file>   Key file,                   default ./certs/client-key.pem

-A <file>   Certificate Authority file, default ./certs/ca-cert.pem

-b <num>    Benchmark <num> connections and print stats

-s          Use pre Shared keys

-t          Track wolfSSL memory use

-d          Disable peer checks

-D          Override Date Errors example

-g          Send server HTTP GET

-u          Use UDP DTLS, add -v 2 for DTLSv1 (default), -v 3 for DTLSv1.2

-m          Match domain name in cert

-N          Use Non-blocking sockets

-r          Resume session

-w          Wait for bidirectional shutdown

-f          Fewer packets/group messages

-x          Disable client cert/key loading


To test against secure gmail try the following.  This is using wolfSSL compiled with the --enable-opensslextra build option:


./examples/client/client -h gmail.google.com -p 443 -d -g

peer's cert info:

issuer : /C=US/O=Google Inc/CN=Google Internet Authority

subject: /C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.google.com

altname = *.googleapis.cn

altname = *.gstatic.com

altname = g.co

altname = goo.gl

altname = *.cloud.google.com

altname = google-analytics.com

altname = *.google-analytics.com

altname = urchin.com

altname = *.urchin.com

altname = *.url.google.com

altname = googlecommerce.com

altname = *.googlecommerce.com

altname = android.com

altname = *.android.com

altname = *.google.com.tr

altname = *.google.com.vn

altname = *.google.com.co

altname = *.google.com.ar

altname = *.google.com.mx

altname = *.google.hu

altname = *.google.co.jp

altname = *.google.com.au

altname = *.google.nl

altname = *.google.pl

altname = *.google.cl

altname = *.google.de

altname = *.google.it

altname = *.google.pt

altname = *.google.fr

altname = *.google.ca

altname = *.google.co.uk

altname = *.google.es

altname = *.google.co.in

altname = *.google.com.br

altname = *.ytimg.com

altname = youtu.be

altname = *.youtube-nocookie.com

altname = youtube.com

altname = *.youtube.com

altname = google.com

altname = *.google.com

serial number:40:98:f6:53:00:00:00:00:68:b6

SSL version is TLSv1.2

SSL cipher suite is SSL_RSA_WITH_RC4_128_SHA

SSL connect ok, sending GET...

Server response: HTTP/1.0 302 Found

Cache-Control: private

Content-Type: text/html; charset=UTF-8

Location: http://www.google.com

Content-Length: 218

Date: Mon, 01 Oct 2012 21:17:18 GMT

Server: GFE/2.0


This tells the client to connect to gmail.google.com on the HTTPS port of 443 and sends a generic GET. The “-d” option tells the client not to verify the server. The rest is the initial output from the server that fits into the read buffer.


If no command line arguments are given, then the client attempts to connect to the localhost on the wolfSSL default port of 11111.  It also loads the client certificate in case the server wants to perform client authentication.


The client is able to benchmark a connection when using the “-b <num>” argument. When used, the client attempts to connect to the specified server/port the argument number of times and gives the average time in milliseconds that it took to perform SSL_connect().  For example,


./examples/client/client -b 100

SSL_connect avg took: 0.653 milliseconds


If you'd like to change the default host from localhost, or the default port from 11111, you can change these settings in /wolfssl/test.h. The variables yasslIP and yasslPort control these settings. Re-build all of the examples including testsuite when changing these settings otherwise the test programs won't be able to connect to each other.


By default, the wolfSSL example client tries to connect to the specified server using TLS 1.2.  The user is able to change the SSL/TLS version which the client uses by using the “-v” command line option.  The following values are available for this option:


-v 0  =  SSL 3.0

-v 1  =  TLS 1.0

-v 2  =  TLS 1.1

-v 3  =  TLS 1.2


A common error users see when using the example client is -155:


err = -155, ASN sig error, confirm failure


This is typically caused by the wolfSSL client not being able to verify the certificate of the server it is connecting to.  By default, the wolfSSL client loads the yaSSL test CA certificate as a trusted root certificate.  This test CA certificate will not be able to verify an external server certificate which was signed by a different CA.  As such, to solve this problem, users either need to turn off verification of the peer (server), using the “-d” option:


./examples/client/client -h myhost.com -p 443 -d


Or load the correct CA certificate into the CyaSSL client using the “-A” command line option:


./examples/client/client -h myhost.com -p 443 -A serverCA.pem



3.4 Server Example



The server example demonstrates a simple SSL server that optionally performs client authentication. Only one client connection is accepted and then the server quits. The client example in normal mode (no command line arguments) will work just fine against the example server, but if you specify command line arguments for the client example, then a client certificate isn't loaded and the wolfSSL_connect() will fail (unless client cert check is disabled using the “-d” option). The server will report an error "-245, peer didn't send cert".  Like the example client, the server can be used with several command line arguments as well:


./examples/server/server --help

server 3.4.6 NOTE: All files relative to wolfSSL home dir

-?          Help, print this usage

-p <num>    Port to listen on, not 0, default 11111

-v <num>    SSL version [0-3], SSLv3(0) - TLS1.2(3)), default 3

-l <str>    Cipher list

-c <file>   Certificate file,           default ./certs/server-cert.pem

-k <file>   Key file,                   default ./certs/server-key.pem

-A <file>   Certificate Authority file, default ./certs/client-cert.pem

-d          Disable client cert check

-b          Bind to any interface instead of localhost only

-s          Use pre Shared keys

-t          Track wolfSSL memory use

-u          Use UDP DTLS, add -v 2 for DTLSv1 (default), -v 3 for DTLSv1.2

-f          Fewer packets/group messages

-r          Create server ready file, for external monitor

-N          Use Non-blocking sockets

-S <str>    Use Host Name Indication

-w          Wait for bidirectional shutdown


3.5 EchoServer Example



The echoserver example sits in an endless loop waiting for an unlimited number of client connections. Whatever the client sends the echoserver echos back. Client authentication isn't performed so the example client can be used against the echoserver in all 3 modes. Four special commands aren't echoed back and instruct the echoserver to take a different action.


  1. 1."quit"  If the echoserver receives the string "quit" it will shutdown.


  1. 2."break"  If the echoserver receives the string "break" it will stop the current session but continue handling requests. This is particularly useful for DTLS testing.


  1. 3."printstats" If the echoserver receives the string "printstats" it will print out statistics for the session cache.


  1. 4."GET"  If the echoserver receives the string "GET" it will handle it as an http get and send back a simple page with the message "greeting from wolfSSL".  This allows testing of various TLS/SSL clients like Safari, IE, Firefox, gnutls, and the like against the echoserver example.



The output of the echoserver is echoed to stdout unless NO_MAIN_DRIVER is defined.  You can redirect output through the shell or through the first command line argument. To create a file named output.txt with the output from the echoserver run:


./examples/echoserver/echoserver outupt.txt



3.6 EchoClient Example



The echoclient example can be run in interactive mode or batch mode with files. To run in interactive mode and write 3 strings "hello", "wolfssl", and "quit" results in:


./examples/echoclient/echoclient

hello

hello

wolfssl

wolfssl

quit

sending server shutdown command: quit!


To use an input file, specify the file name on the command line as the first argument. To echo the contents of the file input.txt issue:


./examples/echoclient/echoclient input.txt


If you want the result to be written out to a file, you can specify the output file name as an additional command line argument. The following command will echo the contents of file input.txt and write the result from the server to output.txt:


./examples/echoclient/echoclient input.txt output.txt


The testsuite program does just that but hashes the input and output files to make sure that the client and server were getting/sending the correct and expected results.



3.7 Benchmark



Many users are curious about how the wolfSSL embedded SSL library will perform on a specific hardware device or in a specific environment.  Because of the wide variety of different platforms and compilers used today in embedded, enterprise, and cloud-based environments, it is hard to give generic performance calculations across the board.


To help wolfSSL users and customers in determining SSL performance for wolfSSL / wolfCrypt, a benchmark application is provided which is bundled with wolfSSL.  wolfSSL uses the wolfCrypt cryptography library for all crypto operations by default.  Because the underlying crypto is a very performance-critical aspect of SSL/TLS, our benchmark application runs performance tests on wolfCrypt’s algorithms.


The benchmark utility located in wolfcrypt/benchmark may be used to benchmark the cryptographic functionality of wolfCrypt. Typical output may look like the following (in this output, several optional algorithms/ciphers were enabled including HC-128, RABBIT, ECC, SHA-256, SHA-512, AES-GCM, AES-CCM, and Camellia):


./wolfcrypt/benchmark/benchmark

AES      50 megs took 0.274 seconds,  182.588 MB/s Cycles per byte =  11.99

AES-GCM  50 megs took 0.824 seconds,   60.694 MB/s Cycles per byte =  36.06

AES-CCM  50 megs took 0.517 seconds,   96.697 MB/s Cycles per byte =  22.63

Camellia 50 megs took 0.367 seconds,  136.311 MB/s Cycles per byte =  16.05

HC128    50 megs took 0.030 seconds, 1651.847 MB/s Cycles per byte =   1.32

RABBIT   50 megs took 0.110 seconds,  452.555 MB/s Cycles per byte =   4.84

CHACHA   50 megs took 0.136 seconds,  366.617 MB/s Cycles per byte =   5.97

CHA-POLY 50 megs took 0.173 seconds,  288.301 MB/s Cycles per byte =   7.59

3DES     50 megs took 1.858 seconds,   26.907 MB/s Cycles per byte =  81.33


MD5      50 megs took 0.114 seconds,  440.273 MB/s Cycles per byte =   4.97

POLY1305 50 megs took 0.043 seconds, 1153.562 MB/s Cycles per byte =   1.90

SHA      50 megs took 0.103 seconds,  484.172 MB/s Cycles per byte =   4.52

SHA-256  50 megs took 0.240 seconds,  208.581 MB/s Cycles per byte =  10.49

SHA-384  50 megs took 0.159 seconds,  313.674 MB/s Cycles per byte =   6.98

SHA-512  50 megs took 0.206 seconds,  242.518 MB/s Cycles per byte =   9.02

BLAKE2b  50 megs took 0.091 seconds,  548.120 MB/s Cycles per byte =   3.99


RSA 2048 encryption took  0.080 milliseconds, avg over 100 iterations

RSA 2048 decryption took  2.026 milliseconds, avg over 100 iterations

DH  2048 key generation   0.793 milliseconds, avg over 100 iterations

DH  2048 key agreement    0.763 milliseconds, avg over 100 iterations


ECC  256 key generation   0.426 milliseconds, avg over 100 iterations

EC-DHE   key agreement    0.421 milliseconds, avg over 100 iterations

EC-DSA   sign   time      0.451 milliseconds, avg over 100 iterations

EC-DSA   verify time      0.612 milliseconds, avg over 100 iterations


This is especially useful for comparing the public key speed before and after changing the math library. You can test the results using the normal math library (./configure), the fastmath library (./configure --enable-fastmath), and the fasthugemath library (./configure --enable-fasthugemath).


For more details about benchmarking wolfSSL and wolfCrypt, please refer to the wolfSSL Benchmarks page.


3.7.1 Relative Performance


Although the performance of individual ciphers and algorithms will depend on the host platform, the following graph shows relative performance between wolfCrypt’s ciphers.  These tests were conducted on a Macbook Pro (OS X 10.6.8) running a 2.2 GHz Intel Core i7.




If you want to use only a subset of ciphers, you can customize which specific cipher suites and/or ciphers wolfSSL uses when making an SSL/TLS connection.  For example, to force 128-bit AES, add the following line after the call to wolfSSL_CTX_new (SSL_CTX_new):


wolfSSL_CTX_set_cipher_list(ctx, “AES128-SHA”);



3.7.2 Benchmarking Notes


  1. 1.The processors native register size (32 vs 64-bit) can make a big difference when doing 1000+ bit public key operations.


  1. 2.keygen (--enable-keygen) will allow you to also benchmark key generation speeds when running the benchmark utility.


  1. 3.fastmath (--enable-fastmath) reduces dynamic memory usage and speeds up public key operations. If you are having trouble building on 32-bit platform with fastmath, disable shared libraries so that PIC isn’t hogging a register (also see notes in the README)

    ./configure --enable-fastmath --disable-shared
    make clean
    make

    *Note: doing a “make clean” is good practice with wolfSSL when switching configure options.

  2. 4.By default, fastmath tries to use assembly optimizations if possible. If assembly optimizations don’t work, you can still use fastmath without them by adding TFM_NO_ASM to CFLAGS when building wolfSSL:

    ./configure --enable-fastmath CFLAGS=DTFM_NO_ASM

  3. 5.Using fasthugemath can try to push fastmath even more for users who are not running on embedded platforms:

    ./configure --enable-fasthugemath

  4. 6.With the default wolfSSL build, we have tried to find a good balance between memory usage and performance. If you are more concerned about one of the two, please refer back to Chapter 2 for additional wolfSSL configuration options.

  5. 7.Bulk Transfers: wolfSSL by default uses 128 byte I/O buffers since about 80% of SSL traffic falls within this size and to limit dynamic memory use. It can be configured to use 16K buffers (the maximum SSL size) if bulk transfers are required.



3.7.3 Benchmarking on Embedded Systems


There are several build options available to make building the benchmark application on an embedded system easier.  These include:


BENCH_EMBEDDED - enabling this define will switch the benchmark application from using Megabytes to using Kilobytes, therefore reducing the memory usage.  By default, when using this define, ciphers and algorithms will be benchmarked with 25kB.  Public key algorithms will only be benchmarked over 1 iteration (as public key operations on some embedded processors can be fairly slow).  These can be adjusted in benchmark.c by altering the variables “numBlocks” and “times” located inside the BENCH_EMBEDDED define.


USE_CERT_BUFFERS_1024 - enabling this define will switch the benchmark application from loading test keys and certificates from the file system and instead use 1024-bit key and certificate buffers located in <wolfssl_root>/wolfssl/certs_test.h.  It is useful to use this define when an embedded platform has no filesystem (used with NO_FILESYSTEM) and a slow processor where 2048-bit public key operations may not be reasonable.


USE_CERT_BUFFERS_2048 - enabling this define is similar to USE_CERT_BUFFERS_1024 except that 2048-bit key and certificate buffers are used instead of 1024-bit ones.  This define is useful when the processor is fast enough to do 2048-bit public key operations but when there is no filesystem available to load keys and certificates from files.



3.8 Changing a Client Application to Use wolfSSL



This section will explain the basic steps needed to add wolfSSL to a client application, using the wolfSSL native API. For a server explanation, please see section 3.9.  A more complete walk-through with example code is located in the SSL Tutorial in Chapter 11.  If you want more information about the OpenSSL compatibility layer, please see Chapter 13.


  1. 1.Include the wolfSSL header


    #include <wolfssl/ssl.h>


  1. 2.Change all calls from read() (or recv()) to wolfSSL_read() so


    result = read(fd, buffer, bytes);


         becomes


    result = wolfSSL_read(ssl, buffer, bytes);


  1. 3.Change all calls from write (or send) to wolfSSL_write() so


    result = write(fd, buffer, bytes);


         becomes


    result = wolfSSL_write(ssl, buffer, bytes);


  1. 4.You can manually call wolfSSL_connect() but that's not even necessary, the first call to wolfSSL_read() or wolfSSL_write() will initiate the wolfSSL_connect() if it hasn't taken place yet.


  1. 5.Initialize wolfSSL and the WOLFSSL_CTX. You can use one WOLFSSL_CTX no matter how many WOLFSSL objects you end up creating. Basically you'll just have to load CA certificates to verify the server you're connecting to. Basic initialization looks like:


    wolfSSL_Init();


    WOLFSSL_CTX* ctx;


    if ( (ctx = wolfSSL_CTX_new(wolfTLSv1_client_method())) == NULL) {

       fprintf(stderr, "wolfSSL_CTX_new error.\n");

       exit(EXIT_FAILURE);

    }


    if (wolfSSL_CTX_load_verify_locations(ctx,"./ca-cert.pem",0) != SSL_SUCCESS) {

       fprintf(stderr, "Error loading ./ca-cert.pem,"

                       " please check the file.\n");

       exit(EXIT_FAILURE);

    }


  1. 6.Create the WOLFSSL object after each TCP connect and associate the file descriptor with the session:


    // after connecting to socket fd


    WOLFSSL* ssl;


    if ( (ssl = wolfSSL_new(ctx)) == NULL) {

       fprintf(stderr, "wolfSSL_new error.\n");

       exit(EXIT_FAILURE);

    }


    wolfSSL_set_fd(ssl, fd);


  1. 7.Error checking. Each wolfSSL_read() and wolfSSL_write() call will return the number of bytes written upon success, 0 upon connection closure, and -1 for an error,  just like read() and write(). In the event of an error you can use two calls to get more information about the error:


    char errorString[80];

    int err = wolfSSL_get_error(ssl, 0);

    wolfSSL_ERR_error_string(err, errorString);


  1. If you are using non blocking sockets, you can test for errno EAGAIN/EWOULDBLOCK or more correctly you can test the specific error code for SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE.


  1. 8.Cleanup. After each WOLFSSL object is done being used you can free it up by calling:


    wolfSSL_free(ssl);


  1. When you are completely done using SSL/TLS altogether you can free the WOLFSSL_CTX object by calling:


    wolfSSL_CTX_free(ctx);

    wolfSSL_Cleanup();


  1. For an example of a client application using wolfSSL, see the client example located in the <wolfssl_root>/examples/client.c file.


3.9 Changing a Server Application to Use wolfSSL



This section will explain the basic steps needed to add wolfSSL to a server application using the wolfSSL native API. For a client explanation, please see section 3.8.  A more complete walk-through, with example code, is located in the SSL Tutorial in Chapter 11.


  1. 1.Follow the instructions above for a client, except change the client method call in step 5 to a server one, so


    wolfSSL_CTX_new(wolfTLSv1_client_method())


  1. becomes


    wolfSSL_CTX_new(wolfTLSv1_server_method())


  1. or even


    wolfSSL_CTX_new(wolfSSLv23_server_method())


  1. To allow SSLv3 and TLSv1+ clients to connect to the server.


  1. 2.Add the server's certificate and key file to the initialization in step 5 above:


    if (wolfSSL_CTX_use_certificate_file(ctx,"./server-cert.pem",

                                    SSL_FILETYPE_PEM) != SSL_SUCCESS) {

       fprintf(stderr, "Error loading ./server-cert.pem,"

                       " please check the file.\n");

       exit(EXIT_FAILURE);

    }


    if (wolfSSL_CTX_use_PrivateKey_file(ctx,"./server-key.pem",

                                         SSL_FILETYPE_PEM) != SSL_SUCCESS) {

       fprintf(stderr, "Error loading ./server-key.pem,"

                       " please check the file.\n");

       exit(EXIT_FAILURE);

    }


It is possible to load certificates and keys from buffers as well if there is no filesystem available.  In this case, see the wolfSSL_CTX_use_certificate_buffer() and wolfSSL_CTX_use_PrivateKey_buffer() API documentation for more information.


For an example of a server application using CyaSSL, see the server example located in the <wolfssl_root>/examples/server.c file.

 

Docs -> wolfSSL Manual

Questions? +1 (425) 245-8247