/* * COPYRIGHT (c) 2008 * The Regents of the University of Michigan * ALL RIGHTS RESERVED * * Permission is granted to use, copy, create derivative works * and redistribute this software and such derivative works * for any purpose, so long as the name of The University of * Michigan is not used in any advertising or publicity * pertaining to the use of distribution of this software * without specific, written prior authorization. If the * above copyright notice or any other identification of the * University of Michigan is included in any copy of any * portion of this software, then the disclaimer below must * also be included. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF * SUCH DAMAGES. */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include <crypto/skcipher.h> #include <linux/err.h> #include <linux/types.h> #include <linux/sunrpc/gss_krb5.h> #include <linux/sunrpc/xdr.h> #include <linux/lcm.h> #include <crypto/hash.h> #include <kunit/visibility.h> #include "gss_krb5_internal.h" #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) #define RPCDBG_FACILITY … #endif /** * krb5_nfold - n-fold function * @inbits: number of bits in @in * @in: buffer containing input to fold * @outbits: number of bits in the output buffer * @out: buffer to hold the result * * This is the n-fold function as described in rfc3961, sec 5.1 * Taken from MIT Kerberos and modified. */ VISIBLE_IF_KUNIT void krb5_nfold(u32 inbits, const u8 *in, u32 outbits, u8 *out) { … } EXPORT_SYMBOL_IF_KUNIT(…); /* * This is the DK (derive_key) function as described in rfc3961, sec 5.1 * Taken from MIT Kerberos and modified. */ static int krb5_DK(const struct gss_krb5_enctype *gk5e, const struct xdr_netobj *inkey, u8 *rawkey, const struct xdr_netobj *in_constant, gfp_t gfp_mask) { … } /* * This is the identity function, with some sanity checking. */ static int krb5_random_to_key_v2(const struct gss_krb5_enctype *gk5e, struct xdr_netobj *randombits, struct xdr_netobj *key) { … } /** * krb5_derive_key_v2 - Derive a subkey for an RFC 3962 enctype * @gk5e: Kerberos 5 enctype profile * @inkey: base protocol key * @outkey: OUT: derived key * @label: subkey usage label * @gfp_mask: memory allocation control flags * * Caller sets @outkey->len to the desired length of the derived key. * * On success, returns 0 and fills in @outkey. A negative errno value * is returned on failure. */ int krb5_derive_key_v2(const struct gss_krb5_enctype *gk5e, const struct xdr_netobj *inkey, struct xdr_netobj *outkey, const struct xdr_netobj *label, gfp_t gfp_mask) { … } /* * K(i) = CMAC(key, K(i-1) | i | constant | 0x00 | k) * * i: A block counter is used with a length of 4 bytes, represented * in big-endian order. * * constant: The label input to the KDF is the usage constant supplied * to the key derivation function * * k: The length of the output key in bits, represented as a 4-byte * string in big-endian order. * * Caller fills in K(i-1) in @step, and receives the result K(i) * in the same buffer. */ static int krb5_cmac_Ki(struct crypto_shash *tfm, const struct xdr_netobj *constant, u32 outlen, u32 count, struct xdr_netobj *step) { … } /** * krb5_kdf_feedback_cmac - Derive a subkey for a Camellia/CMAC-based enctype * @gk5e: Kerberos 5 enctype parameters * @inkey: base protocol key * @outkey: OUT: derived key * @constant: subkey usage label * @gfp_mask: memory allocation control flags * * RFC 6803 Section 3: * * "We use a key derivation function from the family specified in * [SP800-108], Section 5.2, 'KDF in Feedback Mode'." * * n = ceiling(k / 128) * K(0) = zeros * K(i) = CMAC(key, K(i-1) | i | constant | 0x00 | k) * DR(key, constant) = k-truncate(K(1) | K(2) | ... | K(n)) * KDF-FEEDBACK-CMAC(key, constant) = random-to-key(DR(key, constant)) * * Caller sets @outkey->len to the desired length of the derived key (k). * * On success, returns 0 and fills in @outkey. A negative errno value * is returned on failure. */ int krb5_kdf_feedback_cmac(const struct gss_krb5_enctype *gk5e, const struct xdr_netobj *inkey, struct xdr_netobj *outkey, const struct xdr_netobj *constant, gfp_t gfp_mask) { … } /* * K1 = HMAC-SHA(key, 0x00000001 | label | 0x00 | k) * * key: The source of entropy from which subsequent keys are derived. * * label: An octet string describing the intended usage of the * derived key. * * k: Length in bits of the key to be outputted, expressed in * big-endian binary representation in 4 bytes. */ static int krb5_hmac_K1(struct crypto_shash *tfm, const struct xdr_netobj *label, u32 outlen, struct xdr_netobj *K1) { … } /** * krb5_kdf_hmac_sha2 - Derive a subkey for an AES/SHA2-based enctype * @gk5e: Kerberos 5 enctype policy parameters * @inkey: base protocol key * @outkey: OUT: derived key * @label: subkey usage label * @gfp_mask: memory allocation control flags * * RFC 8009 Section 3: * * "We use a key derivation function from Section 5.1 of [SP800-108], * which uses the HMAC algorithm as the PRF." * * function KDF-HMAC-SHA2(key, label, [context,] k): * k-truncate(K1) * * Caller sets @outkey->len to the desired length of the derived key. * * On success, returns 0 and fills in @outkey. A negative errno value * is returned on failure. */ int krb5_kdf_hmac_sha2(const struct gss_krb5_enctype *gk5e, const struct xdr_netobj *inkey, struct xdr_netobj *outkey, const struct xdr_netobj *label, gfp_t gfp_mask) { … }