David Howells 742e38d4d4 crypto/krb5: Implement the Camellia enctypes from rfc6803
Implement the camellia128-cts-cmac and camellia256-cts-cmac enctypes from
rfc6803.

Note that the test vectors in rfc6803 for encryption are incomplete,
lacking the key usage number needed to derive Ke and Ki, and there are
errata for this:

	https://www.rfc-editor.org/errata_search.php?rfc=6803

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
2025-03-02 21:55:23 +00:00

161 lines
5.6 KiB
C

/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Kerberos 5 crypto
*
* Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*/
#ifndef _CRYPTO_KRB5_H
#define _CRYPTO_KRB5_H
#include <linux/crypto.h>
#include <crypto/aead.h>
#include <crypto/hash.h>
struct crypto_shash;
struct scatterlist;
/*
* Per Kerberos v5 protocol spec crypto types from the wire. These get mapped
* to linux kernel crypto routines.
*/
#define KRB5_ENCTYPE_NULL 0x0000
#define KRB5_ENCTYPE_DES_CBC_CRC 0x0001 /* DES cbc mode with CRC-32 */
#define KRB5_ENCTYPE_DES_CBC_MD4 0x0002 /* DES cbc mode with RSA-MD4 */
#define KRB5_ENCTYPE_DES_CBC_MD5 0x0003 /* DES cbc mode with RSA-MD5 */
#define KRB5_ENCTYPE_DES_CBC_RAW 0x0004 /* DES cbc mode raw */
/* XXX deprecated? */
#define KRB5_ENCTYPE_DES3_CBC_SHA 0x0005 /* DES-3 cbc mode with NIST-SHA */
#define KRB5_ENCTYPE_DES3_CBC_RAW 0x0006 /* DES-3 cbc mode raw */
#define KRB5_ENCTYPE_DES_HMAC_SHA1 0x0008
#define KRB5_ENCTYPE_DES3_CBC_SHA1 0x0010
#define KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96 0x0011
#define KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96 0x0012
#define KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128 0x0013
#define KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192 0x0014
#define KRB5_ENCTYPE_ARCFOUR_HMAC 0x0017
#define KRB5_ENCTYPE_ARCFOUR_HMAC_EXP 0x0018
#define KRB5_ENCTYPE_CAMELLIA128_CTS_CMAC 0x0019
#define KRB5_ENCTYPE_CAMELLIA256_CTS_CMAC 0x001a
#define KRB5_ENCTYPE_UNKNOWN 0x01ff
#define KRB5_CKSUMTYPE_CRC32 0x0001
#define KRB5_CKSUMTYPE_RSA_MD4 0x0002
#define KRB5_CKSUMTYPE_RSA_MD4_DES 0x0003
#define KRB5_CKSUMTYPE_DESCBC 0x0004
#define KRB5_CKSUMTYPE_RSA_MD5 0x0007
#define KRB5_CKSUMTYPE_RSA_MD5_DES 0x0008
#define KRB5_CKSUMTYPE_NIST_SHA 0x0009
#define KRB5_CKSUMTYPE_HMAC_SHA1_DES3 0x000c
#define KRB5_CKSUMTYPE_HMAC_SHA1_96_AES128 0x000f
#define KRB5_CKSUMTYPE_HMAC_SHA1_96_AES256 0x0010
#define KRB5_CKSUMTYPE_CMAC_CAMELLIA128 0x0011
#define KRB5_CKSUMTYPE_CMAC_CAMELLIA256 0x0012
#define KRB5_CKSUMTYPE_HMAC_SHA256_128_AES128 0x0013
#define KRB5_CKSUMTYPE_HMAC_SHA384_192_AES256 0x0014
#define KRB5_CKSUMTYPE_HMAC_MD5_ARCFOUR -138 /* Microsoft md5 hmac cksumtype */
/*
* Constants used for key derivation
*/
/* from rfc3961 */
#define KEY_USAGE_SEED_CHECKSUM (0x99)
#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);
size_t crypto_krb5_how_much_buffer(const struct krb5_enctype *krb5,
enum krb5_crypto_mode mode,
size_t data_size, size_t *_offset);
size_t crypto_krb5_how_much_data(const struct krb5_enctype *krb5,
enum krb5_crypto_mode mode,
size_t *_buffer_size, size_t *_offset);
void crypto_krb5_where_is_the_data(const struct krb5_enctype *krb5,
enum krb5_crypto_mode mode,
size_t *_offset, size_t *_len);
struct crypto_aead *crypto_krb5_prepare_encryption(const struct krb5_enctype *krb5,
const struct krb5_buffer *TK,
u32 usage, gfp_t gfp);
struct crypto_shash *crypto_krb5_prepare_checksum(const struct krb5_enctype *krb5,
const struct krb5_buffer *TK,
u32 usage, gfp_t gfp);
ssize_t crypto_krb5_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);
int crypto_krb5_decrypt(const struct krb5_enctype *krb5,
struct crypto_aead *aead,
struct scatterlist *sg, unsigned int nr_sg,
size_t *_offset, size_t *_len);
ssize_t crypto_krb5_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);
int crypto_krb5_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);
/*
* krb5_kdf.c
*/
int crypto_krb5_calc_PRFplus(const struct krb5_enctype *krb5,
const struct krb5_buffer *K,
unsigned int L,
const struct krb5_buffer *S,
struct krb5_buffer *result,
gfp_t gfp);
#endif /* _CRYPTO_KRB5_H */