Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : Group Key Distribution Protocol functions
4 :
5 : Copyright (C) Catalyst.Net Ltd 2023
6 :
7 : This program is free software: you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation, either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program. If not, see <https://www.gnu.org/licenses/>.
19 : */
20 :
21 : #ifndef LIB_CRYPTO_GKDI_H
22 : #define LIB_CRYPTO_GKDI_H
23 :
24 : #include <stdint.h>
25 :
26 : #include <gnutls/gnutls.h>
27 :
28 : #include "lib/util/data_blob.h"
29 :
30 : #include "libcli/util/ntstatus.h"
31 :
32 : #include "librpc/gen_ndr/misc.h"
33 : #include "lib/util/time.h"
34 : #include "talloc.h"
35 :
36 : enum KdfAlgorithmId {
37 : KDF_ALGORITHM_SP800_108_CTR_HMAC,
38 : };
39 :
40 : enum KdfSp800_108Param {
41 : KDF_PARAM_SHA1,
42 : KDF_PARAM_SHA256,
43 : KDF_PARAM_SHA384,
44 : KDF_PARAM_SHA512,
45 : };
46 :
47 : struct KdfAlgorithm {
48 : union {
49 : enum KdfSp800_108Param sp800_108;
50 : } param;
51 : enum KdfAlgorithmId id;
52 : };
53 :
54 : enum {
55 : root_key_version_1 = 1,
56 : };
57 :
58 : struct ProvRootKey {
59 : struct GUID id;
60 : DATA_BLOB data;
61 : NTTIME create_time;
62 : NTTIME use_start_time;
63 : const char *domain_id;
64 : struct KdfAlgorithm kdf_algorithm;
65 : int32_t version;
66 : };
67 :
68 : NTSTATUS ProvRootKey(TALLOC_CTX *mem_ctx,
69 : const struct GUID root_key_id,
70 : const int32_t version,
71 : const DATA_BLOB root_key_data,
72 : const NTTIME create_time,
73 : const NTTIME use_start_time,
74 : const char *const domain_id,
75 : const struct KdfAlgorithm kdf_algorithm,
76 : const struct ProvRootKey **const root_key_out);
77 :
78 : struct Gkid {
79 : int32_t l0_idx;
80 : int8_t l1_idx; /* [range(0, 31)] */
81 : int8_t l2_idx; /* [range(0, 31)] */
82 : };
83 :
84 : enum GkidType {
85 : GKID_DEFAULT = -1,
86 : GKID_L0_SEED_KEY = 0,
87 : GKID_L1_SEED_KEY = 1,
88 : GKID_L2_SEED_KEY = 2,
89 : };
90 :
91 : /*
92 : * Construct a GKID. The caller must check the returned GKID is valid before
93 : * using it!
94 : */
95 1 : static inline struct Gkid Gkid(int32_t l0_idx, int8_t l1_idx, int8_t l2_idx)
96 : {
97 0 : return (struct Gkid){l0_idx, l1_idx, l2_idx};
98 : }
99 :
100 : static const struct Gkid invalid_gkid = {
101 : INT32_MIN,
102 : INT8_MIN,
103 : INT8_MIN,
104 : };
105 :
106 : static const uint32_t key_envelope_magic = 0x4b53444b; /* ‘KDSK’ */
107 :
108 : struct KeyEnvelopeId {
109 : struct GUID root_key_id;
110 : struct Gkid gkid;
111 : };
112 :
113 : struct KeyEnvelope;
114 : NTSTATUS gkdi_pull_KeyEnvelope(TALLOC_CTX *mem_ctx,
115 : const DATA_BLOB *pwd_id_blob,
116 : struct KeyEnvelope *pwd_id_out);
117 :
118 : const struct KeyEnvelopeId *gkdi_pull_KeyEnvelopeId(
119 : const DATA_BLOB key_env,
120 : struct KeyEnvelopeId *key_env_out);
121 :
122 : enum GkidType gkid_key_type(const struct Gkid gkid);
123 :
124 : bool gkid_is_valid(const struct Gkid gkid);
125 :
126 : static const int gkdi_l1_key_iteration = 32;
127 : static const int gkdi_l2_key_iteration = 32;
128 :
129 : static const int64_t gkdi_key_cycle_duration = 360000000000; /* ten hours */
130 : static const int64_t gkdi_max_clock_skew = 3000000000; /* five minutes */
131 :
132 : #define GKDI_KEY_LEN 64
133 :
134 : struct Gkid gkdi_get_interval_id(const NTTIME time);
135 :
136 : NTTIME gkdi_get_key_start_time(const struct Gkid gkid);
137 :
138 : NTTIME gkdi_get_interval_start_time(const NTTIME time);
139 :
140 : bool gkid_less_than_or_equal_to(const struct Gkid g1, const struct Gkid g2);
141 :
142 : bool gkdi_rollover_interval(const int64_t managed_password_interval,
143 : NTTIME *result);
144 :
145 : gnutls_mac_algorithm_t get_sp800_108_mac_algorithm(
146 : const struct KdfAlgorithm kdf_algorithm);
147 :
148 : NTSTATUS compute_seed_key(TALLOC_CTX *mem_ctx,
149 : const DATA_BLOB target_security_descriptor,
150 : const struct ProvRootKey *const root_key,
151 : const struct Gkid gkid,
152 : uint8_t out[static const GKDI_KEY_LEN]);
153 :
154 : NTSTATUS kdf_sp_800_108_from_params(
155 : const DATA_BLOB *const kdf_param,
156 : struct KdfAlgorithm *const kdf_algorithm_out);
157 :
158 : NTSTATUS kdf_algorithm_from_params(
159 : const char *const kdf_algorithm_id,
160 : const DATA_BLOB *const kdf_param,
161 : struct KdfAlgorithm *const kdf_algorithm_out);
162 :
163 : #endif /* LIB_CRYPTO_GKDI_H */
|