<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Kerberos V Cryptography API — The Linux Kernel documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=fa44fd50" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=3918102e" />
<script src="../_static/documentation_options.js?v=5929fcd5"></script>
<script src="../_static/doctools.js?v=9bcbadda"></script>
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="BPF Documentation" href="../bpf/index.html" />
<link rel="prev" title="octeontx2 devlink support" href="device_drivers/octeontx2.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/logo.svg" alt="Logo of The Linux Kernel"/>
</a></p>
<h1 class="logo"><a href="../index.html">The Linux Kernel</a></h1>
<p class="blurb">6.18.50</p>
<search id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script>
<p>
<h3 class="kernel-toc-contents">Contents</h3>
<input type="checkbox" class="kernel-toc-toggle" id = "kernel-toc-toggle" checked>
<label class="kernel-toc-title" for="kernel-toc-toggle"></label>
<div class="kerneltoc" id="kerneltoc">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../process/development-process.html">Development process</a></li>
<li class="toctree-l1"><a class="reference internal" href="../process/submitting-patches.html">Submitting patches</a></li>
<li class="toctree-l1"><a class="reference internal" href="../process/code-of-conduct.html">Code of conduct</a></li>
<li class="toctree-l1"><a class="reference internal" href="../maintainer/index.html">Maintainer handbook</a></li>
<li class="toctree-l1"><a class="reference internal" href="../process/index.html">All development-process docs</a></li>
</ul>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../core-api/index.html">Core API</a></li>
<li class="toctree-l1"><a class="reference internal" href="../driver-api/index.html">Driver APIs</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../subsystem-apis.html">Subsystems</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../subsystem-apis.html#core-subsystems">Core subsystems</a></li>
<li class="toctree-l2"><a class="reference internal" href="../subsystem-apis.html#human-interfaces">Human interfaces</a></li>
<li class="toctree-l2"><a class="reference internal" href="../subsystem-apis.html#networking-interfaces">Networking interfaces</a></li>
<li class="toctree-l2"><a class="reference internal" href="../subsystem-apis.html#storage-interfaces">Storage interfaces</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="../subsystem-apis.html#other-subsystems">Other subsystems</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="../accounting/index.html">Accounting</a></li>
<li class="toctree-l3"><a class="reference internal" href="../cpu-freq/index.html">CPUFreq - CPU frequency and voltage scaling code in the Linux(TM) kernel</a></li>
<li class="toctree-l3"><a class="reference internal" href="../edac/index.html">EDAC Subsystem</a></li>
<li class="toctree-l3"><a class="reference internal" href="../fpga/index.html">FPGA</a></li>
<li class="toctree-l3"><a class="reference internal" href="../i2c/index.html">I2C/SMBus Subsystem</a></li>
<li class="toctree-l3"><a class="reference internal" href="../iio/index.html">Industrial I/O</a></li>
<li class="toctree-l3"><a class="reference internal" href="../pcmcia/index.html">PCMCIA</a></li>
<li class="toctree-l3"><a class="reference internal" href="../spi/index.html">Serial Peripheral Interface (SPI)</a></li>
<li class="toctree-l3"><a class="reference internal" href="../w1/index.html">1-Wire Subsystem</a></li>
<li class="toctree-l3"><a class="reference internal" href="../watchdog/index.html">Watchdog Support</a></li>
<li class="toctree-l3"><a class="reference internal" href="../virt/index.html">Virtualization Support</a></li>
<li class="toctree-l3"><a class="reference internal" href="../hwmon/index.html">Hardware Monitoring</a></li>
<li class="toctree-l3"><a class="reference internal" href="../accel/index.html">Compute Accelerators</a></li>
<li class="toctree-l3"><a class="reference internal" href="../security/index.html">Security Documentation</a></li>
<li class="toctree-l3 current"><a class="reference internal" href="index.html">Crypto API</a></li>
<li class="toctree-l3"><a class="reference internal" href="../bpf/index.html">BPF Documentation</a></li>
<li class="toctree-l3"><a class="reference internal" href="../usb/index.html">USB support</a></li>
<li class="toctree-l3"><a class="reference internal" href="../PCI/index.html">PCI Bus Subsystem</a></li>
<li class="toctree-l3"><a class="reference internal" href="../misc-devices/index.html">Assorted Miscellaneous Devices Documentation</a></li>
<li class="toctree-l3"><a class="reference internal" href="../peci/index.html">PECI Subsystem</a></li>
<li class="toctree-l3"><a class="reference internal" href="../wmi/index.html">WMI Subsystem</a></li>
<li class="toctree-l3"><a class="reference internal" href="../tee/index.html">TEE Subsystem</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../locking/index.html">Locking</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../process/license-rules.html">Licensing rules</a></li>
<li class="toctree-l1"><a class="reference internal" href="../doc-guide/index.html">Writing documentation</a></li>
<li class="toctree-l1"><a class="reference internal" href="../dev-tools/index.html">Development tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="../dev-tools/testing-overview.html">Testing guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../kernel-hacking/index.html">Hacking guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../trace/index.html">Tracing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../fault-injection/index.html">Fault injection</a></li>
<li class="toctree-l1"><a class="reference internal" href="../livepatch/index.html">Livepatching</a></li>
<li class="toctree-l1"><a class="reference internal" href="../rust/index.html">Rust</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../admin-guide/index.html">Administration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../kbuild/index.html">Build system</a></li>
<li class="toctree-l1"><a class="reference internal" href="../admin-guide/reporting-issues.html">Reporting issues</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tools/index.html">Userspace tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="../userspace-api/index.html">Userspace API</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../firmware-guide/index.html">Firmware</a></li>
<li class="toctree-l1"><a class="reference internal" href="../devicetree/index.html">Firmware and Devicetree</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../arch/index.html">CPU architectures</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../staging/index.html">Unsorted documentation</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../translations/index.html">Translations</a></li>
</ul>
</div>
<script type="text/javascript"> <!--
var sbar = document.getElementsByClassName("sphinxsidebar")[0];
let currents = document.getElementsByClassName("current")
if (currents.length) {
sbar.scrollTop = currents[currents.length - 1].offsetTop;
}
--> </script>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/crypto/krb5.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
</div>
</div>
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="kerberos-v-cryptography-api">
<h1>Kerberos V Cryptography API<a class="headerlink" href="#kerberos-v-cryptography-api" title="Link to this heading">¶</a></h1>
<section id="overview">
<h2>Overview<a class="headerlink" href="#overview" title="Link to this heading">¶</a></h2>
<p>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.</p>
<p>The following crypto types are supported:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>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
</pre></div>
</div>
<p>The API can be included by:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>#include <crypto/krb5.h>
</pre></div>
</div>
<section id="small-buffer">
<h3>Small Buffer<a class="headerlink" href="#small-buffer" title="Link to this heading">¶</a></h3>
<p>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:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>struct krb5_buffer {
unsigned int len;
void *data;
};
</pre></div>
</div>
</section>
</section>
<section id="encoding-type">
<h2>Encoding Type<a class="headerlink" href="#encoding-type" title="Link to this heading">¶</a></h2>
<p>The encoding type is defined by the following structure:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>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;
...
};
</pre></div>
</div>
<p>The fields of interest to the user of the API are as follows:</p>
<blockquote>
<div><ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">etype</span></code> and <code class="docutils literal notranslate"><span class="pre">ctype</span></code> indicate the protocol number for this encoding
type for encryption and checksumming respectively. They hold
<code class="docutils literal notranslate"><span class="pre">KRB5_ENCTYPE_*</span></code> and <code class="docutils literal notranslate"><span class="pre">KRB5_CKSUMTYPE_*</span></code> constants.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">name</span></code> is the formal name of the encoding.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">key_len</span></code> and <code class="docutils literal notranslate"><span class="pre">key_bytes</span></code> are the input key length and the derived key
length. (I think they only differ for DES, which isn’t supported here).</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">Kc_len</span></code>, <code class="docutils literal notranslate"><span class="pre">Ke_len</span></code> and <code class="docutils literal notranslate"><span class="pre">Ki_len</span></code> 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.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">prf_len</span></code> is the size of the result from the PRF+ function calculation.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">block_len</span></code>, <code class="docutils literal notranslate"><span class="pre">conf_len</span></code> and <code class="docutils literal notranslate"><span class="pre">cksum_len</span></code> 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.</p></li>
</ul>
</div></blockquote>
<p>The encoding type is looked up by number using the following function:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>const struct krb5_enctype *crypto_krb5_find_enctype(u32 enctype);
</pre></div>
</div>
</section>
<section id="key-derivation">
<h2>Key Derivation<a class="headerlink" href="#key-derivation" title="Link to this heading">¶</a></h2>
<p>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.</p>
<section id="prf-calculation">
<h3>PRF+ Calculation<a class="headerlink" href="#prf-calculation" title="Link to this heading">¶</a></h3>
<p>To aid in key derivation, a function to calculate the Kerberos GSSAPI
mechanism’s PRF+ is provided:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>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);
</pre></div>
</div>
<p>This can be used to derive the transport key from a source key plus additional
data to limit its use.</p>
</section>
</section>
<section id="crypto-functions">
<h2>Crypto Functions<a class="headerlink" href="#crypto-functions" title="Link to this heading">¶</a></h2>
<p>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 <code class="xref c c-enum broken_xref docutils literal notranslate"><span class="pre">enum</span>
<span class="pre">and</span></code> a pair of functions are provided to aid in this:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>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);
</pre></div>
</div>
<p>All these functions take the encoding type and an indication the mode of crypto
(checksum-only or full encryption).</p>
<p>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.</p>
<p>When a message has been received, the location and size of the data with the
message can be determined by calling:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>int crypto_krb5_where_is_the_data(const struct krb5_enctype *krb5,
enum krb5_crypto_mode mode,
size_t *_offset, size_t *_len);
</pre></div>
</div>
<p>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. The
function returns an error if the length is too small or if the mode is
unsupported. An additional function:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>int crypto_krb5_check_data_len(const struct krb5_enctype *krb5,
enum krb5_crypto_mode mode,
size_t len, size_t min_content);
</pre></div>
</div>
<p>is provided to just do a basic check that the decrypted/verified message would
have a sufficient minimum payload.</p>
<section id="preparation-functions">
<h3>Preparation Functions<a class="headerlink" href="#preparation-functions" title="Link to this heading">¶</a></h3>
<p>Two functions are provided to allocated and prepare a crypto object for use by
the action functions:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>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);
</pre></div>
</div>
<p>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.</p>
</section>
<section id="encryption-mode">
<h3>Encryption Mode<a class="headerlink" href="#encryption-mode" title="Link to this heading">¶</a></h3>
<p>A pair of functions are provided to encrypt and decrypt a message:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>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);
</pre></div>
</div>
<p>In both cases, the input and output buffers are indicated by the same
scatterlist.</p>
<p>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.</p>
<p>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.</p>
</section>
<section id="checksum-mode">
<h3>Checksum Mode<a class="headerlink" href="#checksum-mode" title="Link to this heading">¶</a></h3>
<p>A pair of function are provided to generate the checksum on a message and to
verify that checksum:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>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);
</pre></div>
</div>
<p>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.</p>
<p>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).</p>
<p>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.</p>
</section>
</section>
<section id="the-krb5enc-aead-algorithm">
<h2>The krb5enc AEAD algorithm<a class="headerlink" href="#the-krb5enc-aead-algorithm" title="Link to this heading">¶</a></h2>
<p>A template AEAD crypto algorithm, called “krb5enc”, is provided that hashes the
plaintext before encrypting it (the reverse of authenc). The handle returned
by <code class="docutils literal notranslate"><span class="pre">crypto_krb5_prepare_encryption()</span></code> may be one of these, but there’s no
requirement for the user of this API to interact with it directly.</p>
<p>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.</p>
<p>Using specifically ordered words means that the static test data doesn’t
require byteswapping.</p>
</section>
</section>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
©The kernel development community.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 8.1.3</a>
& <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a>
|
<a href="../_sources/crypto/krb5.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>