mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
synced 2025-08-27 06:50:37 +00:00

Add API documentation for the 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
263 lines
8.7 KiB
ReStructuredText
263 lines
8.7 KiB
ReStructuredText
.. SPDX-License-Identifier: GPL-2.0
|
|
|
|
===========================
|
|
Kerberos V Cryptography API
|
|
===========================
|
|
|
|
.. Contents:
|
|
|
|
- Overview.
|
|
- Small Buffer.
|
|
- Encoding Type.
|
|
- Key Derivation.
|
|
- PRF+ Calculation.
|
|
- Kc, Ke And Ki Derivation.
|
|
- Crypto Functions.
|
|
- Preparation Functions.
|
|
- Encryption Mode.
|
|
- Checksum Mode.
|
|
- The krb5enc AEAD algorithm
|
|
|
|
Overview
|
|
========
|
|
|
|
This API provides Kerberos 5-style cryptography for key derivation, encryption
|
|
and checksumming for use in network filesystems and can be used to implement
|
|
the low-level crypto that's needed for GSSAPI.
|
|
|
|
The following crypto types are supported::
|
|
|
|
KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96
|
|
KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96
|
|
KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128
|
|
KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192
|
|
KRB5_ENCTYPE_CAMELLIA128_CTS_CMAC
|
|
KRB5_ENCTYPE_CAMELLIA256_CTS_CMAC
|
|
|
|
KRB5_CKSUMTYPE_HMAC_SHA1_96_AES128
|
|
KRB5_CKSUMTYPE_HMAC_SHA1_96_AES256
|
|
KRB5_CKSUMTYPE_CMAC_CAMELLIA128
|
|
KRB5_CKSUMTYPE_CMAC_CAMELLIA256
|
|
KRB5_CKSUMTYPE_HMAC_SHA256_128_AES128
|
|
KRB5_CKSUMTYPE_HMAC_SHA384_192_AES256
|
|
|
|
The API can be included by::
|
|
|
|
#include <crypto/krb5.h>
|
|
|
|
Small Buffer
|
|
------------
|
|
|
|
To pass small pieces of data about, such as keys, a buffer structure is
|
|
defined, giving a pointer to the data and the size of that data::
|
|
|
|
struct krb5_buffer {
|
|
unsigned int len;
|
|
void *data;
|
|
};
|
|
|
|
Encoding Type
|
|
=============
|
|
|
|
The encoding type is defined by the following structure::
|
|
|
|
struct krb5_enctype {
|
|
int etype;
|
|
int ctype;
|
|
const char *name;
|
|
u16 key_bytes;
|
|
u16 key_len;
|
|
u16 Kc_len;
|
|
u16 Ke_len;
|
|
u16 Ki_len;
|
|
u16 prf_len;
|
|
u16 block_len;
|
|
u16 conf_len;
|
|
u16 cksum_len;
|
|
...
|
|
};
|
|
|
|
The fields of interest to the user of the API are as follows:
|
|
|
|
* ``etype`` and ``ctype`` indicate the protocol number for this encoding
|
|
type for encryption and checksumming respectively. They hold
|
|
``KRB5_ENCTYPE_*`` and ``KRB5_CKSUMTYPE_*`` constants.
|
|
|
|
* ``name`` is the formal name of the encoding.
|
|
|
|
* ``key_len`` and ``key_bytes`` are the input key length and the derived key
|
|
length. (I think they only differ for DES, which isn't supported here).
|
|
|
|
* ``Kc_len``, ``Ke_len`` and ``Ki_len`` are the sizes of the derived Kc, Ke
|
|
and Ki keys. Kc is used for in checksum mode; Ke and Ki are used in
|
|
encryption mode.
|
|
|
|
* ``prf_len`` is the size of the result from the PRF+ function calculation.
|
|
|
|
* ``block_len``, ``conf_len`` and ``cksum_len`` are the encryption block
|
|
length, confounder length and checksum length respectively. All three are
|
|
used in encryption mode, but only the checksum length is used in checksum
|
|
mode.
|
|
|
|
The encoding type is looked up by number using the following function::
|
|
|
|
const struct krb5_enctype *crypto_krb5_find_enctype(u32 enctype);
|
|
|
|
Key Derivation
|
|
==============
|
|
|
|
Once the application has selected an encryption type, the keys that will be
|
|
used to do the actual crypto can be derived from the transport key.
|
|
|
|
PRF+ Calculation
|
|
----------------
|
|
|
|
To aid in key derivation, a function to calculate the Kerberos GSSAPI
|
|
mechanism's PRF+ is provided::
|
|
|
|
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);
|
|
|
|
This can be used to derive the transport key from a source key plus additional
|
|
data to limit its use.
|
|
|
|
Crypto Functions
|
|
================
|
|
|
|
Once the keys have been derived, crypto can be performed on the data. The
|
|
caller must leave gaps in the buffer for the storage of the confounder (if
|
|
needed) and the checksum when preparing a message for transmission. An enum
|
|
and a pair of functions are provided to aid in this::
|
|
|
|
enum krb5_crypto_mode {
|
|
KRB5_CHECKSUM_MODE,
|
|
KRB5_ENCRYPT_MODE,
|
|
};
|
|
|
|
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);
|
|
|
|
All these functions take the encoding type and an indication the mode of crypto
|
|
(checksum-only or full encryption).
|
|
|
|
The first function returns how big the buffer will need to be to house a given
|
|
amount of data; the second function returns how much data will fit in a buffer
|
|
of a particular size, and adjusts down the size of the required buffer
|
|
accordingly. In both cases, the offset of the data within the buffer is also
|
|
returned.
|
|
|
|
When a message has been received, the location and size of the data with the
|
|
message can be determined by calling::
|
|
|
|
void crypto_krb5_where_is_the_data(const struct krb5_enctype *krb5,
|
|
enum krb5_crypto_mode mode,
|
|
size_t *_offset, size_t *_len);
|
|
|
|
The caller provides the offset and length of the message to the function, which
|
|
then alters those values to indicate the region containing the data (plus any
|
|
padding). It is up to the caller to determine how much padding there is.
|
|
|
|
Preparation Functions
|
|
---------------------
|
|
|
|
Two functions are provided to allocated and prepare a crypto object for use by
|
|
the action functions::
|
|
|
|
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);
|
|
|
|
Both of these functions take the encoding type, the transport key and the usage
|
|
value used to derive the appropriate subkey(s). They create an appropriate
|
|
crypto object, an AEAD template for encryption and a synchronous hash for
|
|
checksumming, set the key(s) on it and configure it. The caller is expected to
|
|
pass these handles to the action functions below.
|
|
|
|
Encryption Mode
|
|
---------------
|
|
|
|
A pair of functions are provided to encrypt and decrypt a message::
|
|
|
|
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);
|
|
|
|
In both cases, the input and output buffers are indicated by the same
|
|
scatterlist.
|
|
|
|
For the encryption function, the output buffer may be larger than is needed
|
|
(the amount of output generated is returned) and the location and size of the
|
|
data are indicated (which must match the encoding). If no confounder is set,
|
|
the function will insert one.
|
|
|
|
For the decryption function, the offset and length of the message in buffer are
|
|
supplied and these are shrunk to fit the data. The decryption function will
|
|
verify any checksums within the message and give an error if they don't match.
|
|
|
|
Checksum Mode
|
|
-------------
|
|
|
|
A pair of function are provided to generate the checksum on a message and to
|
|
verify that checksum::
|
|
|
|
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);
|
|
|
|
In both cases, the input and output buffers are indicated by the same
|
|
scatterlist. Additional metadata can be passed in which will get added to the
|
|
hash before the data.
|
|
|
|
For the get_mic function, the output buffer may be larger than is needed (the
|
|
amount of output generated is returned) and the location and size of the data
|
|
are indicated (which must match the encoding).
|
|
|
|
For the verification function, the offset and length of the message in buffer
|
|
are supplied and these are shrunk to fit the data. An error will be returned
|
|
if the checksums don't match.
|
|
|
|
The krb5enc AEAD algorithm
|
|
==========================
|
|
|
|
A template AEAD crypto algorithm, called "krb5enc", is provided that hashes the
|
|
plaintext before encrypting it (the reverse of authenc). The handle returned
|
|
by ``crypto_krb5_prepare_encryption()`` may be one of these, but there's no
|
|
requirement for the user of this API to interact with it directly.
|
|
|
|
For reference, its key format begins with a BE32 of the format number. Only
|
|
format 1 is provided and that continues with a BE32 of the Ke key length
|
|
followed by a BE32 of the Ki key length, followed by the bytes from the Ke key
|
|
and then the Ki key.
|
|
|
|
Using specifically ordered words means that the static test data doesn't
|
|
require byteswapping.
|