# KMS v2 crypto changes
### Unchanged
```mermaid
stateDiagram-v2
KEK
note right of KEK
accessed via plugin
end note
KEK --> DEK: encrypts
DEK --> etcd: EDEK stored
```
### Current KMS v2
```mermaid
stateDiagram-v2
resource %% https://github.com/kubernetes/kubernetes/pull/86124#issuecomment-564596094
note right of resource
stored as
nonce|encrypted_dek|ciphertext
end note
etcd_path
note left of etcd_path
unique per object in etcd
/PATH_PREFIX/secrets/NAMESPACE/NAME
end note
DEK --> aes_gcm
counter_nonce_8 --> nonce_12
rand_nonce_4 --> nonce_12
nonce_12 --> aes_gcm
etcd_path --> aes_gcm: additional_data
aes_gcm --> resource: encrypts
```
### 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.
```mermaid
stateDiagram-v2
etcd_path
note left of etcd_path
unique per object in etcd
/PATH_PREFIX/secrets/NAMESPACE/NAME
end note
resource
note right of resource
stored as
info|nonce|encrypted_seed|ciphertext
end note
DEK_seed --> hkdf_expand: pseudo random key
sha256 --> hkdf_expand: hash
rand_nonce_32 --> hkdf_expand: info param
hkdf_expand --> DEK: generates
DEK --> aes_gcm: key
rand_nonce_12 --> aes_gcm: nonce
etcd_path --> aes_gcm: additional_data
aes_gcm --> resource: encrypts
```