From c7cf29768731deee7864c1084ff8b8c6be379867 Mon Sep 17 00:00:00 2001 From: Sebastien Buisson Date: Fri, 27 Sep 2024 09:48:44 +0200 Subject: [PATCH] LU-18256 gss: deprecate insecure enctypes A number of encryption types declared in the GSS code are deprecated for security reasons, and should not be used. So remove support for them in the Lustre code: - des-cbc-crc - des-cbc-md4 - des-cbc-md5 - des-cbc-raw - des-hmac-sha1 - des3-cbc-sha - des3-cbc-raw - des3-cbc-sha1 - arcfour-hmac - arcfour-hmac-exp Test-Parameters: trivial Test-Parameters: testgroup=review-dne-selinux-ssk-part-1 Test-Parameters: testgroup=review-dne-selinux-ssk-part-2 Test-Parameters: kerberos=true testlist=sanity-krb5 Signed-off-by: Sebastien Buisson Change-Id: Ic8dd2470339323be88a416796c8d420ecd2f55e4 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/56512 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Aurelien Degremont Reviewed-by: Oleg Drokin --- lustre/autoconf/kerberos5.m4 | 11 --- lustre/ptlrpc/gss/gss_krb5.h | 21 +++-- lustre/ptlrpc/gss/gss_krb5_mech.c | 165 +++++--------------------------------- lustre/utils/gss/context_lucid.c | 67 +++++----------- lustre/utils/gss/lgss_utils.h | 8 ++ 5 files changed, 59 insertions(+), 213 deletions(-) diff --git a/lustre/autoconf/kerberos5.m4 b/lustre/autoconf/kerberos5.m4 index bf53d0f..dbe7ba0 100644 --- a/lustre/autoconf/kerberos5.m4 +++ b/lustre/autoconf/kerberos5.m4 @@ -130,17 +130,6 @@ krb5int_derive_key and krb5_derive_key functions! ]) ]) - dnl Version 1.18 removed support for all DES3 enctypes (des3-cbc-raw, - dnl des3-hmac-sha1, des3-cbc-sha1-kd). - AC_MSG_CHECKING([for DES3 enctype support by krb5]) - if test $K5VERS -lt 1180; then - AC_DEFINE(HAVE_DES3_SUPPORT, 1, - [DES3 enctype is supported by krb5]) - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - fi - dnl If they specified a directory and it didn't work, give them a warning if test "x$krb5_with" != "x" -a "$krb5_with" != "$KRBDIR"; then AC_MSG_WARN([ diff --git a/lustre/ptlrpc/gss/gss_krb5.h b/lustre/ptlrpc/gss/gss_krb5.h index 42827dd..ca53750 100644 --- a/lustre/ptlrpc/gss/gss_krb5.h +++ b/lustre/ptlrpc/gss/gss_krb5.h @@ -142,21 +142,20 @@ enum seal_alg { * these get mapped to linux kernel crypto routines. */ #define ENCTYPE_NULL 0x0000 -#define ENCTYPE_DES_CBC_CRC 0x0001 /* DES cbc mode with CRC-32 */ -#define ENCTYPE_DES_CBC_MD4 0x0002 /* DES cbc mode with RSA-MD4 */ -#define ENCTYPE_DES_CBC_MD5 0x0003 /* DES cbc mode with RSA-MD5 */ -#define ENCTYPE_DES_CBC_RAW 0x0004 /* DES cbc mode raw */ -/* XXX deprecated? */ -#define ENCTYPE_DES3_CBC_SHA 0x0005 /* DES-3 cbc mode with NIST-SHA */ -#define ENCTYPE_DES3_CBC_RAW 0x0006 /* DES-3 cbc mode raw */ -#define ENCTYPE_DES_HMAC_SHA1 0x0008 -#define ENCTYPE_DES3_CBC_SHA1 0x0010 +/* deprecated ENCTYPE_DES_CBC_CRC 0x0001 DES cbc mode with CRC-32 */ +/* deprecated ENCTYPE_DES_CBC_MD4 0x0002 DES cbc mode with RSA-MD4 */ +/* deprecated ENCTYPE_DES_CBC_MD5 0x0003 DES cbc mode with RSA-MD5 */ +/* deprecated ENCTYPE_DES_CBC_RAW 0x0004 DES cbc mode raw */ +/* deprecated ENCTYPE_DES3_CBC_SHA 0x0005 DES-3 cbc mode with NIST-SHA */ +/* deprecated ENCTYPE_DES3_CBC_RAW 0x0006 DES-3 cbc mode raw */ +/* deprecated ENCTYPE_DES_HMAC_SHA1 0x0008 des-hmac-sha1 */ +/* deprecated ENCTYPE_DES3_CBC_SHA1 0x0010 des3-cbc-sha1 */ #define ENCTYPE_AES128_CTS_HMAC_SHA1_96 0x0011 #define ENCTYPE_AES256_CTS_HMAC_SHA1_96 0x0012 #define ENCTYPE_AES128_CTS_HMAC_SHA256_128 0x0013 #define ENCTYPE_AES256_CTS_HMAC_SHA384_192 0x0014 -#define ENCTYPE_ARCFOUR_HMAC 0x0017 -#define ENCTYPE_ARCFOUR_HMAC_EXP 0x0018 +/* deprecated ENCTYPE_ARCFOUR_HMAC 0x0017 arcfour-hmac-md5 */ +/* deprecated ENCTYPE_ARCFOUR_HMAC_EXP 0x0018 arcfour-hmac-exp */ #define ENCTYPE_UNKNOWN 0x01ff #endif /* PTLRPC_GSS_KRB5_H */ diff --git a/lustre/ptlrpc/gss/gss_krb5_mech.c b/lustre/ptlrpc/gss/gss_krb5_mech.c index 332810c..17aab2a 100644 --- a/lustre/ptlrpc/gss/gss_krb5_mech.c +++ b/lustre/ptlrpc/gss/gss_krb5_mech.c @@ -88,23 +88,6 @@ struct krb5_enctype { * yet. this need to be fixed in the future. */ static struct krb5_enctype enctypes[] = { - [ENCTYPE_DES_CBC_RAW] = { /* des-cbc-md5 */ - .ke_dispname = "des-cbc-md5", - .ke_enc_name = "cbc(des)", - .ke_hash_name = "md5", - .ke_hash_size = 16, - .ke_conf_size = 8, - }, -#ifdef HAVE_DES3_SUPPORT - [ENCTYPE_DES3_CBC_RAW] = { /* des3-hmac-sha1 */ - .ke_dispname = "des3-hmac-sha1", - .ke_enc_name = "cbc(des3_ede)", - .ke_hash_name = "sha1", - .ke_hash_size = 20, - .ke_conf_size = 8, - .ke_hash_hmac = 1, - }, -#endif [ENCTYPE_AES128_CTS_HMAC_SHA1_96] = { /* aes128-cts */ .ke_dispname = "aes128-cts-hmac-sha1-96", .ke_enc_name = "cbc(aes)", @@ -137,14 +120,6 @@ static struct krb5_enctype enctypes[] = { .ke_conf_size = 16, .ke_hash_hmac = 1, }, - [ENCTYPE_ARCFOUR_HMAC] = { /* arcfour-hmac-md5 */ - .ke_dispname = "arcfour-hmac-md5", - .ke_enc_name = "ecb(arc4)", - .ke_hash_name = "md5", - .ke_hash_size = 16, - .ke_conf_size = 8, - .ke_hash_hmac = 1, - } }; static const char * enctype2str(__u32 enctype) @@ -168,9 +143,7 @@ int krb5_init_keys(struct krb5_ctx *kctx) ke = &enctypes[kctx->kc_enctype]; - /* tfm arc4 is stateful, user should alloc-use-free by his own */ - if (kctx->kc_enctype != ENCTYPE_ARCFOUR_HMAC && - gss_keyblock_init(&kctx->kc_keye, ke->ke_enc_name, ke->ke_enc_mode)) + if (gss_keyblock_init(&kctx->kc_keye, ke->ke_enc_name, ke->ke_enc_mode)) return -1; /* tfm hmac is stateful, user should alloc-use-free by his own */ @@ -1026,16 +999,11 @@ __u32 gss_wrap_kerberos(struct gss_ctx *gctx, /* generate confounder */ get_random_bytes(conf, ke->ke_conf_size); - /* get encryption blocksize. note kc_keye might not associated with - * a tfm, currently only for arcfour-hmac */ - if (kctx->kc_enctype == ENCTYPE_ARCFOUR_HMAC) { - LASSERT(kctx->kc_keye.kb_tfm == NULL); - blocksize = 1; - } else { - LASSERT(kctx->kc_keye.kb_tfm); - blocksize = crypto_sync_skcipher_blocksize( - kctx->kc_keye.kb_tfm); - } + /* Get encryption blocksize. Note kc_keye might be associated with + * a tfm. + */ + LASSERT(kctx->kc_keye.kb_tfm); + blocksize = crypto_sync_skcipher_blocksize(kctx->kc_keye.kb_tfm); LASSERT(blocksize <= ke->ke_conf_size); /* padding the message */ @@ -1080,41 +1048,8 @@ __u32 gss_wrap_kerberos(struct gss_ctx *gctx, cipher.len = token->len - sizeof(*khdr); LASSERT(cipher.len >= ke->ke_conf_size + msg->len + sizeof(*khdr)); - if (kctx->kc_enctype == ENCTYPE_ARCFOUR_HMAC) { - rawobj_t arc4_keye = RAWOBJ_EMPTY; - struct crypto_sync_skcipher *arc4_tfm; - - if (krb5_make_checksum(ENCTYPE_ARCFOUR_HMAC, &kctx->kc_keyi, - NULL, 1, &cksum, 0, NULL, &arc4_keye, - gctx->hash_func)) { - CERROR("failed to obtain arc4 enc key\n"); - GOTO(arc4_out_key, rc = -EACCES); - } - - arc4_tfm = crypto_alloc_sync_skcipher("ecb(arc4)", 0, 0); - if (IS_ERR(arc4_tfm)) { - CERROR("failed to alloc tfm arc4 in ECB mode\n"); - GOTO(arc4_out_key, rc = -EACCES); - } - - if (crypto_sync_skcipher_setkey(arc4_tfm, arc4_keye.data, - arc4_keye.len)) { - CERROR("failed to set arc4 key, len %d\n", - arc4_keye.len); - GOTO(arc4_out_tfm, rc = -EACCES); - } - - rc = gss_crypt_rawobjs(arc4_tfm, NULL, 3, data_desc, - &cipher, 1); -arc4_out_tfm: - crypto_free_sync_skcipher(arc4_tfm); -arc4_out_key: - rawobj_free(&arc4_keye); - } else { - rc = gss_crypt_rawobjs(kctx->kc_keye.kb_tfm, local_iv, 3, - data_desc, &cipher, 1); - } - + rc = gss_crypt_rawobjs(kctx->kc_keye.kb_tfm, local_iv, 3, + data_desc, &cipher, 1); if (rc) GOTO(out_free_cksum, major = GSS_S_FAILURE); @@ -1200,15 +1135,11 @@ __u32 gss_wrap_bulk_kerberos(struct gss_ctx *gctx, /* generate confounder */ get_random_bytes(conf, ke->ke_conf_size); - /* get encryption blocksize. note kc_keye might not associated with - * a tfm, currently only for arcfour-hmac */ - if (kctx->kc_enctype == ENCTYPE_ARCFOUR_HMAC) { - LASSERT(kctx->kc_keye.kb_tfm == NULL); - blocksz = 1; - } else { - LASSERT(kctx->kc_keye.kb_tfm); - blocksz = crypto_sync_skcipher_blocksize(kctx->kc_keye.kb_tfm); - } + /* Get encryption blocksize. Note kc_keye might be associated with + * a tfm. + */ + LASSERT(kctx->kc_keye.kb_tfm); + blocksz = crypto_sync_skcipher_blocksize(kctx->kc_keye.kb_tfm); /* * we assume the size of krb5_header (16 bytes) must be n * blocksize. @@ -1254,13 +1185,8 @@ __u32 gss_wrap_bulk_kerberos(struct gss_ctx *gctx, cipher.data = (__u8 *)(khdr + 1); cipher.len = blocksz + sizeof(*khdr); - if (kctx->kc_enctype == ENCTYPE_ARCFOUR_HMAC) { - LBUG(); - rc = 0; - } else { - rc = krb5_encrypt_bulk(kctx->kc_keye.kb_tfm, khdr, - conf, desc, &cipher, adj_nob); - } + rc = krb5_encrypt_bulk(kctx->kc_keye.kb_tfm, khdr, + conf, desc, &cipher, adj_nob); if (rc) GOTO(out_free_cksum, major = GSS_S_FAILURE); @@ -1312,13 +1238,8 @@ __u32 gss_unwrap_kerberos(struct gss_ctx *gctx, } /* block size */ - if (kctx->kc_enctype == ENCTYPE_ARCFOUR_HMAC) { - LASSERT(kctx->kc_keye.kb_tfm == NULL); - blocksz = 1; - } else { - LASSERT(kctx->kc_keye.kb_tfm); - blocksz = crypto_sync_skcipher_blocksize(kctx->kc_keye.kb_tfm); - } + LASSERT(kctx->kc_keye.kb_tfm); + blocksz = crypto_sync_skcipher_blocksize(kctx->kc_keye.kb_tfm); /* expected token layout: * ---------------------------------------- @@ -1355,46 +1276,8 @@ __u32 gss_unwrap_kerberos(struct gss_ctx *gctx, plain_out.data = tmpbuf; plain_out.len = bodysize; - if (kctx->kc_enctype == ENCTYPE_ARCFOUR_HMAC) { - rawobj_t arc4_keye; - struct crypto_sync_skcipher *arc4_tfm; - - cksum.data = token->data + token->len - ke->ke_hash_size; - cksum.len = ke->ke_hash_size; - - if (krb5_make_checksum(ENCTYPE_ARCFOUR_HMAC, &kctx->kc_keyi, - NULL, 1, &cksum, 0, NULL, &arc4_keye, - gctx->hash_func)) { - CERROR("failed to obtain arc4 enc key\n"); - GOTO(arc4_out, rc = -EACCES); - } - - arc4_tfm = crypto_alloc_sync_skcipher("ecb(arc4)", 0, 0); - if (IS_ERR(arc4_tfm)) { - CERROR("failed to alloc tfm arc4 in ECB mode\n"); - GOTO(arc4_out_key, rc = -EACCES); - } - - if (crypto_sync_skcipher_setkey(arc4_tfm, arc4_keye.data, - arc4_keye.len)) { - CERROR("failed to set arc4 key, len %d\n", - arc4_keye.len); - GOTO(arc4_out_tfm, rc = -EACCES); - } - - rc = gss_crypt_rawobjs(arc4_tfm, NULL, 1, &cipher_in, - &plain_out, 0); -arc4_out_tfm: - crypto_free_sync_skcipher(arc4_tfm); -arc4_out_key: - rawobj_free(&arc4_keye); -arc4_out: - cksum = RAWOBJ_EMPTY; - } else { - rc = gss_crypt_rawobjs(kctx->kc_keye.kb_tfm, local_iv, 1, - &cipher_in, &plain_out, 0); - } - + rc = gss_crypt_rawobjs(kctx->kc_keye.kb_tfm, local_iv, 1, + &cipher_in, &plain_out, 0); if (rc != 0) { CERROR("error decrypt\n"); goto out_free; @@ -1479,14 +1362,8 @@ __u32 gss_unwrap_bulk_kerberos(struct gss_ctx *gctx, } /* block size */ - if (kctx->kc_enctype == ENCTYPE_ARCFOUR_HMAC) { - LASSERT(kctx->kc_keye.kb_tfm == NULL); - blocksz = 1; - LBUG(); - } else { - LASSERT(kctx->kc_keye.kb_tfm); - blocksz = crypto_sync_skcipher_blocksize(kctx->kc_keye.kb_tfm); - } + LASSERT(kctx->kc_keye.kb_tfm); + blocksz = crypto_sync_skcipher_blocksize(kctx->kc_keye.kb_tfm); LASSERT(sizeof(*khdr) >= blocksz && sizeof(*khdr) % blocksz == 0); /* diff --git a/lustre/utils/gss/context_lucid.c b/lustre/utils/gss/context_lucid.c index 9c78ddd..e87db9b 100644 --- a/lustre/utils/gss/context_lucid.c +++ b/lustre/utils/gss/context_lucid.c @@ -194,10 +194,6 @@ enum seal_alg { * We don't have "legal" access to these MIT-only * structures located in libk5crypto */ -extern void *krb5int_enc_arcfour; -#ifdef HAVE_DES3_SUPPORT -extern void *krb5int_enc_des3; -#endif extern void *krb5int_enc_aes128; extern void *krb5int_enc_aes256; @@ -276,17 +272,6 @@ derive_key_lucid(const gss_krb5_lucid_key_t *in, gss_krb5_lucid_key_t *out, * values and structures located in libk5crypto */ switch (in->type) { -#ifdef HAVE_DES3_SUPPORT - case ENCTYPE_DES3_CBC_SHA1: -#ifdef HAVE_KRB5 - case ENCTYPE_DES3_CBC_RAW: -#endif - keylength = 24; -#ifdef HAVE_KRB5 - enc = &krb5int_enc_des3; -#endif - break; -#endif case ENCTYPE_AES128_CTS_HMAC_SHA1_96: case ENCTYPE_AES128_CTS_HMAC_SHA256_128: keylength = 16; @@ -301,6 +286,20 @@ derive_key_lucid(const gss_krb5_lucid_key_t *in, gss_krb5_lucid_key_t *out, enc = &krb5int_enc_aes256; #endif break; + case ENCTYPE_DES_CBC_CRC: + case ENCTYPE_DES_CBC_MD4: + case ENCTYPE_DES_CBC_MD5: + case ENCTYPE_DES_CBC_RAW: + case ENCTYPE_DES3_CBC_SHA: + case ENCTYPE_DES3_CBC_RAW: + case ENCTYPE_DES_HMAC_SHA1: + case ENCTYPE_DES3_CBC_SHA1: + case ENCTYPE_ARCFOUR_HMAC: + case ENCTYPE_ARCFOUR_HMAC_EXP: + /* deprecated enc types */ + printerr(0, "ERROR: %s: deprecated enc type %d\n", + __func__, in->type); + fallthrough; default: code = KRB5_BAD_ENCTYPE; goto out; @@ -440,19 +439,6 @@ prepare_krb5_rfc4121_buffer(gss_krb5_lucid_context_v1_t *lctx, printerr(3, "protocol %d\n", lctx->protocol); if (lctx->protocol == 0) { enctype = lctx->rfc1964_kd.ctx_key.type; -#ifdef HAVE_HEIMDAL - /* - * The kernel gss code expects ENCTYPE_DES3_CBC_RAW (6) for - * 3des keys, but Heimdal key has ENCTYPE_DES3_CBC_SHA1 (16). - * Force the Heimdal enctype to 6. - */ - if (enctype == ENCTYPE_DES3_CBC_SHA1) { - printerr(2, "%s: overriding heimdal keytype (%d => %d)\n", - __FUNCTION__, enctype, 6); - - enctype = 6; - } -#endif keysize = lctx->rfc1964_kd.ctx_key.length; numkeys = 3; /* XXX is always gonna be three? */ } else { @@ -484,25 +470,12 @@ prepare_krb5_rfc4121_buffer(gss_krb5_lucid_context_v1_t *lctx, goto out_err; /* Kc */ - /* - * RC4 is special, it dosen't need key derivation. Actually - * the Ke is based on plain text. Here we just let all three - * key identical, kernel will handle everything. --ericm - */ - if (lctx->rfc1964_kd.ctx_key.type == ENCTYPE_ARCFOUR_HMAC) { - if (write_bytes(&p, end, lctx->rfc1964_kd.ctx_key.data, - lctx->rfc1964_kd.ctx_key.length)) - goto out_err; - } else { - if (derive_key_lucid(&lctx->rfc1964_kd.ctx_key, - &derived_key, - KG_USAGE_SIGN, KEY_USAGE_SEED_CHECKSUM)) - goto out_err; - if (write_bytes(&p, end, derived_key.data, - derived_key.length)) - goto out_err; - free(derived_key.data); - } + if (derive_key_lucid(&lctx->rfc1964_kd.ctx_key, &derived_key, + KG_USAGE_SIGN, KEY_USAGE_SEED_CHECKSUM)) + goto out_err; + if (write_bytes(&p, end, derived_key.data, derived_key.length)) + goto out_err; + free(derived_key.data); } else { gss_krb5_lucid_key_t *keyptr; uint32_t sign_usage, seal_usage; diff --git a/lustre/utils/gss/lgss_utils.h b/lustre/utils/gss/lgss_utils.h index 86f3aca..0ba1589 100644 --- a/lustre/utils/gss/lgss_utils.h +++ b/lustre/utils/gss/lgss_utils.h @@ -192,4 +192,12 @@ int gss_OID_equal(gss_OID_desc *oid1, gss_OID_desc *oid2) #define g_OID_equal(o1,o2) gss_OID_equal((o1), (o2)) #endif +#ifndef fallthrough +# if defined(__GNUC__) && __GNUC__ >= 7 +# define fallthrough __attribute__((fallthrough)) /* fallthrough */ +# else +# define fallthrough do {} while (0) /* fallthrough */ +# endif +#endif + #endif /* LGSS_UTILS_H */ -- 1.8.3.1