MinIO supports two different types of server-side encryption ([SSE](#sse)):
MinIO supports two different types of server-side encryption ([SSE](#sse)):
- **SSE-C**: The MinIO server en/decrypts an object with a secret key provided by the S3 client
- **SSE-C**: The MinIO server en/decrypts an object with a secret key provided by the S3 client as part of the HTTP request headers. Therefore, [SSE-C](#ssec) requires TLS/HTTPS.
as part of the HTTP request headers. Therefore, [SSE-C](#ssec) requires TLS/HTTPS.
- **SSE-S3**: The MinIO server en/decrypts an object with a secret key managed by a KMS. Therefore, MinIO requires a valid KMS configuration for [SSE-S3](#sses3).
- **SSE-S3**: The MinIO server en/decrypts an object with a secret key managed by a KMS.
Therefore, MinIO requires a valid KMS configuration for [SSE-S3](#sses3).
### Server-Side Encryption - Preliminaries
### Server-Side Encryption - Preliminaries
#### Secret Keys
#### Secret Keys
The MinIO server uses an unique, randomly generated secret key per object also known as,
The MinIO server uses an unique, randomly generated secret key per object also known as, Object Encryption Key ([OEK](#oek)). Neither the client-provided SSE-C key nor the KMS-managed key is directly used to en/decrypt an object. Instead, the OEK is stored as part of the object metadata next to the object in an encrypted form. To en/decrypt the OEK another secret key is needed also known as, Key Encryption Key ([KEK](#kek)).
Object Encryption Key ([OEK](#oek)). Neither the client-provided SSE-C key nor the KMS-managed
key is directly used to en/decrypt an object. Instead, the OEK is stored as part of the object
The MinIO server runs a key-derivation algorithm to generate the KEK using a pseudo-random function ([PRF](#prf)):
metadata next to the object in an encrypted form. To en/decrypt the OEK another secret key is
`KEK := PRF(EK, IV, context_values)` where:
needed also known as, Key Encryption Key ([KEK](#kek)).
- [EK](#ek): is the external key. In case of SSE-C this is the client-provided key. In case of SSE-S3 this is secret key generated by the KMS. For further details see [SSE-C](#Server-Side-Encryption-with-client-provided-Keys) or [SSE-S3](#Server-Side-Encryption-with-a-KMS).
The MinIO server runs a key-derivation algorithm to generate the KEK using a pseudo-random
- [IV](#iv): is a randomly generated initialization vector. It is public and part of the object metadata.
function ([PRF](#prf)):
- `context_values`: are values like the bucket and object name and other information which should be cryptographically bound to the KEK.
`KEK := PRF(EK, IV, context_values)` where
- [EK](#ek): is the external key. In case of SSE-C this is the client-provided key. In case of SSE-S3
this is secret key generated by the KMS. For further details see
[SSE-C](#Server-Side-Encryption-with-client-provided-Keys) or
[SSE-S3](#Server-Side-Encryption-with-a-KMS).
- [IV](#iv): is a randomly generated initialization vector. It is public and part of the
object metadata.
- `context_values`: are values like the bucket and object name and other information which should be
cryptographically bound to the KEK.
To summarize for any encrypted object there exists (at least) three different keys:
To summarize for any encrypted object there exists (at least) three different keys:
1. [OEK](#oek): A secret and unique key used to encrypted the object, stored in an encrypted form as
part of the object metadata and only loaded to RAM in plaintext during en/decrypting the object.
- [OEK](#oek): A secret and unique key used to encrypted the object, stored in an encrypted form as part of the object metadata and only loaded to RAM in plaintext during en/decrypting the object.
2. [KEK](#kek): A secret and unique key used to en/decrypt the OEK and never stored anywhere.
- [KEK](#kek): A secret and unique key used to en/decrypt the OEK and never stored anywhere. It is(re-)generated whenever en/decrypting an object using an external secret key and public parameters.
It is(re-)generated whenever en/decrypting an object using an external secret key and public
- [EK](#ek): An external secret key - either the SSE-C client-provided key or a secret key generated by the KMS.
parameters.
3. [EK](#ek): An external secret key - either the SSE-C client-provided key or a secret key
generated by the KMS.
#### Content Encryption
#### Content Encryption
The MinIO server uses an authenticated encryption scheme ([AEAD](#aead)) to en/decrypt and
The MinIO server uses an authenticated encryption scheme ([AEAD](#aead)) to en/decrypt and authenticate the object content. The AEAD is combined with some state to build a *Secure Channel*. A *Secure Channel* is a cryptographic construction that ensures confidentiality and integrity of the processed data. In particular the *Secure Channel* splits the plaintext content into fixed size chunks and en/decrypts each chunk separately using an unique key-nonce combination.
authenticate the object content. The AEAD is combined with some state to build a
*Secure Channel*. A *Secure Channel* is a cryptographic construction that ensures confidentiality
and integrity of the processed data. In particular the *Secure Channel* splits the plaintext content
into fixed size chunks and en/decrypts each chunk separately using an unique key-nonce combination.
In case of a S3 multi-part operation each part is en/decrypted with the scheme shown in
In case of a S3 multi-part operation each part is en/decrypted with the scheme shown in Figure 1. However, for each part an unique secret key is derived from the OEK and the part number using a PRF. So in case of multi-part not the OEK but the output of `PRF(OEK, part_id)` is used as secret key.
Figure 1. However, for each part an unique secret key is derived from the OEK and the part
number using a PRF. So in case of multi-part not the OEK but the output of `PRF(OEK, part_id)`
is used as secret key.
#### Cryptographic Primitives
#### Cryptographic Primitives
The SSE schemes described in [Secret Keys](#Secret-Keys) and [Content Encryption](#Content-Encryption)
The SSE schemes described in [Secret Keys](#Secret-Keys) and [Content Encryption](#Content-Encryption) are generic over the cryptographic primitives. However, the MinIO server uses the following cryptographic primitive implementations:
are generic over the cryptographic primitives. However, the MinIO server uses the following
cryptographic primitive implementations:
- [PRF](#prf): HMAC-SHA-256
- [PRF](#prf): HMAC-SHA-256
- [AEAD](#aead): AES-256-GCM if the CPU supports AES-NI, ChaCha20-Poly1305 otherwise.
- [AEAD](#aead): AES-256-GCM if the CPU supports AES-NI, ChaCha20-Poly1305 otherwise. More specifically AES-256-GCM is only selected for X86-64 CPUs with AES-NI extension.
More specifically AES-256-GCM is only selected for X86-64 CPUs with AES-NI extension.
Further any secret key (apart from the KMS-generated ones) is 256 bits long. The KMS-generated keys
Further any secret key (apart from the KMS-generated ones) is 256 bits long. The KMS-generated keys may be 256 bits but this depends on the KMS capabilities and configuration.
may be 256 bits but this depends on the KMS capabilities and configuration.
The *Secure Channel* splits the object content into chunks of a fixed size of `65536` bytes. The last
The *Secure Channel* splits the object content into chunks of a fixed size of `65536` bytes. The last chunk may be smaller to avoid adding additional overhead and is treated specially to prevent truncation attacks. The nonce value is 96 bits long and generated randomly per object / multi-part part. The *Secure Channel* supports plaintexts up to `65536 * 2^32 = 256 TiB`.
chunk may be smaller to avoid adding additional overhead and is treated specially to prevent truncation
attacks. The nonce value is 96 bits long and generated randomly per object / multi-part part. The
*Secure Channel* supports plaintexts up to `65536 * 2^32 = 256 TiB`.
#### Randomness
#### Randomness
The MinIO server generates unique keys and other cryptographic values using a cryptographically
The MinIO server generates unique keys and other cryptographic values using a cryptographically secure pseudo-random number generator ([CSPRNG](#csprng)). However, in the context of SSE, the MinIO server does not require that the CSPRNG generates values that are indistinguishable from truly random bit strings. Instead, it is sufficient if the generated values are unique - which is a weaker requirement. Nevertheless other parts - for example the TLS-stack - may require that CSPRNG-generated values are indistinguishable from truly random bit strings.
secure pseudo-random number generator ([CSPRNG](#csprng)). However, in the context of SSE,
the MinIO server does not require that the CSPRNG generates values that are indistinguishable
from truly random bit strings. Instead, it is sufficient if the generated values are unique - which
is a weaker requirement. Nevertheless other parts - for example the TLS-stack - may require that
CSPRNG-generated values are indistinguishable from truly random bit strings.
### Server-Side Encryption with client-provided Keys
### Server-Side Encryption with client-provided Keys
SSE-C allows an S3 client to en/decrypt an object at the MinIO server. Therefore the S3 client
SSE-C allows an S3 client to en/decrypt an object at the MinIO server. Therefore the S3 client sends a secret key as part of the HTTP request. This secret key is **never** stored by the MinIO server and only resides in RAM during the en/decryption process.
sends a secret key as part of the HTTP request. This secret key is **never** stored by the
MinIO server and only resides in RAM during the en/decryption process.
MinIO does not assume or require that the client-provided key is unique. It may be used for
MinIO does not assume or require that the client-provided key is unique. It may be used for multiple objects or buckets. Especially a single client-provided key may be used for all objects - even though all objects must be treated as compromised if that key is ever compromised.
multiple objects or buckets. Especially a single client-provided key may be used for all
objects - even though all objects must be treated as compromised if that key is ever compromised.
#### Key rotation
#### Key rotation
S3 clients can change the client-provided key of an existing object. Therefore an S3 client
S3 clients can change the client-provided key of an existing object. Therefore an S3 client must perform a S3 COPY operation where the copy source and destination are equal. Further the COPY request headers must contain the current and the new client key:
must perform a S3 COPY operation where the copy source and destination are equal. Further the
COPY request headers must contain the current and the new client key:
- `X-Amz-Server-Side-Encryption-Customer-Key`: Base64 encoded new key.
- `X-Amz-Server-Side-Encryption-Customer-Key`: Base64 encoded new key.
- `X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key`: Base64 encoded current key.
- `X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key`: Base64 encoded current key.
@ -111,31 +74,25 @@ Such a special COPY request is also known as S3 SSE-C key rotation.
### Server-Side Encryption with a KMS
### Server-Side Encryption with a KMS
SSE-S3 allows an S3 client to en/decrypt an object at the MinIO server using a KMS. The MinIO
SSE-S3 allows an S3 client to en/decrypt an object at the MinIO server using a KMS. The MinIO
server only assumes that the KMS provides two services:
server only assumes that the KMS provides two services:
1. `GenerateKey`: Takes a key ID and generates a new data key from a master key referenced by
the key ID. It returns the new data key in two different forms: The plain data key
- `GenerateKey`: Takes a key ID and generates a new data key from a master key referenced by the key ID. It returns the new data key in two different forms: The plain data key and the data key encrypted using the master key.
and the data key encrypted using the master key.
2. `DecryptKey`: Takes a key ID and an encrypted data key and returns the plain data key - the
- `DecryptKey`: Takes a key ID and an encrypted data key and returns the plain data key - the decryption of the encrypted data key using the master key referenced by the key ID - on success or an error otherwise.
decryption of the encrypted data key using the master key referenced by the key ID -
on success or an error otherwise.
More details about supported KMS implementations and configuration can be found at the [KMS guide](https://github.com/minio/minio/blob/master/docs/kms/README.md).
More details about supported KMS implementations and configuration can be found at the [KMS guide](https://github.com/minio/minio/blob/master/docs/kms/README.md).
The MinIO server requests a new data key from the KMS for each uploaded object and uses that data key
The MinIO server requests a new data key from the KMS for each uploaded object and uses that data key as EK. Additionally it stores the encrypted form of the data key and the master key ID as part of the object metadata. The plain data only resides in RAM during the en/decryption process. The MinIO server does not store any SSE-related key at the KMS. Instead the KMS is treated as trusted component that performs key sealing/unsealing operations to build a key hierarchy:
as EK. Additionally it stores the encrypted form of the data key and the master key ID as part
of the object metadata. The plain data only resides in RAM during the en/decryption process.
The MinIO server does not store any SSE-related key at the KMS. Instead the KMS is treated as trusted
component that performs key sealing/unsealing operations to build a key hierarchy:
@ -158,11 +115,7 @@ component that performs key sealing/unsealing operations to build a key hierarch
#### Key rotation - Basic Operation
#### Key rotation - Basic Operation
The MinIO server supports key rotation for SSE-S3 encrypted objects. The minio server decrypts
The MinIO server supports key rotation for SSE-S3 encrypted objects. The minio server decrypts the OEK using the current encrypted data key and the master key ID of the object metadata. If this succeeds, the server requests a new data key from the KMS using the master key ID of the **current MinIO KMS configuration** and re-wraps the *OEK* with a new *KEK* derived from the new data key / EK:
the OEK using the current encrypted data key and the master key ID of the object metadata. If
this succeeds, the server requests a new data key from the KMS using the master key ID of
the **current MinIO KMS configuration** and re-wraps the *OEK* with a new *KEK* derived from
the new data key / EK:
```
```
object metadata KMS
object metadata KMS
@ -202,35 +155,25 @@ the new data key / EK:
```
```
<center>Figure 3 - KMS data key rotation</center>
<center>Figure 3 - KMS data key rotation</center>
Only the root/admin user can perform an SSE-S3 key rotation using the Admin-API via [mc](https://github.com/minio/mc).
Only the root/admin user can perform an SSE-S3 key rotation using the Admin-API via [mc](https://github.com/minio/mc). For more details about how to perform key management operations using the CLI refer to [mc admin guide](https://github.com/minio/mc/blob/master/docs/minio-admin-complete-guide.md) or run `mc admin kms key`.
For more details about how to perform key management operations using the CLI refer to
The MinIO server requires an available KMS to en/decrypt SSE-S3 encrypted objects. Therefore it
The MinIO server requires an available KMS to en/decrypt SSE-S3 encrypted objects. Therefore it is possible to erase or lock some or all encrypted objects. For example in case of a detected attack or other emergency situations the following actions can be taken:
is possible to erase or lock some or all encrypted objects. For example in case of a detected attack
or other emergency situations the following actions can be taken:
- Seal the KMS such that it cannot be accessed by MinIO server anymore. That will lock **all** SSE-S3 encrypted objects protected by master keys stored on the KMS. All these objects can not be decrypted as long as the KMS is sealed.
- Seal the KMS such that it cannot be accessed by MinIO server anymore. That will lock **all**
- Seal/Unmount one/some master keys. That will lock all SSE-S3 encrypted objects protected by these master keys. All these objects can not be decrypted as long as the key(s) are sealed.
SSE-S3 encrypted objects protected by master keys stored on the KMS. All these objects
- Delete one/some master keys. From a security standpoint, this is equal to erasing all SSE-S3 encrypted objects protected by these master keys. All these objects are lost forever as they cannot be decrypted. Especially deleting all master keys at the KMS is equivalent to secure erasing all SSE-S3 encrypted objects.
can not be decrypted as long as the KMS is sealed.
- Seal/Unmount one/some master keys. That will lock all SSE-S3 encrypted objects protected by
these master keys. All these objects can not be decrypted as long as the key(s) are sealed.
- Delete one/some master keys. From a security standpoint, this is equal to erasing all SSE-S3
encrypted objects protected by these master keys. All these objects are lost forever as they cannot
be decrypted. Especially deleting all master keys at the KMS is equivalent to secure erasing all
SSE-S3 encrypted objects.
## Acronyms
## Acronyms
- <aname="aead"></a>**AEAD**: Authenticated Encryption with Associated Data
- <aname="aead"></a>**AEAD**: Authenticated Encryption with Associated Data
- <aname="csprng"></a>**CSPRNG**: Cryptographically Secure Pseudo Random Number Generator
- <aname="csprng"></a>**CSPRNG**: Cryptographically Secure Pseudo Random Number Generator
- <aname="ek"></a>**EK**: External Key
- <aname="ek"></a>**EK**: External Key
- <aname="iv"></a>**IV**: Initialization Vector
- <aname="iv"></a>**IV**: Initialization Vector
- <aname="kek"></a>**KEK**: Key Encryption Key
- <aname="kek"></a>**KEK**: Key Encryption Key
- <aname="oek"></a>**OEK**: Object Encryption Key
- <aname="oek"></a>**OEK**: Object Encryption Key
- <aname="prf"></a>**PRF**: Pseudo Random Function
- <aname="prf"></a>**PRF**: Pseudo Random Function