---
layout: docs
page_title: Oracle TDE - PKCS#11 Provider - Vault Enterprise
description: |-
  The Vault PKCS#11 Provider can be used to enable Oracle TDE.
---

# Oracle TDE

@include 'alerts/enterprise-only.mdx'

[Oracle Transparent Data Encryption](https://docs.oracle.com/en/database/oracle/oracle-database/19/asoag/introduction-to-transparent-data-encryption.html) (TDE)
is supported with the [Vault PKCS#11 provider](/vault/docs/enterprise/pkcs11-provider).
In this setup, Vault's KMIP engine generates and store the "TDE Master Encryption Key" that the Oracle Database uses to encrypt and decrypt the "TDE Table Keys".
Oracle will not have access to the TDE Master Encryption Key itself.

## Requirements

To setup Oracle TDE backed by Vault, the following are required:

- A database running Oracle 19c Enterprise Edition
- A Vault Enterprise 1.11+ server with Advanced Data Protection for KMIP support.
- Vault has TCP port 5696 accessible to the Oracle database.
- `libvault-pkcs11.so` downloaded from [releases.hashicorp.com](https://releases.hashicorp.com/vault-pkcs11-provider) for the operating system running the Oracle database.

## Vault setup

On the Vault server, we need to [setup the KMIP Secrets Engine](/vault/docs/secrets/kmip):

1. Start the KMIP Secrets Engine and listener:

    ```sh
    vault secrets enable kmip
    vault write kmip/config listen_addrs=0.0.0.0:5696
    ```

    ~> **Important**: When configuring KMIP for Oracle, you will probably need to set the
    `server_hostnames` and `server_ips` [configuration parameters](/vault/api-docs/secret/kmip#parameters),
    otherwise the TLS connection to the KMIP Secrets Engine will fail due to certification validation errors.
    When configuring Oracle TDE, this error can manifest as the `sqlplus` session silently hanging.

1. Create a KMIP scope to contain the TDE keys and objects.
   The KMIP scope is essentially an isolated namespace.
   For example, you can create a scope called `my-service`:

    ```sh
    vault write -f kmip/scope/my-service
    ```

1. Create a KMIP role that has access to the scope:

    ```sh
    vault write kmip/scope/my-service/role/admin operation_all=true
    ```

1. Create TLS credentials (a certificate, key, and CA bundle) for the KMIP role:

    ~> **Note**: This command will output the credentials in plaintext.

    ```sh
    vault write -f -format=json kmip/scope/my-service/role/admin/credential/generate | tee kmip.json
    ```

    The response from the `credential/generate` endpoint is JSON.
    The `.data.certificate` entry contains a bundle of the TLS client key and certificate we will use to connect to KMIP with from Oracle.
    The `.data.ca_chain[]` entries contain the CA bundle to verify the KMIP server's certificate.
    Save these to, e.g., `cert.pem` and `ca.pem`:

    ```sh
    jq --raw-output --exit-status '.data.ca_chain[]' kmip.json > ca.pem
    jq --raw-output --exit-status '.data.certificate' kmip.json > cert.pem
    ```

## Oracle TDE preparation

The rest of the steps take place on the Oracle server.

We need to configure the Vault PKCS#11 provider.

1. Copy the `libvault-pkcs11.so` binary into `$ORACLE_BASE/extapi/64/hsm`, and ensure there are no other PKCS#11 libraries in `$ORACLE_BASE/extapi/64/hsm`.

1. Copy the TLS certificate and key bundle (e.g., `/etc/cert.pem`) and CA bundle (e.g., `/etc/ca.pem`) for the KMIP role (configured as above) to the Oracle server.
   The exact location does not matter as long as the Oracle process has access to it.

1. Create a configuration file, for example `/etc/vault-pkcs11.hcl`, with the following contents:

    ```hcl
    slot {
      server = "VAULT_ADDRESS:5696"
      tls_cert_path = "/etc/cert.pem"
      ca_path = "/etc/ca.pem"
      scope = "my-service"
    }
    ```

    This file is used by `libvault-pkcs11.so` to know how to find and communicate with the KMIP engine in Vault.

    In particular:
    - The `slot` block configures the first PKCS#11 slot to point to Vault. Oracle will use this first slot.
    - `server` should point to the Vault server's IP (or DNS name) and port number (5696 is the default).
    - `tls_cert_path` should be the location on the Oracle database of the client TLS certificate and key bundle used to connect to Vault server.
    - `ca_path` should be the location of the CA bundle on the Oracle database.
    - `scope` is the KMIP scope to authenticate against and where the TDE master keys and associated metadata will be stored.

    The default location the PKCS#11 library will look for the configuration file is the current directory (`./vault-pkcs11.hcl`) and `/etc/vault-pkcs11.hcl`, but you can override this by setting the `VAULT_KMIP_CONFIG` environment variable to any file.

1. If you want to view the Vault logs (helpful when trying to find error messages), you can specify the `VAULT_LOG_FILE` (default is stdout) and `VAULT_LOG_LEVEL` (default is `INFO`). We'd recommend setting `VAULT_LOG_FILE` to something like `/tmp/vault.log` or `/var/log/vault.log`. Other useful log levels are `WARN` (quieter) and `TRACE` (very verbose, could possibly contain sensitive information, like raw network packets).

## Enable TDE 

The only remaining step is to setup Oracle TDE for an external HSM using shared library, `libvault-pkcs11.so`.
These steps are not specific to Vault, other than requiring the shared library, HCL configuration, and certificates be present.
TDE is complex, but an example way to enable it is:

1. Open a `sqlplus` session into the root container (or switch into it with `ALTER SESSION SET CONTAINER = CDB$ROOT;`).

1. Set WALLET_ROOT and TDE_CONFIGURATION parameters on the Oracle database. The wallet root directory is only used to set the TDE configuration parameter. To learn more about the wallet parameters refer to the [Oracle TDE documentation](https://docs.oracle.com/en/database/oracle/oracle-database/19/refrn/TDE_CONFIGURATION.html).

    ```sql
    SQL> alter system set wallet_root='/opt/oracle/admin/ORCLCDB/wallet' scope=spfile;
    SQL> shutdown immediate;
    SQL> startup;
    SQL> alter system set TDE_CONFIGURATION="KEYSTORE_CONFIGURATION=HSM" SCOPE=both;
    ```
1. Validate the parameters are set by querying `V$PARAMETER`

    ```sql
    SQL> SELECT name, value from V$PARAMETER WHERE NAME IN ('wallet_root','tde_configuration');

    NAME                           VALUE
    ------------------------------ --------------------------------------------------
    wallet_root                    /opt/oracle/admin/ORCLCDB/wallet
    tde_configuration              KEYSTORE_CONFIGURATION=HSM
    ```

1. Open the HSM wallet: `ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN IDENTIFIED BY "1234" CONTAINER = ALL;`.
   The password `1234` here is used as the password for decrypting the TLS key, if it is stored encrypted on disk.
   If the TLS key is not encrypted, this password is ignored.

1. Create the TDE master key: `ADMINISTER KEY MANAGEMENT SET ENCRYPTION KEY USING TAG 'default' IDENTIFIED BY "1234" CONTAINER = ALL;`, again specifying the TLS key password if necessary.

1. Finally, use TDE in a PDB, e.g., `CREATE TABLE test_tde (something CHAR(32) ENCRYPT);`.

More extensive information on the details and procedures for Oracle TDE can be found in [Oracle's documentation](https://docs.oracle.com/en/database/oracle/oracle-database/19/asoag/configuring-transparent-data-encryption.html#GUID-753C4808-CC51-4DA1-A5C3-980417FDAB14).
