How it works
This page explains in more detail how the plugin works internally.
MariaDB has an encryption key management plugin API. Via this API, plugins can provide MariaDB with symmetric keys. MariaDB then uses these keys to encrypt data in the database. The responsibility of the plugin is to manage these keys and to provide the keys to MariaDB when it asks for them. MariaDB then uses the keys to encrypt the database.
Importantly, this means that:
- The keys are provided to MariaDB in plaintext. MariaDB will keep them in-memory, but not write them to disk.
- The encryption/decryption of data happens on the server running MariaDB, and not on the HSM.
The MariaDB key management plugin API consists of two functions (slightly simplified):
get_key(key_id, version)
: Returns the plaintext key identified by this id, at the given version.get_latest_version(key_id)
: For a given key id, returns the latest version of the key.
The versions are relevant for plugins that support key rotation.
With get_latest_version
the plugin can signal to MariaDB which version of the key is the most recent.
Combined with the innodb_encryption_rotate_key_age
setting, MariaDB can determine whether existing data needs to be re-encrypted.
Since the Securosys plugin currently does not support key rotation, get_latest_version
always returns 1.
Key ids
The other part of this API is the key id.
In MariaDB, every encryption key is identified by a 32-bit integer, the "key id".
The default key id is 1.
This is configured with the innodb_default_encryption_key_id
setting.
Additionally, MariaDB uses key id 2 for encrypting temporary files.
For every table, the database administrator can specify
the ENCRYPTION_KEY_ID
to select which key should be used to encrypt a given table.
The default key id is used to encrypt tables that don't specify an explicit choice of key id,
as well as to encrypt other non-table data (such as logs).
An important thing to note is that the key management plugin, its settings,
and the keys that it provides to MariaDB are global to this MariaDB instance.
If you have multiple databases on this instance, they all use the same key management plugin
and MariaDB uses the same default key id for all databases.
This is a limitation/design choice of MariaDB: note that in the get_key
function above
the plugin does not learn for which database or which table MariaDB is requesting a key.
Therefore as a database administrator, you need to think about how you want to structure your key management.
For example, you can define an addressing scheme where key ids 100-199 belong to tables in database 1,
key ids 200-299 belong to tables in database 2, and so on (similar to how you would allocate IP subnets).
Using this scheme you then explicitly set
the ENCRYPTION_KEY_ID
for your tables.
Another option is to run separate MariaDB instances.
Key hierarchy
Recall that MariaDB receives the plaintext symmetric keys to do the encryption/decryption itself. So where does the HSM come in? Under the hood, there is a hierarchy of keys leading back to the HSM. In particular, there are three types of keys: the root key, the wrapping key, and the data keys (encryption keys).
Key | Type | Stored on HSM as | Leaves HSM? | Purpose | Key creation |
---|---|---|---|---|---|
Root key | RSA with SKA, or AES | Private/secret key | No | Encrypts the wrapping key. Can be protected with SKA policies. | Directly in HSM. |
Wrapping key | AES | Data object | Yes | Encrypts the data keys. Stored in-memory by the plugin after being decrypted by the root key. | In plugin, by fetching random bytes from the HSM. |
Data keys | AES | Data object | Yes | Passed to MariaDB in response to get_key calls. Used by MariaDB for database encryption. | In plugin, by fetching random bytes from the HSM. |
The separation into root key and wrapping key is necessary because the Primus HSM only supports SKA policies for asymmetric keys. Symmetric keys cannot have SKA policies attached to them.
If the plugin detects that the HSM partition has SKA licensed and enabled, it generates an RSA key with SKA as the root key. Initially, the SKA policy is empty, but administrators can later manually modify the SKA policy. If SKA is not available, the plugin generates an AES key as the root key.
Flow diagrams
The flows in the Securosys plugin look as follows: