Libcrypto API
OpenSSL provides two primary libraries: libssl and libcrypto. The libcrypto library provides the fundamental cryptographic routines used by libssl. You can however use libcrypto without using libssl.
Getting Started
In order to use libcrypto it must first (typically) be initialised:
#include <openssl/evp.h> int main(int arc, char *argv[]) { /* Load the human readable error strings for libcrypto */ ERR_load_crypto_strings(); /* Load all digest and cipher algorithms */ OpenSSL_add_all_algorithms();
/* Load config file, and other important initialisation */ OpenSSL_config(); /* ... Do some crypto stuff here ... */ /* Clean up */ /* Removes all digests and ciphers */ EVP_cleanup(); /* Remove error strings */ ERR_free_strings(); return 0; }
High Level and Low Level Interfaces
For most uses, users should use the high level interface that is provided for performing cryptographic operations. This is known as the EVP interface (short for Envelope). This interface provides a suite of functions for performing encryption/decryption (both symmetric and asymmetric), signing/verifying, as well as generating hashes and MAC codes, across the full range of OpenSSL supported algorithms and modes. Working with the high level interface means that a lot of the complexity of performing cryptographic operations is hidden from view. A single consistent API is provided. In the event that you need to change your code to use a different algorithm (for example), then this is a simple change when using the high level interface. In addition low level issues such as padding and encryption modes are all handled for you.
Refer to EVP for further information on the high level interface.
In addition to the high level interface, OpenSSL also provides low level interfaces for working directly with the individual algorithms. These low level interfaces are not recommended for the novice user, but provide a degree of control that may not be possible when using only the high level interface.
Error Handling
Most OpenSSL functions will return an integer to indicate success or failure. Typically a function will return 1 on success or 0 on error. All return codes should be checked and handled as appropriate.
It is common to see errors handled in a way similar to the following:
if(!EVP_xxx()) goto err; if(!EVP_yyy()) goto err; /* ... do some stuff ... */ err: ERR_print_errors_fp(stderr);