# Database Encryption in C

> As explained in page Database Encryption, eXtremeDB provides the capability to encrypt in-memory and persistent databases with standard AES encryption or by a custom encryption implementation.

> # Data Encryption

> The encryption of data in memory is controlled by the `cipher_key` element of the parameter structure (`mco_db_params_t`) passed into mco_db_open_dev(). If this parameter is not `NULL`, then pages are encrypted with the AES or custom encryption algorithm before being saved. Each page is encrypted individually.

> It is also possible to enable encryption with the online backup feature. The encryption of backup files is enabled by specifying the `cipher` argument of functions `mco_backup_create()` and `mco_backup_restore()`. Note that this option has no relation to the database parameter ``mco_db_params_t::cipher_key``.

> Database snapshot files are also encrypted by functions `mco_db_save()`, and decrypted by `mco_db_load()` if field `mco_db_params_t::cipher_key` is specified. Note that the exact same cipher key must be specified for saving and loading an encrypted snapshot.

> The choice of encryption algorithm is determined by the library linked with the application. The AES algorithm implementation is provided in library `mcocryptaes`.

> For details regarding implementation of a custom encryption algorithm, please see page Custom Encryption C API.

> ## In-Memory Database Encryption

> Encryption of in-memory pages is enabled only when both the `cipher_key` is specified and flag `MCO_DB_INMEMORY_PROTECTION` is set in field ``mco_db_params_t.mode_mask``. Internally, `MCO_DB_INMEMORY_PROTECTION` mode will cause the creation of a hash table of used database pages (pages being accessed by the application). The maximum number of pages accessed by one connection at a given time can be specified by the `max_active_pages` field of struct `mco_db_params_t`. The default value is 32. The number of bundles in this hash table (used to minimize the number of lock conflicts in case of concurrent access by multiple threads) can be specified using the `page_hash_bundles` field of `mco_db_params_t`. (This value should be set ideally to the maximum concurrency level; i.e. the number of CPU cores – the default value is 32).

> The following code snippet demonstrates how to enable encryption with the C API:

>         int main(int argc, char* argv[])
>         {
>             MCO_RET            rc;
>             mco_db_h db = 0;
>             mco_device_t       dev[1];
>             mco_db_params_t    db_params;
>             ...

>             /* Initialize and customize the database parameters */
>             mco_db_params_init ( &db_params );                  /* Initialize the params with default values */
>             db_params.mem_page_size      = 128;    /* Set page size for in-memory storage */
>             db_params.disk_page_size     = 0;  /* Set page size 0 for in-memory storage */
>             db_params.db_max_connections = 1;                   /* Set total number of connections to the database */
>             db_params.cipher_key         = "my_secure_key";     /* Set cipher key filename */
>             db_params.mode_mask         = MCO_DB_INMEMORY_PROTECTION;     /* Set mode mask */

>             rc = mco_db_open_dev(db_name, genericdb_get_dictionary(), dev, N_DEVICES, &db_params );
>             if ( MCO_S_OK == rc )
>             {
>                 /* Connect to the database, obtain a database handle */
>                 mco_db_connect(db_name, &db); /* No recovery connection data */
>                 ...
>             }

> Note that in-memory protection can be used only for pure in-memory databases (i.e. no disk manager is used). So if this mode is specified when the `mcovtdsk` library is used, the function `mco_db_open_dev()` or `mco_db_load()` will return error code `MCO_E_ILLEGAL_PARAM`.

> Also note that encryption of database pages can reduce application speed by 2-10 times, especially for index operations. Using the `MCO_DB_INCLUSIVE_BTREE` option can help to reduce this penalty (see the Key-Value-Inclusive and Covering Indexes page for further details).

> ### Compression and Encryption

> If the ``mco_db_params_t::mode_mask`` flag `MCO_DB_INMEMORY_COMPRESSION` is set, then memory pages are being compressed with the ZIP algorithm (see page Database Compression for further details). If mco_db_params_t::cipher_key is set in addition to the `mode_mask` flag `MCO_DB_INMEMORY_COMPRESSION` then transient database pages are both zipped and encrypted. However note that this combination is not compatible with the disk manager, thus compression plus encryption is not applicable for hybrid databases (with both transient and persistent classes) .

> ## Persistent Database Encryption

> eXtremeDB provides the capability to protect the persistent database memory arena, including the memory allocated for storage and the cache (page pool), through the operating system’s VM page-protection mechanism. However, note that it is only possible on UNIX platforms and should be done only for debugging purposes.

> As for in-memory database pages, the encryption of data on persistent storage is controlled by the `cipher_key` element of the parameter structure (`mco_db_params_t`) passed into mco_db_open_dev(). If this parameter is not `NULL`, then pages are encrypted with the AES or custom encryption algorithm before being saved to “disk” and decrypted when loaded from the “disk”. Each page is encrypted individually.

> AES is a symmetric encryption algorithm. On the first pass, the data is encrypted, and on the second pass is decrypted back to its original form. Consequently in the encryption API there are not separate functions to `encrypt` and `decrypt`, but simply the one function `encrypt`().

> The stub library `mcocryptstub` contains empty API implementations which simply halt processing with the error code `MCO_E_UNSUPPORTED` and is provided for developers to implement a custom encryption algorithm. (See section Encryption Libraries below and Custom Encryption Algorithm Implementation for further details.)

> Note that encryption of database pages can reduce application speed by 2-10 times, especially for index operations. Using the `MCO_DB_INCLUSIVE_BTREE` option can help to reduce this penalty (see the Key-Value-Inclusive and Covering Indexes page for further details).

> ## Encryption of other files external to the database

> Apart from protecting persistent and transient databases, encryption can be used to protect database snapshots made by functions `mco_db_save()` and `mco_class_save()`, to protect the TL transaction log (created by `mco_translog_start()`) and also to protect backup files created by function `mco_backup_create()`.

> The encryption of database snapshots and transaction log files is automatically enabled by specifying the `cipher_key` field just as for the encryption of disk and memory pages. Encryption of backup operations is however independent of database open parameters and is directly specified by the `cipher` argument passed to functions ``mco_backup_create()`` and `mco_backup_restore()`.

> ## Encryption Libraries

> Please use the links below to view the AES encryption algorithm library and "stub" library (as well as other libraries) provided for your development platform:

> Unix-Linux | Static libraries for Standard Unix or Linux 64bit or 32bit platforms
> Windows | Static libraries for Windows 7 (or later) platforms
> Integrity | Static libraries for Green Hills Integrity OS
> VxWorks | Static libraries for Wind River VxWorks OS