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 : #define SP800_108_CTR_HMAC "SP800_108_CTR_HMAC"
41 :
42 : enum KdfSp800_108Param {
43 : KDF_PARAM_SHA1,
44 : KDF_PARAM_SHA256,
45 : KDF_PARAM_SHA384,
46 : KDF_PARAM_SHA512,
47 : };
48 :
49 : struct KdfAlgorithm {
50 : union {
51 : enum KdfSp800_108Param sp800_108;
52 : } param;
53 : enum KdfAlgorithmId id;
54 : };
55 :
56 : enum {
57 : root_key_version_1 = 1,
58 : };
59 :
60 : struct ProvRootKey {
61 : struct GUID id;
62 : DATA_BLOB data;
63 : NTTIME create_time;
64 : NTTIME use_start_time;
65 : const char *domain_id;
66 : struct KdfAlgorithm kdf_algorithm;
67 : int32_t version;
68 : };
69 :
70 : NTSTATUS ProvRootKey(TALLOC_CTX *mem_ctx,
71 : const struct GUID root_key_id,
72 : const int32_t version,
73 : const DATA_BLOB root_key_data,
74 : const NTTIME create_time,
75 : const NTTIME use_start_time,
76 : const char *const domain_id,
77 : const struct KdfAlgorithm kdf_algorithm,
78 : const struct ProvRootKey **const root_key_out);
79 :
80 : struct Gkid {
81 : int32_t l0_idx;
82 : int8_t l1_idx; /* [range(0, 31)] */
83 : int8_t l2_idx; /* [range(0, 31)] */
84 : };
85 :
86 : enum GkidType {
87 : GKID_DEFAULT = -1,
88 : GKID_L0_SEED_KEY = 0,
89 : GKID_L1_SEED_KEY = 1,
90 : GKID_L2_SEED_KEY = 2,
91 : };
92 :
93 : /*
94 : * Construct a GKID. The caller must check the returned GKID is valid before
95 : * using it!
96 : */
97 211 : static inline struct Gkid Gkid(int32_t l0_idx, int8_t l1_idx, int8_t l2_idx)
98 : {
99 210 : return (struct Gkid){l0_idx, l1_idx, l2_idx};
100 : }
101 :
102 : static const struct Gkid invalid_gkid = {
103 : INT32_MIN,
104 : INT8_MIN,
105 : INT8_MIN,
106 : };
107 :
108 : static const uint32_t key_envelope_magic = 0x4b53444b; /* ‘KDSK’ */
109 :
110 : struct KeyEnvelopeId {
111 : struct GUID root_key_id;
112 : struct Gkid gkid;
113 : };
114 :
115 : struct KeyEnvelope;
116 : NTSTATUS gkdi_pull_KeyEnvelope(TALLOC_CTX *mem_ctx,
117 : const DATA_BLOB *pwd_id_blob,
118 : struct KeyEnvelope *pwd_id_out);
119 :
120 : const struct KeyEnvelopeId *gkdi_pull_KeyEnvelopeId(
121 : const DATA_BLOB key_env,
122 : struct KeyEnvelopeId *key_env_out);
123 :
124 : enum GkidType gkid_key_type(const struct Gkid gkid);
125 :
126 : bool gkid_is_valid(const struct Gkid gkid);
127 :
128 : static const int gkdi_l1_key_iteration = 32;
129 : static const int gkdi_l2_key_iteration = 32;
130 :
131 : static const int64_t gkdi_key_cycle_duration = 360000000000; /* ten hours */
132 : static const int64_t gkdi_max_clock_skew = 3000000000; /* five minutes */
133 :
134 : #define GKDI_KEY_LEN 64
135 :
136 : struct Gkid gkdi_get_interval_id(const NTTIME time);
137 :
138 : bool gkdi_get_key_start_time(const struct Gkid gkid, NTTIME *start_time_out);
139 :
140 : NTTIME gkdi_get_interval_start_time(const NTTIME time);
141 :
142 : bool gkid_less_than_or_equal_to(const struct Gkid g1, const struct Gkid g2);
143 :
144 : bool gkdi_rollover_interval(const int64_t managed_password_interval,
145 : NTTIME *result);
146 :
147 : gnutls_mac_algorithm_t get_sp800_108_mac_algorithm(
148 : const struct KdfAlgorithm kdf_algorithm);
149 :
150 : NTSTATUS compute_seed_key(TALLOC_CTX *mem_ctx,
151 : const DATA_BLOB target_security_descriptor,
152 : const struct ProvRootKey *const root_key,
153 : const struct Gkid gkid,
154 : uint8_t out[static const GKDI_KEY_LEN]);
155 :
156 : NTSTATUS kdf_sp_800_108_from_params(
157 : const DATA_BLOB *const kdf_param,
158 : struct KdfAlgorithm *const kdf_algorithm_out);
159 :
160 : NTSTATUS kdf_algorithm_from_params(
161 : const char *const kdf_algorithm_id,
162 : const DATA_BLOB *const kdf_param,
163 : struct KdfAlgorithm *const kdf_algorithm_out);
164 :
165 : #endif /* LIB_CRYPTO_GKDI_H */
|