summaryrefslogtreecommitdiffstats
path: root/lib/crypto/gnutls_helpers.h
blob: 0362d5ee78220b1e6fe8ee34f98f42e7bd5583bb (plain)
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
/*
 * Copyright (c) 2019      Andreas Schneider <asn@samba.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _GNUTLS_HELPERS_H
#define _GNUTLS_HELPERS_H

#include <gnutls/gnutls.h>

#include "libcli/util/ntstatus.h"
#include "libcli/util/werror.h"
#include "lib/util/data_blob.h"

/* Those macros are only available in GnuTLS >= 3.6.4 */
#ifndef GNUTLS_FIPS140_SET_LAX_MODE
#define GNUTLS_FIPS140_SET_LAX_MODE()
#endif

#ifndef GNUTLS_FIPS140_SET_STRICT_MODE
#define GNUTLS_FIPS140_SET_STRICT_MODE()
#endif

#ifdef DOXYGEN
/**
 * @brief Convert a gnutls error code to a corresponding NTSTATUS.
 *
 * @param[in]  gnutls_rc      The GnuTLS return code.
 *
 * @param[in]  blocked_status The NTSTATUS return code which should be returned
 *                            in case the e.g. the cipher might be blocked due
 *                            to FIPS mode.
 *
 * @return A corresponding NTSTATUS code.
 */
NTSTATUS gnutls_error_to_ntstatus(int gnutls_rc, NTSTATUS blocked_status);
#else
NTSTATUS _gnutls_error_to_ntstatus(int gnutls_rc,
				   NTSTATUS blocked_status,
				   const char *function,
				   const char *location);
#define gnutls_error_to_ntstatus(gnutls_rc, blocked_status) \
	_gnutls_error_to_ntstatus(gnutls_rc,                \
				  blocked_status,           \
				  __FUNCTION__,             \
				  __location__)
#endif

#ifdef DOXYGEN
/**
 * @brief Convert a gnutls error code to a corresponding WERROR.
 *
 * @param[in]  gnutls_rc      The GnuTLS return code.
 *
 * @param[in]  blocked_werr   The WERROR code which should be returned if e.g
 *                            the cipher we want to used it not allowed to be
 *                            used because of FIPS mode.
 *
 * @return A corresponding WERROR code.
 */
WERROR gnutls_error_to_werror(int gnutls_rc, WERROR blocked_werr);
#else
WERROR _gnutls_error_to_werror(int gnutls_rc,
			       WERROR blocked_werr,
			       const char *function,
			       const char *location);
#define gnutls_error_to_werror(gnutls_rc, blocked_werr) \
	_gnutls_error_to_werror(gnutls_rc,              \
				blocked_werr,           \
				__FUNCTION__,           \
				__location__)
#endif

enum samba_gnutls_direction { SAMBA_GNUTLS_ENCRYPT, SAMBA_GNUTLS_DECRYPT };

/**
 * @brief Encrypt or decrypt a data blob using RC4 with a key and salt.
 *
 * One of the key input should be a session key and the other a confounder
 * (aka salt). Which one depends on the implementation details of the
 * protocol.
 *
 * @param[in]  key_input1 Either a session_key or a confounder.
 *
 * @param[in]  key_input2 Either a session_key or a confounder.
 *
 * @param[in]  data       The data blob to either encrypt or decrypt. The data
 *                        will be encrypted or decrypted in place.
 *
 * @param[in]  encrypt    The encryption direction.
 *
 * @return A gnutls error code.
 */
int samba_gnutls_arcfour_confounded_md5(const DATA_BLOB *key_input1,
					const DATA_BLOB *key_input2,
					DATA_BLOB *data,
					enum samba_gnutls_direction encrypt);

/**
 * @brief Encrypted a secret plaintext using AEAD_AES_256_CBC_HMAC_SHA512 and
 * the session key.
 *
 * This encrypts a secret plaintext using AEAD_AES_256_CBC_HMAC_SHA512 with a
 * key (can be the session key or PBKDF2 password). This is used in SAMR and
 * LSA.
 *
 * @param mem_ctx       The memory context to allocate the cipher text pointer.
 *
 * @param plaintext     The secret to encrypt
 *
 * @param cek           The content encryption key to encrypt the secret.
 *
 * @param key_salt      The salt used to calculate the encryption key.
 *
 * @param key_salt      The salt used to calculate the mac key.

 * @param iv            The initialization vector used for the encryption.
 *
 * @param pciphertext   A pointer to store the cipher text.
 *
 * @param pauth_tag[64] An array to store the auth tag.
 *
 * @return NT_STATUS_OK on success, an nt status error code otherwise.
 */
NTSTATUS
samba_gnutls_aead_aes_256_cbc_hmac_sha512_encrypt(TALLOC_CTX *mem_ctx,
						  const DATA_BLOB *plaintext,
						  const DATA_BLOB *cek,
						  const DATA_BLOB *key_salt,
						  const DATA_BLOB *mac_salt,
						  const DATA_BLOB *iv,
						  DATA_BLOB *pciphertext,
						  uint8_t pauth_tag[64]);

/**
 * @brief Decypt cipher text using AEAD_AES_256_CBC_HMAC_SHA512 and the session
 * key.
 *
 * This decrypts the cipher text using AEAD_AES_256_CBC_HMAC_SHA512 with the
 * given content decryption key key. The plaintext will be zeroed as soon as the
 * data blob is freed.
 *
 * @param mem_ctx       The memory context to allocate the plaintext on.
 *
 * @param ciphertext    The cipher text to decrypt.
 *
 * @param cdk           The content decryption key.
 *
 * @param key_salt      The salt used to calculate the encryption key.
 *
 * @param key_salt      The salt used to calculate the mac key.

 * @param iv            The initialization vector used for the encryption.
 *
 * @param auth_tag[64]  The authentication blob to be verified.
 *
 * @param pplaintext    A pointer to a DATA_BLOB to store the plaintext.
 *
 * @return NT_STATUS_OK on success, an nt status error code otherwise.
 */
NTSTATUS
samba_gnutls_aead_aes_256_cbc_hmac_sha512_decrypt(TALLOC_CTX *mem_ctx,
						  const DATA_BLOB *ciphertext,
						  const DATA_BLOB *cdk,
						  const DATA_BLOB *key_salt,
						  const DATA_BLOB *mac_salt,
						  const DATA_BLOB *iv,
						  const uint8_t auth_tag[64],
						  DATA_BLOB *pplaintext);

/**
 * @brief Check if weak crypto is allowed.
 *
 * @return true if weak crypo is allowed, false otherwise.
 */
bool samba_gnutls_weak_crypto_allowed(void);

/**
 * @brief Derive a key using the NIST SP 800‐108 algorithm.
 *
 * The details of the algorithm can be found at
 * https://csrc.nist.gov/pubs/sp/800/108/r1/final.
 *
 * @param KI            The key‐derivation key used as input.
 *
 * @param KI_len        The length of the key‐derivation key.
 *
 * @param FixedData     If non‐NULL, specifies fixed data to be used in place of
 *                      that constructed from the Label and Context parameters.
 *
 * @param FixedData_len The length of the fixed data, if it is present.
 *
 * @param Label         A label that identifies the purpose for the derived key.
 *                      Ignored if FixedData is non‐NULL.
 *
 * @param Label_len     The length of the label.
 *
 * @param Context       Information related to the derived key. Ignored if
 *                      FixedData is non‐NULL.
 *
 * @param Context_len   The length of the context data.
 *
 * @param algorithm     The HMAC algorithm to use.
 *
 * @param KO            A buffer to receive the derived key.
 *
 * @param KO_len        The length of the key to be derived.
 *
 * @return NT_STATUS_OK on success, an NT status error code otherwise.
 */
NTSTATUS samba_gnutls_sp800_108_derive_key(
	const uint8_t *KI,
	size_t KI_len,
	const uint8_t *FixedData,
	size_t FixedData_len,
	const uint8_t *Label,
	size_t Label_len,
	const uint8_t *Context,
	size_t Context_len,
	const gnutls_mac_algorithm_t algorithm,
	uint8_t *KO,
	size_t KO_len);

#endif /* _GNUTLS_HELPERS_H */