Try   HackMD

KMS v2 crypto changes

Unchanged

encrypts

EDEK stored

KEK

accessed via plugin

DEK

etcd

Current KMS v2

additional_data

encrypts

resource

stored as
nonce|encrypted_dek|ciphertext

etcd_path

unique per object in etcd
/PATH_PREFIX/secrets/NAMESPACE/NAME

DEK

aes_gcm

counter_nonce_8

nonce_12

rand_nonce_4

Proposed KMS v2

The idea is to extend the limited 12 byte AES-GCM nonce with a 32 byte info (randomly generated per write) that is fed into HKDF-Expand (the secret is the "DEK seed" and the hash is SHA-256). We read 32 bytes from HKDF-Expand to use as the AES-GCM DEK.

We want the crypto properties of KMS v1 (one DEK per write) without the network overhead. The DEK seed (32 random bytes) is generated on server start up and automatically rotated whenever the remote KEK changes. Note that the HKDF-Extract step is skipped because we already have a good pseudo random key (thus there is no salt, only info).

This allows us to return to a purely per-write random 12 byte nonce for AES-GCM because each generated DEK+nonce combination is unique (the chance of collision is negligible). VM state restores will no longer be an issue.

While not strictly necessary, a cache will be used to memoize the HKDF operations as they are fully deterministic based on the inputs. This significantly reduces the overhead of the key generation both in terms of CPU time and memory allocations.

Note that the info must be stored (in the clear) with the ciphertext, meaning we increase the storage overhead by 32 bytes.

pseudo random key

hash

info param

generates

key

nonce

additional_data

encrypts

etcd_path

unique per object in etcd
/PATH_PREFIX/secrets/NAMESPACE/NAME

resource

stored as
info|nonce|encrypted_seed|ciphertext

DEK_seed

hkdf_expand

sha256

rand_nonce_32

DEK

aes_gcm

rand_nonce_12