1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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 */
|