crypto/krb5: Implement Kerberos crypto core

Provide core structures, an encoding-type registry and basic module and
config bits for a generic Kerberos crypto library.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: "David S. Miller" <davem@davemloft.net>
cc: Chuck Lever <chuck.lever@oracle.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: Eric Dumazet <edumazet@google.com>
cc: Jakub Kicinski <kuba@kernel.org>
cc: Paolo Abeni <pabeni@redhat.com>
cc: Simon Horman <horms@kernel.org>
cc: linux-afs@lists.infradead.org
cc: linux-nfs@vger.kernel.org
cc: linux-crypto@vger.kernel.org
cc: netdev@vger.kernel.org
This commit is contained in:
David Howells 2020-11-10 17:00:54 +00:00
parent 1b80b6f446
commit 3936f02bf2
7 changed files with 234 additions and 0 deletions

View file

@ -1472,5 +1472,6 @@ endif
source "drivers/crypto/Kconfig"
source "crypto/asymmetric_keys/Kconfig"
source "certs/Kconfig"
source "crypto/krb5/Kconfig"
endif # if CRYPTO

View file

@ -213,3 +213,5 @@ obj-$(CONFIG_CRYPTO_SIMD) += crypto_simd.o
# Key derivation function
#
obj-$(CONFIG_CRYPTO_KDF800108_CTR) += kdf_sp800108.o
obj-$(CONFIG_CRYPTO_KRB5) += krb5/

14
crypto/krb5/Kconfig Normal file
View file

@ -0,0 +1,14 @@
config CRYPTO_KRB5
tristate "Kerberos 5 crypto"
select CRYPTO_MANAGER
select CRYPTO_KRB5ENC
select CRYPTO_AUTHENC
select CRYPTO_SKCIPHER
select CRYPTO_HASH_INFO
select CRYPTO_SHA1
select CRYPTO_CBC
select CRYPTO_CTS
select CRYPTO_AES
help
Provide a library for provision of Kerberos-5-based crypto. This is
intended for network filesystems to use.

9
crypto/krb5/Makefile Normal file
View file

@ -0,0 +1,9 @@
# SPDX-License-Identifier: GPL-2.0
#
# Makefile for asymmetric cryptographic keys
#
krb5-y += \
krb5_api.o
obj-$(CONFIG_CRYPTO_KRB5) += krb5.o

112
crypto/krb5/internal.h Normal file
View file

@ -0,0 +1,112 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Kerberos5 crypto internals
*
* Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*/
#include <crypto/krb5.h>
/*
* Profile used for key derivation and encryption.
*/
struct krb5_crypto_profile {
/* Pseudo-random function */
int (*calc_PRF)(const struct krb5_enctype *krb5,
const struct krb5_buffer *protocol_key,
const struct krb5_buffer *octet_string,
struct krb5_buffer *result,
gfp_t gfp);
/* Checksum key derivation */
int (*calc_Kc)(const struct krb5_enctype *krb5,
const struct krb5_buffer *TK,
const struct krb5_buffer *usage_constant,
struct krb5_buffer *Kc,
gfp_t gfp);
/* Encryption key derivation */
int (*calc_Ke)(const struct krb5_enctype *krb5,
const struct krb5_buffer *TK,
const struct krb5_buffer *usage_constant,
struct krb5_buffer *Ke,
gfp_t gfp);
/* Integrity key derivation */
int (*calc_Ki)(const struct krb5_enctype *krb5,
const struct krb5_buffer *TK,
const struct krb5_buffer *usage_constant,
struct krb5_buffer *Ki,
gfp_t gfp);
/* Derive the keys needed for an encryption AEAD object. */
int (*derive_encrypt_keys)(const struct krb5_enctype *krb5,
const struct krb5_buffer *TK,
unsigned int usage,
struct krb5_buffer *setkey,
gfp_t gfp);
/* Directly load the keys needed for an encryption AEAD object. */
int (*load_encrypt_keys)(const struct krb5_enctype *krb5,
const struct krb5_buffer *Ke,
const struct krb5_buffer *Ki,
struct krb5_buffer *setkey,
gfp_t gfp);
/* Derive the key needed for a checksum hash object. */
int (*derive_checksum_key)(const struct krb5_enctype *krb5,
const struct krb5_buffer *TK,
unsigned int usage,
struct krb5_buffer *setkey,
gfp_t gfp);
/* Directly load the keys needed for a checksum hash object. */
int (*load_checksum_key)(const struct krb5_enctype *krb5,
const struct krb5_buffer *Kc,
struct krb5_buffer *setkey,
gfp_t gfp);
/* Encrypt data in-place, inserting confounder and checksum. */
ssize_t (*encrypt)(const struct krb5_enctype *krb5,
struct crypto_aead *aead,
struct scatterlist *sg, unsigned int nr_sg,
size_t sg_len,
size_t data_offset, size_t data_len,
bool preconfounded);
/* Decrypt data in-place, removing confounder and checksum */
int (*decrypt)(const struct krb5_enctype *krb5,
struct crypto_aead *aead,
struct scatterlist *sg, unsigned int nr_sg,
size_t *_offset, size_t *_len);
/* Generate a MIC on part of a packet, inserting the checksum */
ssize_t (*get_mic)(const struct krb5_enctype *krb5,
struct crypto_shash *shash,
const struct krb5_buffer *metadata,
struct scatterlist *sg, unsigned int nr_sg,
size_t sg_len,
size_t data_offset, size_t data_len);
/* Verify the MIC on a piece of data, removing the checksum */
int (*verify_mic)(const struct krb5_enctype *krb5,
struct crypto_shash *shash,
const struct krb5_buffer *metadata,
struct scatterlist *sg, unsigned int nr_sg,
size_t *_offset, size_t *_len);
};
/*
* Crypto size/alignment rounding convenience macros.
*/
#define crypto_roundup(X) ((unsigned int)round_up((X), CRYPTO_MINALIGN))
#define krb5_aead_size(TFM) \
crypto_roundup(sizeof(struct aead_request) + crypto_aead_reqsize(TFM))
#define krb5_aead_ivsize(TFM) \
crypto_roundup(crypto_aead_ivsize(TFM))
#define krb5_shash_size(TFM) \
crypto_roundup(sizeof(struct shash_desc) + crypto_shash_descsize(TFM))
#define krb5_digest_size(TFM) \
crypto_roundup(crypto_shash_digestsize(TFM))
#define round16(x) (((x) + 15) & ~15)

42
crypto/krb5/krb5_api.c Normal file
View file

@ -0,0 +1,42 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/* Kerberos 5 crypto library.
*
* Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/export.h>
#include <linux/kernel.h>
#include "internal.h"
MODULE_DESCRIPTION("Kerberos 5 crypto");
MODULE_AUTHOR("Red Hat, Inc.");
MODULE_LICENSE("GPL");
static const struct krb5_enctype *const krb5_supported_enctypes[] = {
};
/**
* crypto_krb5_find_enctype - Find the handler for a Kerberos5 encryption type
* @enctype: The standard Kerberos encryption type number
*
* Look up a Kerberos encryption type by number. If successful, returns a
* pointer to the type tables; returns NULL otherwise.
*/
const struct krb5_enctype *crypto_krb5_find_enctype(u32 enctype)
{
const struct krb5_enctype *krb5;
size_t i;
for (i = 0; i < ARRAY_SIZE(krb5_supported_enctypes); i++) {
krb5 = krb5_supported_enctypes[i];
if (krb5->etype == enctype)
return krb5;
}
return NULL;
}
EXPORT_SYMBOL(crypto_krb5_find_enctype);

View file

@ -8,6 +8,12 @@
#ifndef _CRYPTO_KRB5_H
#define _CRYPTO_KRB5_H
#include <linux/crypto.h>
#include <crypto/aead.h>
struct crypto_shash;
struct scatterlist;
/*
* Per Kerberos v5 protocol spec crypto types from the wire. These get mapped
* to linux kernel crypto routines.
@ -48,4 +54,52 @@
#define KEY_USAGE_SEED_ENCRYPTION (0xAA)
#define KEY_USAGE_SEED_INTEGRITY (0x55)
/*
* Mode of operation.
*/
enum krb5_crypto_mode {
KRB5_CHECKSUM_MODE, /* Checksum only */
KRB5_ENCRYPT_MODE, /* Fully encrypted, possibly with integrity checksum */
};
struct krb5_buffer {
unsigned int len;
void *data;
};
/*
* Kerberos encoding type definition.
*/
struct krb5_enctype {
int etype; /* Encryption (key) type */
int ctype; /* Checksum type */
const char *name; /* "Friendly" name */
const char *encrypt_name; /* Crypto encrypt+checksum name */
const char *cksum_name; /* Crypto checksum name */
const char *hash_name; /* Crypto hash name */
const char *derivation_enc; /* Cipher used in key derivation */
u16 block_len; /* Length of encryption block */
u16 conf_len; /* Length of confounder (normally == block_len) */
u16 cksum_len; /* Length of checksum */
u16 key_bytes; /* Length of raw key, in bytes */
u16 key_len; /* Length of final key, in bytes */
u16 hash_len; /* Length of hash in bytes */
u16 prf_len; /* Length of PRF() result in bytes */
u16 Kc_len; /* Length of Kc in bytes */
u16 Ke_len; /* Length of Ke in bytes */
u16 Ki_len; /* Length of Ki in bytes */
bool keyed_cksum; /* T if a keyed cksum */
const struct krb5_crypto_profile *profile;
int (*random_to_key)(const struct krb5_enctype *krb5,
const struct krb5_buffer *in,
struct krb5_buffer *out); /* complete key generation */
};
/*
* krb5_api.c
*/
const struct krb5_enctype *crypto_krb5_find_enctype(u32 enctype);
#endif /* _CRYPTO_KRB5_H */