libroach: add data key manager#21150
Conversation
6e07dc7 to
7a3436b
Compare
7a3436b to
14ee156
Compare
c-deps/libroach/ccl/key_manager.cc
Outdated
| key->key = contents; | ||
| key->source = path; | ||
| key->set_key(contents); | ||
| info->set_key_id(KeyHash(contents)); |
There was a problem hiding this comment.
this is iffy. The key IDs are meant to be stored in the clear in the file registry. Using plain hashes makes it too easy to do lookup table attacks against key hashes.
We have some options here, some simpler than others:
- use the first 256 bits of the hash for the ID, the number of needed bytes after that for the key. We would need to switch to SHA-512 (not much of an issue).
- use salts per key. We only have two key IDs to check against anyway. Where the key ID is either the ciphertext of the salt encrypted with the key (key check value) or the key run through a KDF (probably not needed as we don't need to add enthropy)
- require key files to be
<key ID length> + <key length>and use the first<key ID length>bytes as a key ID. We can shrink to 64bit key IDs (256 is overkill). Would this be odd? Since the near future should have support for things other than files, it may be acceptable for now.
For the data keys, we don't need to match duplicate keys so we can simply generate a random ID as well. We need to decide if we care to check for duplicates. In the unlikely chance that it happens (we're screwed anyway as we probably have a weak prng) we'll lose the previous key with the same ID.
1c80304 to
1e8aeed
Compare
|
Reviewed 26 of 32 files at r1, 6 of 6 files at r2. c-deps/libroach/ccl/key_manager.cc, line 61 at r1 (raw file): Previously, mberhault (marc) wrote…
Lookup tables aren't really a concern here - you can't enumerate all possible keys to build one. Still, exposing a hash of our keys seems like something best avoided.
For data keys, we should just generate random IDs instead of hashing the value. There's no reason that the id be derivable from the value. Use 128 bits (or a uuid, which throws away 6 bits but is still plenty of entropy) and don't worry about checking for duplicates. For store keys, is the assumption that the filenames will change on every key rotation, or that new keys will be swapped in to the current filenames? If the former, I think the key id should probably be a combination of the filename and a truncated (32 bit?) hash of the key value (the hash would be enough to detect mistakes in which the key was modified without renaming, without providing a useful amount of information about the key even if there were some other problem with exposing the hash). If the filenames are expected to be reused, we'll probably want to either use a hash of the key value or ask the user for something we can use as a key. I think the latter is probably better; I expect that key management tools are likely to use some form of explicit key identifier instead of a hash of the value. pkg/ccl/storageccl/engineccl/enginepbccl/key_registry.proto, line 17 at r2 (raw file):
Don't repeat this here; it'll just rot. (or move the whole thing here; see comment below) pkg/ccl/storageccl/engineccl/enginepbccl/key_registry.proto, line 28 at r2 (raw file):
What is the key for this map and the following one? A copy of KeyInfo.key_id? pkg/storage/engine/enginepb/file_registry.proto, line 32 at r2 (raw file):
Putting these constants in OSS isn't great. There's obviously not any real IP concerns here but I think it would be cleaner if they lived on the CCL side (even if that meant the Comments from Reviewable |
|
Review status: all files reviewed at latest revision, 4 unresolved discussions, all commit checks successful. c-deps/libroach/ccl/key_manager.cc, line 61 at r1 (raw file): Previously, bdarnell (Ben Darnell) wrote…
surprisingly, 1. is pretty common (often to derive encryption and hmac keys from a single key). 2. would be a randomly-generated salt stored in plaintext alongside the ID. It would either be combined ala KDF, or encrypted using the key. This would only be there to prevent hash lookups. I'm using "salt" for lack of a better name. 3. has the issue we were talking about: people may be surprised by having to provide 24 bytes for a 128 bit key. Data keys I've already moved over to a random ID (no reason not to) and am ignoring duplicates. We have absolutely no control over what people will use for filenames. Additionally, if we want to allow signal-based store key reload, we can't change the filename without having a layer of indirection (we threw away the custom file a while back). I'm happy with a hash for now, although I'm also happy asking for extra bits. pkg/ccl/storageccl/engineccl/enginepbccl/key_registry.proto, line 17 at r2 (raw file): Previously, bdarnell (Ben Darnell) wrote…
True. Let's decide where we want it. pkg/ccl/storageccl/engineccl/enginepbccl/key_registry.proto, line 28 at r2 (raw file): Previously, bdarnell (Ben Darnell) wrote…
Yup. It's a bit redundant, but not a huge deal. We never modify a key ID, and having it in the pkg/storage/engine/enginepb/file_registry.proto, line 32 at r2 (raw file): Previously, bdarnell (Ben Darnell) wrote…
I could make them more oblivious, but at some point I'll need encryption info in there as well (IV/counter). I would prefer not to have to use serialized protos for that (or Comments from Reviewable |
|
Review status: all files reviewed at latest revision, 4 unresolved discussions, all commit checks successful. c-deps/libroach/ccl/key_manager.cc, line 61 at r1 (raw file): Previously, mberhault (marc) wrote…
OK, let's ask for extra bits for now. We can revisit once we start looking at other key management systems. pkg/ccl/storageccl/engineccl/enginepbccl/key_registry.proto, line 28 at r2 (raw file): Previously, mberhault (marc) wrote…
I'm fine with the redundancy. I was basically asking for a comment to be added about the keys. pkg/storage/engine/enginepb/file_registry.proto, line 32 at r2 (raw file): Previously, mberhault (marc) wrote…
Hmm. My preference would still be to try to keep everything knowledgeable about crypto details on the CCL side, but I don't feel strongly about proto definition stuff. Comments from Reviewable |
1e8aeed to
6c7825a
Compare
|
Review status: 12 of 27 files reviewed at latest revision, 4 unresolved discussions, some commit checks pending. c-deps/libroach/ccl/key_manager.cc, line 61 at r1 (raw file): Previously, bdarnell (Ben Darnell) wrote…
Done. I'm using 32 bytes for key IDs. If I use shorter (8 or 16), the user may provide 24 bytes but end up with AES-128. 32 (AES-256 key size) makes that impossible (unless they think there's such a thing as AES-512, but then we can't help them). pkg/ccl/storageccl/engineccl/enginepbccl/key_registry.proto, line 17 at r2 (raw file): Previously, mberhault (marc) wrote…
Done. pkg/ccl/storageccl/engineccl/enginepbccl/key_registry.proto, line 28 at r2 (raw file): Previously, bdarnell (Ben Darnell) wrote…
Done. Sorry about that. Added clarifying comments. pkg/storage/engine/enginepb/file_registry.proto, line 32 at r2 (raw file): Previously, bdarnell (Ben Darnell) wrote…
Done. Moved to CCL. We can move it back later if needed. Comments from Reviewable |
b06f6a8 to
1fd516a
Compare
|
Review status: 10 of 27 files reviewed at latest revision, 4 unresolved discussions, all commit checks successful. c-deps/libroach/ccl/key_manager.cc, line 61 at r1 (raw file): Previously, mberhault (marc) wrote…
We shouldn't have key ids just concatenated with the keys if we're also going to infer key length from file size. This seems too confusing and error prone. (and 32 byte ids are kind of ridiculous) I think we should include the desired cipher and key size in the command line flag that gives the key file path. Comments from Reviewable |
|
Review status: 10 of 27 files reviewed at latest revision, 4 unresolved discussions, all commit checks successful. c-deps/libroach/ccl/key_manager.cc, line 61 at r1 (raw file): Previously, bdarnell (Ben Darnell) wrote…
I agree they're a bit ridiculous, but we can do that length just for store keys, not much of a hardship. The confusion is the main concern. The RFC explored different ways of specifying the encryption settings. If you'll recall we decided that inferring the desired AES key size from the store key size was easiest. I'm happy going back to key sha to avoid confusion, but this is starting to feel like something we just need to decide and live with. Ultimately, I'm hoping that third-party KMS support will mean the plain-file key manager will be mostly irrelevant (I may regret those words one day). Comments from Reviewable |
|
Review status: 10 of 27 files reviewed at latest revision, 4 unresolved discussions, all commit checks successful. c-deps/libroach/ccl/key_manager.cc, line 61 at r1 (raw file): Previously, mberhault (marc) wrote…
OK, let's leave it for now. Allowing plenty of room for the key id will also allow for non-random IDs if someone wants to manage things that way for some reason. Comments from Reviewable |
|
Reviewed 5 of 32 files at r1, 2 of 2 files at r3, 12 of 13 files at r4, 3 of 3 files at r5. c-deps/libroach/testutils.h, line 52 at r5 (raw file):
Why do you need both literal match and regex? What if I pass a string that fails to compile as a regex? I'd prefer to make this regex-only, and if you need exact matching make it a separate macro/function. Comments from Reviewable |
e508746 to
0ec4422
Compare
|
Review status: 24 of 27 files reviewed at latest revision, 5 unresolved discussions. c-deps/libroach/testutils.h, line 52 at r5 (raw file): Previously, bdarnell (Ben Darnell) wrote…
I initially put both to avoid having to escape parentheses (eg: c-deps/libroach/ccl/key_manager.cc, line 61 at r1 (raw file): Previously, bdarnell (Ben Darnell) wrote…
Done. Comments from Reviewable |
Release note: None Part of encryption at rest: see cockroachdb#19783 The data key manager persists its keys in a local file and generates a new key when the active store key has changed or if the current key is too old. Reworked the key storage to distinguish actual keys (SecretKey) from just the key information (KeyInfo). The KeyInfo should be passed most of the time, with `CurrentKey` and `GetKey` possibly going away in favor of a `SetKeyForCipher` method in the future.
0ec4422 to
f544e00
Compare
Release note: None
Part of encryption at rest: see #19783
The data key manager persists its keys in a local file and generates a
new key when the active store key has changed or if the current key is
too old.
Reworked the key storage to distinguish actual keys (SecretKey) from
just the key information (KeyInfo). The KeyInfo should be passed most of
the time, with
CurrentKeyandGetKeypossibly going away in favor ofa
SetKeyForCiphermethod in the future.