aboutsummaryrefslogtreecommitdiff
path: root/src/include/common/kmgr_utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/common/kmgr_utils.h')
-rw-r--r--src/include/common/kmgr_utils.h98
1 files changed, 98 insertions, 0 deletions
diff --git a/src/include/common/kmgr_utils.h b/src/include/common/kmgr_utils.h
new file mode 100644
index 00000000000..23124a7fc60
--- /dev/null
+++ b/src/include/common/kmgr_utils.h
@@ -0,0 +1,98 @@
+/*-------------------------------------------------------------------------
+ *
+ * kmgr_utils.h
+ * Declarations for utility function for file encryption key
+ *
+ * Portions Copyright (c) 2020, PostgreSQL Global Development Group
+ *
+ * src/include/common/kmgr_utils.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef KMGR_UTILS_H
+#define KMGR_UTILS_H
+
+#include "common/cipher.h"
+
+/* Current version number */
+#define KMGR_VERSION 1
+
+/*
+ * Directories where cluster file encryption keys reside within PGDATA.
+ */
+#define KMGR_DIR "pg_cryptokeys"
+#define KMGR_DIR_PID KMGR_DIR"/pg_alterckey.pid"
+#define LIVE_KMGR_DIR KMGR_DIR"/live"
+/* used during cluster key rotation */
+#define NEW_KMGR_DIR KMGR_DIR"/new"
+#define OLD_KMGR_DIR KMGR_DIR"/old"
+
+/* CryptoKey file name is keys id */
+#define CryptoKeyFilePath(path, dir, id) \
+ snprintf((path), MAXPGPATH, "%s/%d", (dir), (id))
+
+/*
+ * Identifiers of internal keys.
+ */
+#define KMGR_KEY_ID_REL 0
+#define KMGR_KEY_ID_WAL 1
+#define KMGR_MAX_INTERNAL_KEYS 2
+
+/* We always, today, use a 256-bit AES key. */
+#define KMGR_CLUSTER_KEY_LEN PG_AES256_KEY_LEN
+
+/* double for hex format, plus some for spaces, \r,\n, and null byte */
+#define ALLOC_KMGR_CLUSTER_KEY_LEN (KMGR_CLUSTER_KEY_LEN * 2 + 10 + 2 + 1)
+
+/* Maximum length of key the key manager can store */
+#define KMGR_MAX_KEY_LEN 256
+#define KMGR_MAX_KEY_LEN_BYTES KMGR_MAX_KEY_LEN / 8
+#define KMGR_MAX_WRAPPED_KEY_LEN KmgrSizeOfCipherText(KMGR_MAX_KEY_LEN)
+
+
+/*
+ * Cryptographic key data structure.
+ *
+ * This is the structure we use to write out the encrypted keys.
+ *
+ * pgkey_id is the identifier for this key (should be same as the
+ * file name and be one of KMGR_KEY_ID_* from above). This is what
+ * we consider our 'context' or 'fixed' portion of the deterministic
+ * IV we create.
+ *
+ * counter is updated each time we use the cluster KEK to encrypt a
+ * new key. This is our the 'invocation' field of the deterministic
+ * IV we create.
+ *
+ * Absolutely essential when using GCM (or CTR) is that the IV is unique,
+ * for a given key, but a deterministic IV such as this is perfectly
+ * acceptable and encouraged. If (and only if!) the KEK is changed to a
+ * new key, then we can re-initialize the counter.
+ *
+ * Detailed discussion of deterministic IV creation can be found here:
+ *
+ * https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
+ *
+ * tag is the GCM tag which is produced and must be validated in order
+ * to be able to trust the results of our decryption.
+ *
+ * encrypted_key is the encrypted key length (as an int) + encrypted key.
+ */
+typedef struct CryptoKey
+{
+ uint64 pgkey_id; /* Upper half of IV */
+ uint64 counter; /* Lower half of IV */
+ uint128 tag; /* GCM tag */
+ unsigned char encrypted_key[sizeof(int) + KMGR_MAX_KEY_LEN_BYTES];
+} CryptoKey;
+
+extern bool kmgr_wrap_key(PgCipherCtx *ctx, CryptoKey *in, CryptoKey *out);
+extern bool kmgr_unwrap_key(PgCipherCtx *ctx, CryptoKey *in, CryptoKey *out);
+extern bool kmgr_verify_cluster_key(unsigned char *cluster_key,
+ CryptoKey *in_keys, CryptoKey *out_keys,
+ int nkey);
+extern int kmgr_run_cluster_key_command(char *cluster_key_command,
+ char *buf, int size, char *dir);
+extern CryptoKey *kmgr_get_cryptokeys(const char *path, int *nkeys);
+
+#endif /* KMGR_UTILS_H */