Whamcloud - gitweb
LU-16138 kernel: preserve RHEL8.x server kABI for block integrity
[fs/lustre-release.git] / lustre / utils / gss / sk_utils.h
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (C) 2015, Trustees of Indiana University
24  *
25  * Author: Jeremy Filizetti <jfilizet@iu.edu>
26  */
27
28 #ifndef SK_UTILS_H
29 #define SK_UTILS_H
30
31 #ifdef HAVE_OPENSSL_SSK
32 #include <gssapi/gssapi.h>
33 #ifdef HAVE_LIBKEYUTILS
34 #include <keyutils.h>
35 #endif
36 #include <linux/lustre/lustre_idl.h>
37 #include <openssl/dh.h>
38 #include <openssl/evp.h>
39 #include <openssl/hmac.h>
40 #ifdef HAVE_OPENSSL_EVP_PKEY
41 #include <openssl/core_names.h>
42 #endif
43 #include <openssl/err.h>
44 #include <sys/types.h>
45
46 #include <libcfs/libcfs_crypto.h>
47 #include "lsupport.h"
48
49 #ifndef ARRAY_SIZE
50 # define ARRAY_SIZE(a) ((sizeof(a)) / (sizeof((a)[0])))
51 #endif /* !ARRAY_SIZE */
52
53 /* LL_CRYPTO_MAX_NAME value must match value of
54  * CRYPTO_MAX_ALG_NAME in include/linux/crypto.h
55  */
56 #ifdef HAVE_CRYPTO_MAX_ALG_NAME_128
57 #define LL_CRYPTO_MAX_NAME 128
58 #else
59 #define LL_CRYPTO_MAX_NAME 64
60 #endif
61
62 #if OPENSSL_VERSION_NUMBER < 0x10100000L
63 static inline HMAC_CTX *HMAC_CTX_new(void)
64 {
65         HMAC_CTX *ctx = OPENSSL_malloc(sizeof(*ctx));
66
67         if (ctx != NULL)
68                 HMAC_CTX_init(ctx);
69         return ctx;
70 }
71
72 static inline void HMAC_CTX_free(HMAC_CTX *ctx)
73 {
74         if (ctx != NULL) {
75                 HMAC_CTX_cleanup(ctx);
76                 OPENSSL_cleanse(ctx, sizeof(*ctx));
77                 OPENSSL_free(ctx);
78         }
79 }
80 static inline void DH_get0_pqg(const DH *dh,
81                                const BIGNUM **p, const BIGNUM **q,
82                                const BIGNUM **g)
83 {
84         if (p != NULL)
85                 *p = dh->p;
86         if (q != NULL)
87                 *q = dh->q;
88         if (g != NULL)
89                 *g = dh->g;
90 }
91
92 static inline int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
93 {
94         /* If the fields p and g in dh are NULL, the corresponding input
95          * parameters MUST be non-NULL.  q may remain NULL.
96          */
97         if ((dh->p == NULL && p == NULL)
98             || (dh->g == NULL && g == NULL))
99                 return 0;
100
101         if (p != NULL) {
102                 BN_free(dh->p);
103                 dh->p = p;
104         }
105         if (q != NULL) {
106                 BN_free(dh->q);
107                 dh->q = q;
108         }
109         if (g != NULL) {
110                 BN_free(dh->g);
111                 dh->g = g;
112         }
113
114         if (q != NULL)
115                 dh->length = BN_num_bits(q);
116
117         return 1;
118 }
119
120 static inline void DH_get0_key(const DH *dh, const BIGNUM **pub_key,
121                                const BIGNUM **priv_key)
122 {
123         if (pub_key != NULL)
124                 *pub_key = dh->pub_key;
125         if (priv_key != NULL)
126                 *priv_key = dh->priv_key;
127 }
128
129 static inline const BIGNUM *DH_get0_p(const DH *dh)
130 {
131         return dh->p;
132 }
133 #endif
134
135 /* Some limits and defaults */
136 #define SK_CONF_VERSION 1
137 #define SK_MSG_VERSION 1
138 #define SK_GENERATOR 2
139 #define SK_SESSION_MAX_KEYLEN_BYTES 1024
140 #define SK_MAX_KEYLEN_BYTES 128
141 #define SK_MAX_P_BYTES 2048
142 #define SK_NONCE_SIZE 4
143 #define MAX_MGSNIDS 16
144
145 enum sk_ctx_init_buffers {
146         /* Initiator netstring buffer ordering */
147         SK_INIT_VERSION = 0,
148         SK_INIT_RANDOM  = 1,
149         SK_INIT_P       = 2,
150         SK_INIT_PUB_KEY = 3,
151         SK_INIT_TARGET  = 4,
152         SK_INIT_NODEMAP = 5,
153         SK_INIT_FLAGS   = 6,
154         SK_INIT_HMAC    = 7,
155         SK_INIT_BUFFERS = 8,
156
157         /* Responder netstring buffer ordering */
158         SK_RESP_VERSION = 0,
159         SK_RESP_RANDOM  = 1,
160         SK_RESP_PUB_KEY = 2,
161         SK_RESP_HMAC    = 3,
162         SK_RESP_BUFFERS = 4,
163 };
164
165 /* String consisting of "lustre:fsname:nodemap_hash" */
166 #define SK_DESCRIPTION_SIZE (9 + MTI_NAME_MAXLEN + LUSTRE_NODEMAP_NAME_LENGTH)
167
168 enum sk_key_type {
169         SK_TYPE_INVALID = 0x0,
170         SK_TYPE_CLIENT  = 0x1,
171         SK_TYPE_SERVER  = 0x2,
172         SK_TYPE_MGS     = 0x4,
173 };
174
175 /* This is the packed structure format of key files that are distributed.
176  * The on disk format should be store in big-endian. */
177 struct sk_keyfile_config {
178         /* File format version */
179         uint32_t        skc_version;
180         /* HMAC algorithm used for message integrity */
181         uint16_t        skc_hmac_alg;
182         /* Crypt algorithm used for privacy mode */
183         uint16_t        skc_crypt_alg;
184         /* Number of seconds that a context is valid after it is created from
185          * this keyfile */
186         uint32_t        skc_expire;
187         /* Length of shared key in skc_shared_key */
188         uint32_t        skc_shared_keylen;
189         /* Length of the prime used in the DHKE */
190         uint32_t        skc_prime_bits;
191         /* Key type */
192         uint8_t         skc_type;
193         /* Array of MGS NIDs to load key's for.  This is for the client since
194          * the upcall only knows the target name which is MGC<IP>@<NET>
195          * Only needed when mounting with mgssec */
196         lnet_nid_t      skc_mgsnids[MAX_MGSNIDS];
197         /* File system name for this key.  It can be unused for MGS only keys */
198         char            skc_fsname[MTI_NAME_MAXLEN + 1];
199         /* Nodemap name for this key.  Used by the server side to verify the
200          * client is in the correct nodemap */
201         char            skc_nodemap[LUSTRE_NODEMAP_NAME_LENGTH + 1];
202         /* Shared key */
203         unsigned char   skc_shared_key[SK_MAX_KEYLEN_BYTES];
204         /* Prime (p) for DHKE */
205         unsigned char   skc_p[SK_MAX_P_BYTES];
206 } __attribute__((packed));
207
208 /* Format passed to the kernel from userspace */
209 struct sk_kernel_ctx {
210         uint32_t        skc_version;
211         char            skc_hmac_alg[LL_CRYPTO_MAX_NAME];
212         char            skc_crypt_alg[LL_CRYPTO_MAX_NAME];
213         uint32_t        skc_expire;
214         uint32_t        skc_host_random;
215         uint32_t        skc_peer_random;
216         gss_buffer_desc skc_hmac_key;
217         gss_buffer_desc skc_encrypt_key;
218         gss_buffer_desc skc_shared_key;
219         gss_buffer_desc skc_session_key;
220 };
221
222
223 #ifdef HAVE_OPENSSL_EVP_PKEY
224 #define DECLARE_EVP_MD(name, hash)                                      \
225         OSSL_PARAM name[] = {                                           \
226                 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, \
227                                                (char *)EVP_MD_get0_name(hash), \
228                                                0),                      \
229                 OSSL_PARAM_END                                          \
230         }
231 #else /* !HAVE_OPENSSL_EVP_PKEY */
232 #define EVP_PKEY DH
233 #define EVP_PKEY_free(dh) DH_free(dh)
234 struct dh_ssk_ctx { uint32_t bits; uint32_t gen; };
235 #define EVP_PKEY_CTX struct dh_ssk_ctx
236 #define EVP_PKEY_CTX_new_from_name(p1, name, p2) malloc(sizeof(EVP_PKEY_CTX))
237 #define EVP_PKEY_paramgen_init(ctx) 1
238 #undef EVP_PKEY_CTX_set_dh_paramgen_prime_len
239 #define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) ((ctx)->bits = len)
240 #undef EVP_PKEY_CTX_set_dh_paramgen_generator
241 #define EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, g) ((ctx)->gen = g)
242 #define EVP_PKEY_paramgen(ctx, dhp)                                     \
243         ((*dhp = DH_new()) &&                                           \
244          DH_generate_parameters_ex(*(dhp), (ctx)->bits, (ctx)->gen, NULL))
245 #define EVP_PKEY_get_bn_param(dh, param, bnp) (*bnp = (BIGNUM *)DH_get0_p(dh))
246 #define EVP_PKEY_CTX_free(ctx) free(ctx)
247 #define DECLARE_EVP_MD(name, hash)      \
248         const EVP_MD *name = hash
249 #define EVP_MAC_CTX HMAC_CTX
250 #define EVP_MAC_CTX_new(mac) HMAC_CTX_new()
251 #define EVP_MAC_CTX_free HMAC_CTX_free
252 #define EVP_MAC void
253 #define EVP_MAC_fetch(a, b, c) (void *)1
254 #define EVP_MAC_init(ctx, val, len, alg) HMAC_Init_ex(ctx, val, len, alg, NULL)
255 #define EVP_MAC_update HMAC_Update
256 #define EVP_MAC_final(ctx, val, lenp, hlen)             \
257         HMAC_Final(ctx, val, (unsigned int *)(lenp))
258 #define EVP_MAC_free(mac) {}
259 #endif
260
261 /* Structure used in context initiation to hold all necessary data */
262 struct sk_cred {
263         uint32_t                 sc_flags;
264         gss_buffer_desc          sc_p;
265         gss_buffer_desc          sc_pub_key;
266         gss_buffer_desc          sc_tgt;
267         gss_buffer_desc          sc_nodemap_hash;
268         gss_buffer_desc          sc_hmac;
269         gss_buffer_desc          sc_dh_shared_key;
270         struct sk_kernel_ctx     sc_kctx;
271         EVP_PKEY *sc_params;
272 };
273
274 /* Names match up with openssl enc and dgst commands */
275 /* When adding new alg types, make sure first occurrence's name
276  * matches cht_name in hash_types array.
277  */
278 static const struct sk_crypt_type sk_crypt_algs[] = {
279         {
280                 .sct_name = "null",
281                 .sct_type = SK_CRYPT_EMPTY
282         },
283         {
284                 .sct_name = "NONE",
285                 .sct_type = SK_CRYPT_EMPTY
286         },
287         {
288                 .sct_name = "ctr(aes)",
289                 .sct_type = SK_CRYPT_AES256_CTR
290         },
291         {
292                 .sct_name = "AES-256-CTR",
293                 .sct_type = SK_CRYPT_AES256_CTR
294         }
295 };
296 static const struct sk_hmac_type sk_hmac_algs[] = {
297         {
298                 .sht_name = "null",
299                 .sht_type = SK_HMAC_EMPTY
300         },
301         {
302                 .sht_name = "NONE",
303                 .sht_type = SK_HMAC_EMPTY
304         },
305         {
306                 .sht_name = "sha256",
307                 .sht_type = SK_HMAC_SHA256
308         },
309         {
310                 .sht_name = "SHA256",
311                 .sht_type = SK_HMAC_SHA256
312         },
313         {
314                 .sht_name = "sha512",
315                 .sht_type = SK_HMAC_SHA512
316         },
317         {
318                 .sht_name = "SHA512",
319                 .sht_type = SK_HMAC_SHA512
320         }
321 };
322
323 static inline int sk_name2crypt(char *name)
324 {
325         int i;
326
327         for (i = 0; i < ARRAY_SIZE(sk_crypt_algs); i++) {
328                 if (strcasecmp(name, sk_crypt_algs[i].sct_name) == 0)
329                         return sk_crypt_algs[i].sct_type;
330         }
331
332         return SK_CRYPT_INVALID;
333 }
334
335 static inline int sk_name2hmac(char *name)
336 {
337         int i;
338
339         for (i = 0; i < ARRAY_SIZE(sk_hmac_algs); i++) {
340                 if (strcasecmp(name, sk_hmac_algs[i].sht_name) == 0)
341                         return sk_hmac_algs[i].sht_type;
342         }
343
344         return SK_HMAC_INVALID;
345 }
346
347 static inline const char *sk_crypt2name(enum sk_crypt_alg type)
348 {
349         int i;
350
351         for (i = 0; i < ARRAY_SIZE(sk_crypt_algs); i++) {
352                 if (type == sk_crypt_algs[i].sct_type)
353                         return sk_crypt_algs[i].sct_name;
354         }
355
356         return NULL;
357 }
358
359 static inline const char *sk_hmac2name(enum sk_hmac_alg type)
360 {
361         int i;
362
363         for (i = 0; i < ARRAY_SIZE(sk_hmac_algs); i++) {
364                 if (type == sk_hmac_algs[i].sht_type)
365                         return sk_hmac_algs[i].sht_name;
366         }
367
368         return NULL;
369 }
370
371 void sk_init_logging(char *program, int verbose, int fg);
372 struct sk_keyfile_config *sk_read_file(char *filename);
373 int sk_load_keyfile(char *path);
374 void sk_config_disk_to_cpu(struct sk_keyfile_config *config);
375 void sk_config_cpu_to_disk(struct sk_keyfile_config *config);
376 int sk_validate_config(const struct sk_keyfile_config *config);
377 uint32_t sk_verify_hash(const char *string, const EVP_MD *hash_alg,
378                         const gss_buffer_desc *current_hash);
379 struct sk_cred *sk_create_cred(const char *fsname, const char *cluster,
380                                const uint32_t flags);
381 #ifndef HAVE_OPENSSL_EVP_PKEY
382 int sk_speedtest_dh_valid(unsigned int usec_check_max);
383 #endif
384 uint32_t sk_gen_params(struct sk_cred *skc, int num_rounds);
385 int sk_sign_bufs(gss_buffer_desc *key, gss_buffer_desc *bufs, const int numbufs,
386                  const EVP_MD *hash_alg, gss_buffer_desc *hmac);
387 uint32_t sk_verify_hmac(struct sk_cred *skc, gss_buffer_desc *bufs,
388                         const int numbufs, const EVP_MD *hash_alg,
389                         gss_buffer_desc *hmac);
390 void sk_free_cred(struct sk_cred *skc);
391 int sk_session_kdf(struct sk_cred *skc, lnet_nid_t client_nid,
392                    gss_buffer_desc *client_token, gss_buffer_desc *server_token);
393 uint32_t sk_compute_dh_key(struct sk_cred *skc, const gss_buffer_desc *pub_key);
394 int sk_compute_keys(struct sk_cred *skc);
395 int sk_serialize_kctx(struct sk_cred *skc, gss_buffer_desc *ctx_token);
396 int sk_decode_netstring(gss_buffer_desc *bufs, int numbufs,
397                         gss_buffer_desc *ns);
398 int sk_encode_netstring(gss_buffer_desc *bufs, int numbufs,
399                         gss_buffer_desc *ns);
400
401 #endif /* HAVE_OPENSSL_SSK */
402 #endif /* SK_UTILS_H */