18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * linux/net/sunrpc/gss_krb5_mech.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2001-2008 The Regents of the University of Michigan. 68c2ecf20Sopenharmony_ci * All rights reserved. 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * Andy Adamson <andros@umich.edu> 98c2ecf20Sopenharmony_ci * J. Bruce Fields <bfields@umich.edu> 108c2ecf20Sopenharmony_ci */ 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <crypto/hash.h> 138c2ecf20Sopenharmony_ci#include <crypto/skcipher.h> 148c2ecf20Sopenharmony_ci#include <linux/err.h> 158c2ecf20Sopenharmony_ci#include <linux/module.h> 168c2ecf20Sopenharmony_ci#include <linux/init.h> 178c2ecf20Sopenharmony_ci#include <linux/types.h> 188c2ecf20Sopenharmony_ci#include <linux/slab.h> 198c2ecf20Sopenharmony_ci#include <linux/sunrpc/auth.h> 208c2ecf20Sopenharmony_ci#include <linux/sunrpc/gss_krb5.h> 218c2ecf20Sopenharmony_ci#include <linux/sunrpc/xdr.h> 228c2ecf20Sopenharmony_ci#include <linux/sunrpc/gss_krb5_enctypes.h> 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#include "auth_gss_internal.h" 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) 278c2ecf20Sopenharmony_ci# define RPCDBG_FACILITY RPCDBG_AUTH 288c2ecf20Sopenharmony_ci#endif 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_cistatic struct gss_api_mech gss_kerberos_mech; 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_cistatic int gss_krb5_import_ctx_des(struct krb5_ctx *ctx, gfp_t gfp_mask); 338c2ecf20Sopenharmony_cistatic int gss_krb5_import_ctx_v1(struct krb5_ctx *ctx, gfp_t gfp_mask); 348c2ecf20Sopenharmony_cistatic int gss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask); 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_cistatic const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { 378c2ecf20Sopenharmony_ci#ifndef CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES 388c2ecf20Sopenharmony_ci /* 398c2ecf20Sopenharmony_ci * DES (All DES enctypes are mapped to the same gss functionality) 408c2ecf20Sopenharmony_ci */ 418c2ecf20Sopenharmony_ci { 428c2ecf20Sopenharmony_ci .etype = ENCTYPE_DES_CBC_RAW, 438c2ecf20Sopenharmony_ci .ctype = CKSUMTYPE_RSA_MD5, 448c2ecf20Sopenharmony_ci .name = "des-cbc-crc", 458c2ecf20Sopenharmony_ci .encrypt_name = "cbc(des)", 468c2ecf20Sopenharmony_ci .cksum_name = "md5", 478c2ecf20Sopenharmony_ci .encrypt = krb5_encrypt, 488c2ecf20Sopenharmony_ci .decrypt = krb5_decrypt, 498c2ecf20Sopenharmony_ci .import_ctx = gss_krb5_import_ctx_des, 508c2ecf20Sopenharmony_ci .mk_key = NULL, 518c2ecf20Sopenharmony_ci .signalg = SGN_ALG_DES_MAC_MD5, 528c2ecf20Sopenharmony_ci .sealalg = SEAL_ALG_DES, 538c2ecf20Sopenharmony_ci .keybytes = 7, 548c2ecf20Sopenharmony_ci .keylength = 8, 558c2ecf20Sopenharmony_ci .blocksize = 8, 568c2ecf20Sopenharmony_ci .conflen = 8, 578c2ecf20Sopenharmony_ci .cksumlength = 8, 588c2ecf20Sopenharmony_ci .keyed_cksum = 0, 598c2ecf20Sopenharmony_ci }, 608c2ecf20Sopenharmony_ci#endif /* CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES */ 618c2ecf20Sopenharmony_ci /* 628c2ecf20Sopenharmony_ci * 3DES 638c2ecf20Sopenharmony_ci */ 648c2ecf20Sopenharmony_ci { 658c2ecf20Sopenharmony_ci .etype = ENCTYPE_DES3_CBC_RAW, 668c2ecf20Sopenharmony_ci .ctype = CKSUMTYPE_HMAC_SHA1_DES3, 678c2ecf20Sopenharmony_ci .name = "des3-hmac-sha1", 688c2ecf20Sopenharmony_ci .encrypt_name = "cbc(des3_ede)", 698c2ecf20Sopenharmony_ci .cksum_name = "hmac(sha1)", 708c2ecf20Sopenharmony_ci .encrypt = krb5_encrypt, 718c2ecf20Sopenharmony_ci .decrypt = krb5_decrypt, 728c2ecf20Sopenharmony_ci .import_ctx = gss_krb5_import_ctx_v1, 738c2ecf20Sopenharmony_ci .mk_key = gss_krb5_des3_make_key, 748c2ecf20Sopenharmony_ci .signalg = SGN_ALG_HMAC_SHA1_DES3_KD, 758c2ecf20Sopenharmony_ci .sealalg = SEAL_ALG_DES3KD, 768c2ecf20Sopenharmony_ci .keybytes = 21, 778c2ecf20Sopenharmony_ci .keylength = 24, 788c2ecf20Sopenharmony_ci .blocksize = 8, 798c2ecf20Sopenharmony_ci .conflen = 8, 808c2ecf20Sopenharmony_ci .cksumlength = 20, 818c2ecf20Sopenharmony_ci .keyed_cksum = 1, 828c2ecf20Sopenharmony_ci }, 838c2ecf20Sopenharmony_ci /* 848c2ecf20Sopenharmony_ci * AES128 858c2ecf20Sopenharmony_ci */ 868c2ecf20Sopenharmony_ci { 878c2ecf20Sopenharmony_ci .etype = ENCTYPE_AES128_CTS_HMAC_SHA1_96, 888c2ecf20Sopenharmony_ci .ctype = CKSUMTYPE_HMAC_SHA1_96_AES128, 898c2ecf20Sopenharmony_ci .name = "aes128-cts", 908c2ecf20Sopenharmony_ci .encrypt_name = "cts(cbc(aes))", 918c2ecf20Sopenharmony_ci .cksum_name = "hmac(sha1)", 928c2ecf20Sopenharmony_ci .encrypt = krb5_encrypt, 938c2ecf20Sopenharmony_ci .decrypt = krb5_decrypt, 948c2ecf20Sopenharmony_ci .import_ctx = gss_krb5_import_ctx_v2, 958c2ecf20Sopenharmony_ci .mk_key = gss_krb5_aes_make_key, 968c2ecf20Sopenharmony_ci .encrypt_v2 = gss_krb5_aes_encrypt, 978c2ecf20Sopenharmony_ci .decrypt_v2 = gss_krb5_aes_decrypt, 988c2ecf20Sopenharmony_ci .signalg = -1, 998c2ecf20Sopenharmony_ci .sealalg = -1, 1008c2ecf20Sopenharmony_ci .keybytes = 16, 1018c2ecf20Sopenharmony_ci .keylength = 16, 1028c2ecf20Sopenharmony_ci .blocksize = 16, 1038c2ecf20Sopenharmony_ci .conflen = 16, 1048c2ecf20Sopenharmony_ci .cksumlength = 12, 1058c2ecf20Sopenharmony_ci .keyed_cksum = 1, 1068c2ecf20Sopenharmony_ci }, 1078c2ecf20Sopenharmony_ci /* 1088c2ecf20Sopenharmony_ci * AES256 1098c2ecf20Sopenharmony_ci */ 1108c2ecf20Sopenharmony_ci { 1118c2ecf20Sopenharmony_ci .etype = ENCTYPE_AES256_CTS_HMAC_SHA1_96, 1128c2ecf20Sopenharmony_ci .ctype = CKSUMTYPE_HMAC_SHA1_96_AES256, 1138c2ecf20Sopenharmony_ci .name = "aes256-cts", 1148c2ecf20Sopenharmony_ci .encrypt_name = "cts(cbc(aes))", 1158c2ecf20Sopenharmony_ci .cksum_name = "hmac(sha1)", 1168c2ecf20Sopenharmony_ci .encrypt = krb5_encrypt, 1178c2ecf20Sopenharmony_ci .decrypt = krb5_decrypt, 1188c2ecf20Sopenharmony_ci .import_ctx = gss_krb5_import_ctx_v2, 1198c2ecf20Sopenharmony_ci .mk_key = gss_krb5_aes_make_key, 1208c2ecf20Sopenharmony_ci .encrypt_v2 = gss_krb5_aes_encrypt, 1218c2ecf20Sopenharmony_ci .decrypt_v2 = gss_krb5_aes_decrypt, 1228c2ecf20Sopenharmony_ci .signalg = -1, 1238c2ecf20Sopenharmony_ci .sealalg = -1, 1248c2ecf20Sopenharmony_ci .keybytes = 32, 1258c2ecf20Sopenharmony_ci .keylength = 32, 1268c2ecf20Sopenharmony_ci .blocksize = 16, 1278c2ecf20Sopenharmony_ci .conflen = 16, 1288c2ecf20Sopenharmony_ci .cksumlength = 12, 1298c2ecf20Sopenharmony_ci .keyed_cksum = 1, 1308c2ecf20Sopenharmony_ci }, 1318c2ecf20Sopenharmony_ci}; 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_cistatic const int num_supported_enctypes = 1348c2ecf20Sopenharmony_ci ARRAY_SIZE(supported_gss_krb5_enctypes); 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_cistatic int 1378c2ecf20Sopenharmony_cisupported_gss_krb5_enctype(int etype) 1388c2ecf20Sopenharmony_ci{ 1398c2ecf20Sopenharmony_ci int i; 1408c2ecf20Sopenharmony_ci for (i = 0; i < num_supported_enctypes; i++) 1418c2ecf20Sopenharmony_ci if (supported_gss_krb5_enctypes[i].etype == etype) 1428c2ecf20Sopenharmony_ci return 1; 1438c2ecf20Sopenharmony_ci return 0; 1448c2ecf20Sopenharmony_ci} 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_cistatic const struct gss_krb5_enctype * 1478c2ecf20Sopenharmony_ciget_gss_krb5_enctype(int etype) 1488c2ecf20Sopenharmony_ci{ 1498c2ecf20Sopenharmony_ci int i; 1508c2ecf20Sopenharmony_ci for (i = 0; i < num_supported_enctypes; i++) 1518c2ecf20Sopenharmony_ci if (supported_gss_krb5_enctypes[i].etype == etype) 1528c2ecf20Sopenharmony_ci return &supported_gss_krb5_enctypes[i]; 1538c2ecf20Sopenharmony_ci return NULL; 1548c2ecf20Sopenharmony_ci} 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_cistatic inline const void * 1578c2ecf20Sopenharmony_ciget_key(const void *p, const void *end, 1588c2ecf20Sopenharmony_ci struct krb5_ctx *ctx, struct crypto_sync_skcipher **res) 1598c2ecf20Sopenharmony_ci{ 1608c2ecf20Sopenharmony_ci struct xdr_netobj key; 1618c2ecf20Sopenharmony_ci int alg; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci p = simple_get_bytes(p, end, &alg, sizeof(alg)); 1648c2ecf20Sopenharmony_ci if (IS_ERR(p)) 1658c2ecf20Sopenharmony_ci goto out_err; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci switch (alg) { 1688c2ecf20Sopenharmony_ci case ENCTYPE_DES_CBC_CRC: 1698c2ecf20Sopenharmony_ci case ENCTYPE_DES_CBC_MD4: 1708c2ecf20Sopenharmony_ci case ENCTYPE_DES_CBC_MD5: 1718c2ecf20Sopenharmony_ci /* Map all these key types to ENCTYPE_DES_CBC_RAW */ 1728c2ecf20Sopenharmony_ci alg = ENCTYPE_DES_CBC_RAW; 1738c2ecf20Sopenharmony_ci break; 1748c2ecf20Sopenharmony_ci } 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci if (!supported_gss_krb5_enctype(alg)) { 1778c2ecf20Sopenharmony_ci printk(KERN_WARNING "gss_kerberos_mech: unsupported " 1788c2ecf20Sopenharmony_ci "encryption key algorithm %d\n", alg); 1798c2ecf20Sopenharmony_ci p = ERR_PTR(-EINVAL); 1808c2ecf20Sopenharmony_ci goto out_err; 1818c2ecf20Sopenharmony_ci } 1828c2ecf20Sopenharmony_ci p = simple_get_netobj(p, end, &key); 1838c2ecf20Sopenharmony_ci if (IS_ERR(p)) 1848c2ecf20Sopenharmony_ci goto out_err; 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci *res = crypto_alloc_sync_skcipher(ctx->gk5e->encrypt_name, 0, 0); 1878c2ecf20Sopenharmony_ci if (IS_ERR(*res)) { 1888c2ecf20Sopenharmony_ci printk(KERN_WARNING "gss_kerberos_mech: unable to initialize " 1898c2ecf20Sopenharmony_ci "crypto algorithm %s\n", ctx->gk5e->encrypt_name); 1908c2ecf20Sopenharmony_ci *res = NULL; 1918c2ecf20Sopenharmony_ci goto out_err_free_key; 1928c2ecf20Sopenharmony_ci } 1938c2ecf20Sopenharmony_ci if (crypto_sync_skcipher_setkey(*res, key.data, key.len)) { 1948c2ecf20Sopenharmony_ci printk(KERN_WARNING "gss_kerberos_mech: error setting key for " 1958c2ecf20Sopenharmony_ci "crypto algorithm %s\n", ctx->gk5e->encrypt_name); 1968c2ecf20Sopenharmony_ci goto out_err_free_tfm; 1978c2ecf20Sopenharmony_ci } 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci kfree(key.data); 2008c2ecf20Sopenharmony_ci return p; 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ciout_err_free_tfm: 2038c2ecf20Sopenharmony_ci crypto_free_sync_skcipher(*res); 2048c2ecf20Sopenharmony_ciout_err_free_key: 2058c2ecf20Sopenharmony_ci kfree(key.data); 2068c2ecf20Sopenharmony_ci p = ERR_PTR(-EINVAL); 2078c2ecf20Sopenharmony_ciout_err: 2088c2ecf20Sopenharmony_ci return p; 2098c2ecf20Sopenharmony_ci} 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_cistatic int 2128c2ecf20Sopenharmony_cigss_import_v1_context(const void *p, const void *end, struct krb5_ctx *ctx) 2138c2ecf20Sopenharmony_ci{ 2148c2ecf20Sopenharmony_ci u32 seq_send; 2158c2ecf20Sopenharmony_ci int tmp; 2168c2ecf20Sopenharmony_ci u32 time32; 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate)); 2198c2ecf20Sopenharmony_ci if (IS_ERR(p)) 2208c2ecf20Sopenharmony_ci goto out_err; 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci /* Old format supports only DES! Any other enctype uses new format */ 2238c2ecf20Sopenharmony_ci ctx->enctype = ENCTYPE_DES_CBC_RAW; 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci ctx->gk5e = get_gss_krb5_enctype(ctx->enctype); 2268c2ecf20Sopenharmony_ci if (ctx->gk5e == NULL) { 2278c2ecf20Sopenharmony_ci p = ERR_PTR(-EINVAL); 2288c2ecf20Sopenharmony_ci goto out_err; 2298c2ecf20Sopenharmony_ci } 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci /* The downcall format was designed before we completely understood 2328c2ecf20Sopenharmony_ci * the uses of the context fields; so it includes some stuff we 2338c2ecf20Sopenharmony_ci * just give some minimal sanity-checking, and some we ignore 2348c2ecf20Sopenharmony_ci * completely (like the next twenty bytes): */ 2358c2ecf20Sopenharmony_ci if (unlikely(p + 20 > end || p + 20 < p)) { 2368c2ecf20Sopenharmony_ci p = ERR_PTR(-EFAULT); 2378c2ecf20Sopenharmony_ci goto out_err; 2388c2ecf20Sopenharmony_ci } 2398c2ecf20Sopenharmony_ci p += 20; 2408c2ecf20Sopenharmony_ci p = simple_get_bytes(p, end, &tmp, sizeof(tmp)); 2418c2ecf20Sopenharmony_ci if (IS_ERR(p)) 2428c2ecf20Sopenharmony_ci goto out_err; 2438c2ecf20Sopenharmony_ci if (tmp != SGN_ALG_DES_MAC_MD5) { 2448c2ecf20Sopenharmony_ci p = ERR_PTR(-ENOSYS); 2458c2ecf20Sopenharmony_ci goto out_err; 2468c2ecf20Sopenharmony_ci } 2478c2ecf20Sopenharmony_ci p = simple_get_bytes(p, end, &tmp, sizeof(tmp)); 2488c2ecf20Sopenharmony_ci if (IS_ERR(p)) 2498c2ecf20Sopenharmony_ci goto out_err; 2508c2ecf20Sopenharmony_ci if (tmp != SEAL_ALG_DES) { 2518c2ecf20Sopenharmony_ci p = ERR_PTR(-ENOSYS); 2528c2ecf20Sopenharmony_ci goto out_err; 2538c2ecf20Sopenharmony_ci } 2548c2ecf20Sopenharmony_ci p = simple_get_bytes(p, end, &time32, sizeof(time32)); 2558c2ecf20Sopenharmony_ci if (IS_ERR(p)) 2568c2ecf20Sopenharmony_ci goto out_err; 2578c2ecf20Sopenharmony_ci /* unsigned 32-bit time overflows in year 2106 */ 2588c2ecf20Sopenharmony_ci ctx->endtime = (time64_t)time32; 2598c2ecf20Sopenharmony_ci p = simple_get_bytes(p, end, &seq_send, sizeof(seq_send)); 2608c2ecf20Sopenharmony_ci if (IS_ERR(p)) 2618c2ecf20Sopenharmony_ci goto out_err; 2628c2ecf20Sopenharmony_ci atomic_set(&ctx->seq_send, seq_send); 2638c2ecf20Sopenharmony_ci p = simple_get_netobj(p, end, &ctx->mech_used); 2648c2ecf20Sopenharmony_ci if (IS_ERR(p)) 2658c2ecf20Sopenharmony_ci goto out_err; 2668c2ecf20Sopenharmony_ci p = get_key(p, end, ctx, &ctx->enc); 2678c2ecf20Sopenharmony_ci if (IS_ERR(p)) 2688c2ecf20Sopenharmony_ci goto out_err_free_mech; 2698c2ecf20Sopenharmony_ci p = get_key(p, end, ctx, &ctx->seq); 2708c2ecf20Sopenharmony_ci if (IS_ERR(p)) 2718c2ecf20Sopenharmony_ci goto out_err_free_key1; 2728c2ecf20Sopenharmony_ci if (p != end) { 2738c2ecf20Sopenharmony_ci p = ERR_PTR(-EFAULT); 2748c2ecf20Sopenharmony_ci goto out_err_free_key2; 2758c2ecf20Sopenharmony_ci } 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ci return 0; 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ciout_err_free_key2: 2808c2ecf20Sopenharmony_ci crypto_free_sync_skcipher(ctx->seq); 2818c2ecf20Sopenharmony_ciout_err_free_key1: 2828c2ecf20Sopenharmony_ci crypto_free_sync_skcipher(ctx->enc); 2838c2ecf20Sopenharmony_ciout_err_free_mech: 2848c2ecf20Sopenharmony_ci kfree(ctx->mech_used.data); 2858c2ecf20Sopenharmony_ciout_err: 2868c2ecf20Sopenharmony_ci return PTR_ERR(p); 2878c2ecf20Sopenharmony_ci} 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_cistatic struct crypto_sync_skcipher * 2908c2ecf20Sopenharmony_cicontext_v2_alloc_cipher(struct krb5_ctx *ctx, const char *cname, u8 *key) 2918c2ecf20Sopenharmony_ci{ 2928c2ecf20Sopenharmony_ci struct crypto_sync_skcipher *cp; 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci cp = crypto_alloc_sync_skcipher(cname, 0, 0); 2958c2ecf20Sopenharmony_ci if (IS_ERR(cp)) { 2968c2ecf20Sopenharmony_ci dprintk("gss_kerberos_mech: unable to initialize " 2978c2ecf20Sopenharmony_ci "crypto algorithm %s\n", cname); 2988c2ecf20Sopenharmony_ci return NULL; 2998c2ecf20Sopenharmony_ci } 3008c2ecf20Sopenharmony_ci if (crypto_sync_skcipher_setkey(cp, key, ctx->gk5e->keylength)) { 3018c2ecf20Sopenharmony_ci dprintk("gss_kerberos_mech: error setting key for " 3028c2ecf20Sopenharmony_ci "crypto algorithm %s\n", cname); 3038c2ecf20Sopenharmony_ci crypto_free_sync_skcipher(cp); 3048c2ecf20Sopenharmony_ci return NULL; 3058c2ecf20Sopenharmony_ci } 3068c2ecf20Sopenharmony_ci return cp; 3078c2ecf20Sopenharmony_ci} 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_cistatic inline void 3108c2ecf20Sopenharmony_ciset_cdata(u8 cdata[GSS_KRB5_K5CLENGTH], u32 usage, u8 seed) 3118c2ecf20Sopenharmony_ci{ 3128c2ecf20Sopenharmony_ci cdata[0] = (usage>>24)&0xff; 3138c2ecf20Sopenharmony_ci cdata[1] = (usage>>16)&0xff; 3148c2ecf20Sopenharmony_ci cdata[2] = (usage>>8)&0xff; 3158c2ecf20Sopenharmony_ci cdata[3] = usage&0xff; 3168c2ecf20Sopenharmony_ci cdata[4] = seed; 3178c2ecf20Sopenharmony_ci} 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_cistatic int 3208c2ecf20Sopenharmony_cigss_krb5_import_ctx_des(struct krb5_ctx *ctx, gfp_t gfp_mask) 3218c2ecf20Sopenharmony_ci{ 3228c2ecf20Sopenharmony_ci return -EINVAL; 3238c2ecf20Sopenharmony_ci} 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_cistatic int 3268c2ecf20Sopenharmony_cigss_krb5_import_ctx_v1(struct krb5_ctx *ctx, gfp_t gfp_mask) 3278c2ecf20Sopenharmony_ci{ 3288c2ecf20Sopenharmony_ci struct xdr_netobj c, keyin, keyout; 3298c2ecf20Sopenharmony_ci u8 cdata[GSS_KRB5_K5CLENGTH]; 3308c2ecf20Sopenharmony_ci u32 err; 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci c.len = GSS_KRB5_K5CLENGTH; 3338c2ecf20Sopenharmony_ci c.data = cdata; 3348c2ecf20Sopenharmony_ci 3358c2ecf20Sopenharmony_ci keyin.data = ctx->Ksess; 3368c2ecf20Sopenharmony_ci keyin.len = ctx->gk5e->keylength; 3378c2ecf20Sopenharmony_ci keyout.len = ctx->gk5e->keylength; 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci /* seq uses the raw key */ 3408c2ecf20Sopenharmony_ci ctx->seq = context_v2_alloc_cipher(ctx, ctx->gk5e->encrypt_name, 3418c2ecf20Sopenharmony_ci ctx->Ksess); 3428c2ecf20Sopenharmony_ci if (ctx->seq == NULL) 3438c2ecf20Sopenharmony_ci goto out_err; 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_ci ctx->enc = context_v2_alloc_cipher(ctx, ctx->gk5e->encrypt_name, 3468c2ecf20Sopenharmony_ci ctx->Ksess); 3478c2ecf20Sopenharmony_ci if (ctx->enc == NULL) 3488c2ecf20Sopenharmony_ci goto out_free_seq; 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci /* derive cksum */ 3518c2ecf20Sopenharmony_ci set_cdata(cdata, KG_USAGE_SIGN, KEY_USAGE_SEED_CHECKSUM); 3528c2ecf20Sopenharmony_ci keyout.data = ctx->cksum; 3538c2ecf20Sopenharmony_ci err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 3548c2ecf20Sopenharmony_ci if (err) { 3558c2ecf20Sopenharmony_ci dprintk("%s: Error %d deriving cksum key\n", 3568c2ecf20Sopenharmony_ci __func__, err); 3578c2ecf20Sopenharmony_ci goto out_free_enc; 3588c2ecf20Sopenharmony_ci } 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci return 0; 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ciout_free_enc: 3638c2ecf20Sopenharmony_ci crypto_free_sync_skcipher(ctx->enc); 3648c2ecf20Sopenharmony_ciout_free_seq: 3658c2ecf20Sopenharmony_ci crypto_free_sync_skcipher(ctx->seq); 3668c2ecf20Sopenharmony_ciout_err: 3678c2ecf20Sopenharmony_ci return -EINVAL; 3688c2ecf20Sopenharmony_ci} 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_cistatic int 3718c2ecf20Sopenharmony_cigss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask) 3728c2ecf20Sopenharmony_ci{ 3738c2ecf20Sopenharmony_ci struct xdr_netobj c, keyin, keyout; 3748c2ecf20Sopenharmony_ci u8 cdata[GSS_KRB5_K5CLENGTH]; 3758c2ecf20Sopenharmony_ci u32 err; 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci c.len = GSS_KRB5_K5CLENGTH; 3788c2ecf20Sopenharmony_ci c.data = cdata; 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci keyin.data = ctx->Ksess; 3818c2ecf20Sopenharmony_ci keyin.len = ctx->gk5e->keylength; 3828c2ecf20Sopenharmony_ci keyout.len = ctx->gk5e->keylength; 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci /* initiator seal encryption */ 3858c2ecf20Sopenharmony_ci set_cdata(cdata, KG_USAGE_INITIATOR_SEAL, KEY_USAGE_SEED_ENCRYPTION); 3868c2ecf20Sopenharmony_ci keyout.data = ctx->initiator_seal; 3878c2ecf20Sopenharmony_ci err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 3888c2ecf20Sopenharmony_ci if (err) { 3898c2ecf20Sopenharmony_ci dprintk("%s: Error %d deriving initiator_seal key\n", 3908c2ecf20Sopenharmony_ci __func__, err); 3918c2ecf20Sopenharmony_ci goto out_err; 3928c2ecf20Sopenharmony_ci } 3938c2ecf20Sopenharmony_ci ctx->initiator_enc = context_v2_alloc_cipher(ctx, 3948c2ecf20Sopenharmony_ci ctx->gk5e->encrypt_name, 3958c2ecf20Sopenharmony_ci ctx->initiator_seal); 3968c2ecf20Sopenharmony_ci if (ctx->initiator_enc == NULL) 3978c2ecf20Sopenharmony_ci goto out_err; 3988c2ecf20Sopenharmony_ci 3998c2ecf20Sopenharmony_ci /* acceptor seal encryption */ 4008c2ecf20Sopenharmony_ci set_cdata(cdata, KG_USAGE_ACCEPTOR_SEAL, KEY_USAGE_SEED_ENCRYPTION); 4018c2ecf20Sopenharmony_ci keyout.data = ctx->acceptor_seal; 4028c2ecf20Sopenharmony_ci err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 4038c2ecf20Sopenharmony_ci if (err) { 4048c2ecf20Sopenharmony_ci dprintk("%s: Error %d deriving acceptor_seal key\n", 4058c2ecf20Sopenharmony_ci __func__, err); 4068c2ecf20Sopenharmony_ci goto out_free_initiator_enc; 4078c2ecf20Sopenharmony_ci } 4088c2ecf20Sopenharmony_ci ctx->acceptor_enc = context_v2_alloc_cipher(ctx, 4098c2ecf20Sopenharmony_ci ctx->gk5e->encrypt_name, 4108c2ecf20Sopenharmony_ci ctx->acceptor_seal); 4118c2ecf20Sopenharmony_ci if (ctx->acceptor_enc == NULL) 4128c2ecf20Sopenharmony_ci goto out_free_initiator_enc; 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_ci /* initiator sign checksum */ 4158c2ecf20Sopenharmony_ci set_cdata(cdata, KG_USAGE_INITIATOR_SIGN, KEY_USAGE_SEED_CHECKSUM); 4168c2ecf20Sopenharmony_ci keyout.data = ctx->initiator_sign; 4178c2ecf20Sopenharmony_ci err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 4188c2ecf20Sopenharmony_ci if (err) { 4198c2ecf20Sopenharmony_ci dprintk("%s: Error %d deriving initiator_sign key\n", 4208c2ecf20Sopenharmony_ci __func__, err); 4218c2ecf20Sopenharmony_ci goto out_free_acceptor_enc; 4228c2ecf20Sopenharmony_ci } 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_ci /* acceptor sign checksum */ 4258c2ecf20Sopenharmony_ci set_cdata(cdata, KG_USAGE_ACCEPTOR_SIGN, KEY_USAGE_SEED_CHECKSUM); 4268c2ecf20Sopenharmony_ci keyout.data = ctx->acceptor_sign; 4278c2ecf20Sopenharmony_ci err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 4288c2ecf20Sopenharmony_ci if (err) { 4298c2ecf20Sopenharmony_ci dprintk("%s: Error %d deriving acceptor_sign key\n", 4308c2ecf20Sopenharmony_ci __func__, err); 4318c2ecf20Sopenharmony_ci goto out_free_acceptor_enc; 4328c2ecf20Sopenharmony_ci } 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_ci /* initiator seal integrity */ 4358c2ecf20Sopenharmony_ci set_cdata(cdata, KG_USAGE_INITIATOR_SEAL, KEY_USAGE_SEED_INTEGRITY); 4368c2ecf20Sopenharmony_ci keyout.data = ctx->initiator_integ; 4378c2ecf20Sopenharmony_ci err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 4388c2ecf20Sopenharmony_ci if (err) { 4398c2ecf20Sopenharmony_ci dprintk("%s: Error %d deriving initiator_integ key\n", 4408c2ecf20Sopenharmony_ci __func__, err); 4418c2ecf20Sopenharmony_ci goto out_free_acceptor_enc; 4428c2ecf20Sopenharmony_ci } 4438c2ecf20Sopenharmony_ci 4448c2ecf20Sopenharmony_ci /* acceptor seal integrity */ 4458c2ecf20Sopenharmony_ci set_cdata(cdata, KG_USAGE_ACCEPTOR_SEAL, KEY_USAGE_SEED_INTEGRITY); 4468c2ecf20Sopenharmony_ci keyout.data = ctx->acceptor_integ; 4478c2ecf20Sopenharmony_ci err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 4488c2ecf20Sopenharmony_ci if (err) { 4498c2ecf20Sopenharmony_ci dprintk("%s: Error %d deriving acceptor_integ key\n", 4508c2ecf20Sopenharmony_ci __func__, err); 4518c2ecf20Sopenharmony_ci goto out_free_acceptor_enc; 4528c2ecf20Sopenharmony_ci } 4538c2ecf20Sopenharmony_ci 4548c2ecf20Sopenharmony_ci switch (ctx->enctype) { 4558c2ecf20Sopenharmony_ci case ENCTYPE_AES128_CTS_HMAC_SHA1_96: 4568c2ecf20Sopenharmony_ci case ENCTYPE_AES256_CTS_HMAC_SHA1_96: 4578c2ecf20Sopenharmony_ci ctx->initiator_enc_aux = 4588c2ecf20Sopenharmony_ci context_v2_alloc_cipher(ctx, "cbc(aes)", 4598c2ecf20Sopenharmony_ci ctx->initiator_seal); 4608c2ecf20Sopenharmony_ci if (ctx->initiator_enc_aux == NULL) 4618c2ecf20Sopenharmony_ci goto out_free_acceptor_enc; 4628c2ecf20Sopenharmony_ci ctx->acceptor_enc_aux = 4638c2ecf20Sopenharmony_ci context_v2_alloc_cipher(ctx, "cbc(aes)", 4648c2ecf20Sopenharmony_ci ctx->acceptor_seal); 4658c2ecf20Sopenharmony_ci if (ctx->acceptor_enc_aux == NULL) { 4668c2ecf20Sopenharmony_ci crypto_free_sync_skcipher(ctx->initiator_enc_aux); 4678c2ecf20Sopenharmony_ci goto out_free_acceptor_enc; 4688c2ecf20Sopenharmony_ci } 4698c2ecf20Sopenharmony_ci } 4708c2ecf20Sopenharmony_ci 4718c2ecf20Sopenharmony_ci return 0; 4728c2ecf20Sopenharmony_ci 4738c2ecf20Sopenharmony_ciout_free_acceptor_enc: 4748c2ecf20Sopenharmony_ci crypto_free_sync_skcipher(ctx->acceptor_enc); 4758c2ecf20Sopenharmony_ciout_free_initiator_enc: 4768c2ecf20Sopenharmony_ci crypto_free_sync_skcipher(ctx->initiator_enc); 4778c2ecf20Sopenharmony_ciout_err: 4788c2ecf20Sopenharmony_ci return -EINVAL; 4798c2ecf20Sopenharmony_ci} 4808c2ecf20Sopenharmony_ci 4818c2ecf20Sopenharmony_cistatic int 4828c2ecf20Sopenharmony_cigss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx, 4838c2ecf20Sopenharmony_ci gfp_t gfp_mask) 4848c2ecf20Sopenharmony_ci{ 4858c2ecf20Sopenharmony_ci u64 seq_send64; 4868c2ecf20Sopenharmony_ci int keylen; 4878c2ecf20Sopenharmony_ci u32 time32; 4888c2ecf20Sopenharmony_ci int ret; 4898c2ecf20Sopenharmony_ci 4908c2ecf20Sopenharmony_ci p = simple_get_bytes(p, end, &ctx->flags, sizeof(ctx->flags)); 4918c2ecf20Sopenharmony_ci if (IS_ERR(p)) 4928c2ecf20Sopenharmony_ci goto out_err; 4938c2ecf20Sopenharmony_ci ctx->initiate = ctx->flags & KRB5_CTX_FLAG_INITIATOR; 4948c2ecf20Sopenharmony_ci 4958c2ecf20Sopenharmony_ci p = simple_get_bytes(p, end, &time32, sizeof(time32)); 4968c2ecf20Sopenharmony_ci if (IS_ERR(p)) 4978c2ecf20Sopenharmony_ci goto out_err; 4988c2ecf20Sopenharmony_ci /* unsigned 32-bit time overflows in year 2106 */ 4998c2ecf20Sopenharmony_ci ctx->endtime = (time64_t)time32; 5008c2ecf20Sopenharmony_ci p = simple_get_bytes(p, end, &seq_send64, sizeof(seq_send64)); 5018c2ecf20Sopenharmony_ci if (IS_ERR(p)) 5028c2ecf20Sopenharmony_ci goto out_err; 5038c2ecf20Sopenharmony_ci atomic64_set(&ctx->seq_send64, seq_send64); 5048c2ecf20Sopenharmony_ci /* set seq_send for use by "older" enctypes */ 5058c2ecf20Sopenharmony_ci atomic_set(&ctx->seq_send, seq_send64); 5068c2ecf20Sopenharmony_ci if (seq_send64 != atomic_read(&ctx->seq_send)) { 5078c2ecf20Sopenharmony_ci dprintk("%s: seq_send64 %llx, seq_send %x overflow?\n", __func__, 5088c2ecf20Sopenharmony_ci seq_send64, atomic_read(&ctx->seq_send)); 5098c2ecf20Sopenharmony_ci p = ERR_PTR(-EINVAL); 5108c2ecf20Sopenharmony_ci goto out_err; 5118c2ecf20Sopenharmony_ci } 5128c2ecf20Sopenharmony_ci p = simple_get_bytes(p, end, &ctx->enctype, sizeof(ctx->enctype)); 5138c2ecf20Sopenharmony_ci if (IS_ERR(p)) 5148c2ecf20Sopenharmony_ci goto out_err; 5158c2ecf20Sopenharmony_ci /* Map ENCTYPE_DES3_CBC_SHA1 to ENCTYPE_DES3_CBC_RAW */ 5168c2ecf20Sopenharmony_ci if (ctx->enctype == ENCTYPE_DES3_CBC_SHA1) 5178c2ecf20Sopenharmony_ci ctx->enctype = ENCTYPE_DES3_CBC_RAW; 5188c2ecf20Sopenharmony_ci ctx->gk5e = get_gss_krb5_enctype(ctx->enctype); 5198c2ecf20Sopenharmony_ci if (ctx->gk5e == NULL) { 5208c2ecf20Sopenharmony_ci dprintk("gss_kerberos_mech: unsupported krb5 enctype %u\n", 5218c2ecf20Sopenharmony_ci ctx->enctype); 5228c2ecf20Sopenharmony_ci p = ERR_PTR(-EINVAL); 5238c2ecf20Sopenharmony_ci goto out_err; 5248c2ecf20Sopenharmony_ci } 5258c2ecf20Sopenharmony_ci keylen = ctx->gk5e->keylength; 5268c2ecf20Sopenharmony_ci 5278c2ecf20Sopenharmony_ci p = simple_get_bytes(p, end, ctx->Ksess, keylen); 5288c2ecf20Sopenharmony_ci if (IS_ERR(p)) 5298c2ecf20Sopenharmony_ci goto out_err; 5308c2ecf20Sopenharmony_ci 5318c2ecf20Sopenharmony_ci if (p != end) { 5328c2ecf20Sopenharmony_ci p = ERR_PTR(-EINVAL); 5338c2ecf20Sopenharmony_ci goto out_err; 5348c2ecf20Sopenharmony_ci } 5358c2ecf20Sopenharmony_ci 5368c2ecf20Sopenharmony_ci ctx->mech_used.data = kmemdup(gss_kerberos_mech.gm_oid.data, 5378c2ecf20Sopenharmony_ci gss_kerberos_mech.gm_oid.len, gfp_mask); 5388c2ecf20Sopenharmony_ci if (unlikely(ctx->mech_used.data == NULL)) { 5398c2ecf20Sopenharmony_ci p = ERR_PTR(-ENOMEM); 5408c2ecf20Sopenharmony_ci goto out_err; 5418c2ecf20Sopenharmony_ci } 5428c2ecf20Sopenharmony_ci ctx->mech_used.len = gss_kerberos_mech.gm_oid.len; 5438c2ecf20Sopenharmony_ci 5448c2ecf20Sopenharmony_ci ret = gss_krb5_import_ctx_v2(ctx, gfp_mask); 5458c2ecf20Sopenharmony_ci if (ret) { 5468c2ecf20Sopenharmony_ci p = ERR_PTR(ret); 5478c2ecf20Sopenharmony_ci goto out_free; 5488c2ecf20Sopenharmony_ci } 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_ci return 0; 5518c2ecf20Sopenharmony_ci 5528c2ecf20Sopenharmony_ciout_free: 5538c2ecf20Sopenharmony_ci kfree(ctx->mech_used.data); 5548c2ecf20Sopenharmony_ciout_err: 5558c2ecf20Sopenharmony_ci return PTR_ERR(p); 5568c2ecf20Sopenharmony_ci} 5578c2ecf20Sopenharmony_ci 5588c2ecf20Sopenharmony_cistatic int 5598c2ecf20Sopenharmony_cigss_import_sec_context_kerberos(const void *p, size_t len, 5608c2ecf20Sopenharmony_ci struct gss_ctx *ctx_id, 5618c2ecf20Sopenharmony_ci time64_t *endtime, 5628c2ecf20Sopenharmony_ci gfp_t gfp_mask) 5638c2ecf20Sopenharmony_ci{ 5648c2ecf20Sopenharmony_ci const void *end = (const void *)((const char *)p + len); 5658c2ecf20Sopenharmony_ci struct krb5_ctx *ctx; 5668c2ecf20Sopenharmony_ci int ret; 5678c2ecf20Sopenharmony_ci 5688c2ecf20Sopenharmony_ci ctx = kzalloc(sizeof(*ctx), gfp_mask); 5698c2ecf20Sopenharmony_ci if (ctx == NULL) 5708c2ecf20Sopenharmony_ci return -ENOMEM; 5718c2ecf20Sopenharmony_ci 5728c2ecf20Sopenharmony_ci if (len == 85) 5738c2ecf20Sopenharmony_ci ret = gss_import_v1_context(p, end, ctx); 5748c2ecf20Sopenharmony_ci else 5758c2ecf20Sopenharmony_ci ret = gss_import_v2_context(p, end, ctx, gfp_mask); 5768c2ecf20Sopenharmony_ci 5778c2ecf20Sopenharmony_ci if (ret == 0) { 5788c2ecf20Sopenharmony_ci ctx_id->internal_ctx_id = ctx; 5798c2ecf20Sopenharmony_ci if (endtime) 5808c2ecf20Sopenharmony_ci *endtime = ctx->endtime; 5818c2ecf20Sopenharmony_ci } else 5828c2ecf20Sopenharmony_ci kfree(ctx); 5838c2ecf20Sopenharmony_ci 5848c2ecf20Sopenharmony_ci dprintk("RPC: %s: returning %d\n", __func__, ret); 5858c2ecf20Sopenharmony_ci return ret; 5868c2ecf20Sopenharmony_ci} 5878c2ecf20Sopenharmony_ci 5888c2ecf20Sopenharmony_cistatic void 5898c2ecf20Sopenharmony_cigss_delete_sec_context_kerberos(void *internal_ctx) { 5908c2ecf20Sopenharmony_ci struct krb5_ctx *kctx = internal_ctx; 5918c2ecf20Sopenharmony_ci 5928c2ecf20Sopenharmony_ci crypto_free_sync_skcipher(kctx->seq); 5938c2ecf20Sopenharmony_ci crypto_free_sync_skcipher(kctx->enc); 5948c2ecf20Sopenharmony_ci crypto_free_sync_skcipher(kctx->acceptor_enc); 5958c2ecf20Sopenharmony_ci crypto_free_sync_skcipher(kctx->initiator_enc); 5968c2ecf20Sopenharmony_ci crypto_free_sync_skcipher(kctx->acceptor_enc_aux); 5978c2ecf20Sopenharmony_ci crypto_free_sync_skcipher(kctx->initiator_enc_aux); 5988c2ecf20Sopenharmony_ci kfree(kctx->mech_used.data); 5998c2ecf20Sopenharmony_ci kfree(kctx); 6008c2ecf20Sopenharmony_ci} 6018c2ecf20Sopenharmony_ci 6028c2ecf20Sopenharmony_cistatic const struct gss_api_ops gss_kerberos_ops = { 6038c2ecf20Sopenharmony_ci .gss_import_sec_context = gss_import_sec_context_kerberos, 6048c2ecf20Sopenharmony_ci .gss_get_mic = gss_get_mic_kerberos, 6058c2ecf20Sopenharmony_ci .gss_verify_mic = gss_verify_mic_kerberos, 6068c2ecf20Sopenharmony_ci .gss_wrap = gss_wrap_kerberos, 6078c2ecf20Sopenharmony_ci .gss_unwrap = gss_unwrap_kerberos, 6088c2ecf20Sopenharmony_ci .gss_delete_sec_context = gss_delete_sec_context_kerberos, 6098c2ecf20Sopenharmony_ci}; 6108c2ecf20Sopenharmony_ci 6118c2ecf20Sopenharmony_cistatic struct pf_desc gss_kerberos_pfs[] = { 6128c2ecf20Sopenharmony_ci [0] = { 6138c2ecf20Sopenharmony_ci .pseudoflavor = RPC_AUTH_GSS_KRB5, 6148c2ecf20Sopenharmony_ci .qop = GSS_C_QOP_DEFAULT, 6158c2ecf20Sopenharmony_ci .service = RPC_GSS_SVC_NONE, 6168c2ecf20Sopenharmony_ci .name = "krb5", 6178c2ecf20Sopenharmony_ci }, 6188c2ecf20Sopenharmony_ci [1] = { 6198c2ecf20Sopenharmony_ci .pseudoflavor = RPC_AUTH_GSS_KRB5I, 6208c2ecf20Sopenharmony_ci .qop = GSS_C_QOP_DEFAULT, 6218c2ecf20Sopenharmony_ci .service = RPC_GSS_SVC_INTEGRITY, 6228c2ecf20Sopenharmony_ci .name = "krb5i", 6238c2ecf20Sopenharmony_ci .datatouch = true, 6248c2ecf20Sopenharmony_ci }, 6258c2ecf20Sopenharmony_ci [2] = { 6268c2ecf20Sopenharmony_ci .pseudoflavor = RPC_AUTH_GSS_KRB5P, 6278c2ecf20Sopenharmony_ci .qop = GSS_C_QOP_DEFAULT, 6288c2ecf20Sopenharmony_ci .service = RPC_GSS_SVC_PRIVACY, 6298c2ecf20Sopenharmony_ci .name = "krb5p", 6308c2ecf20Sopenharmony_ci .datatouch = true, 6318c2ecf20Sopenharmony_ci }, 6328c2ecf20Sopenharmony_ci}; 6338c2ecf20Sopenharmony_ci 6348c2ecf20Sopenharmony_ciMODULE_ALIAS("rpc-auth-gss-krb5"); 6358c2ecf20Sopenharmony_ciMODULE_ALIAS("rpc-auth-gss-krb5i"); 6368c2ecf20Sopenharmony_ciMODULE_ALIAS("rpc-auth-gss-krb5p"); 6378c2ecf20Sopenharmony_ciMODULE_ALIAS("rpc-auth-gss-390003"); 6388c2ecf20Sopenharmony_ciMODULE_ALIAS("rpc-auth-gss-390004"); 6398c2ecf20Sopenharmony_ciMODULE_ALIAS("rpc-auth-gss-390005"); 6408c2ecf20Sopenharmony_ciMODULE_ALIAS("rpc-auth-gss-1.2.840.113554.1.2.2"); 6418c2ecf20Sopenharmony_ci 6428c2ecf20Sopenharmony_cistatic struct gss_api_mech gss_kerberos_mech = { 6438c2ecf20Sopenharmony_ci .gm_name = "krb5", 6448c2ecf20Sopenharmony_ci .gm_owner = THIS_MODULE, 6458c2ecf20Sopenharmony_ci .gm_oid = { 9, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" }, 6468c2ecf20Sopenharmony_ci .gm_ops = &gss_kerberos_ops, 6478c2ecf20Sopenharmony_ci .gm_pf_num = ARRAY_SIZE(gss_kerberos_pfs), 6488c2ecf20Sopenharmony_ci .gm_pfs = gss_kerberos_pfs, 6498c2ecf20Sopenharmony_ci .gm_upcall_enctypes = KRB5_SUPPORTED_ENCTYPES, 6508c2ecf20Sopenharmony_ci}; 6518c2ecf20Sopenharmony_ci 6528c2ecf20Sopenharmony_cistatic int __init init_kerberos_module(void) 6538c2ecf20Sopenharmony_ci{ 6548c2ecf20Sopenharmony_ci int status; 6558c2ecf20Sopenharmony_ci 6568c2ecf20Sopenharmony_ci status = gss_mech_register(&gss_kerberos_mech); 6578c2ecf20Sopenharmony_ci if (status) 6588c2ecf20Sopenharmony_ci printk("Failed to register kerberos gss mechanism!\n"); 6598c2ecf20Sopenharmony_ci return status; 6608c2ecf20Sopenharmony_ci} 6618c2ecf20Sopenharmony_ci 6628c2ecf20Sopenharmony_cistatic void __exit cleanup_kerberos_module(void) 6638c2ecf20Sopenharmony_ci{ 6648c2ecf20Sopenharmony_ci gss_mech_unregister(&gss_kerberos_mech); 6658c2ecf20Sopenharmony_ci} 6668c2ecf20Sopenharmony_ci 6678c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 6688c2ecf20Sopenharmony_cimodule_init(init_kerberos_module); 6698c2ecf20Sopenharmony_cimodule_exit(cleanup_kerberos_module); 670