__ __ __ __ _____ _ _ _____ _ _ _ | \/ | \ \ / / | __ \ (_) | | / ____| | | | | | \ / |_ __\ V / | |__) | __ ___ ____ _| |_ ___ | (___ | |__ ___| | | | |\/| | '__|> < | ___/ '__| \ \ / / _` | __/ _ \ \___ \| '_ \ / _ \ | | | | | | |_ / . \ | | | | | |\ V / (_| | || __/ ____) | | | | __/ | | |_| |_|_(_)_/ \_\ |_| |_| |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1 if you need WebShell for Seo everyday contact me on Telegram Telegram Address : @jackleetFor_More_Tools:
<!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>Kernel TLS — 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="Kernel TLS offload" href="tls-offload.html" />
<link rel="prev" title="Scaling in the Linux Networking Stack" href="scaling.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 current"><a class="reference internal" href="../subsystem-apis.html#networking-interfaces">Networking interfaces</a><ul class="current">
<li class="toctree-l3 current"><a class="reference internal" href="index.html">Networking</a></li>
<li class="toctree-l3"><a class="reference internal" href="../netlabel/index.html">NetLabel</a></li>
<li class="toctree-l3"><a class="reference internal" href="../infiniband/index.html">InfiniBand</a></li>
<li class="toctree-l3"><a class="reference internal" href="../isdn/index.html">ISDN</a></li>
<li class="toctree-l3"><a class="reference internal" href="../mhi/index.html">MHI</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../subsystem-apis.html#storage-interfaces">Storage interfaces</a></li>
<li class="toctree-l2"><a class="reference internal" href="../subsystem-apis.html#other-subsystems">Other subsystems</a></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/networking/tls.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="kernel-tls">
<span id="id1"></span><h1>Kernel TLS<a class="headerlink" href="#kernel-tls" 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>Transport Layer Security (TLS) is a Upper Layer Protocol (ULP) that runs over
TCP. TLS provides end-to-end data integrity and confidentiality.</p>
</section>
<section id="user-interface">
<h2>User interface<a class="headerlink" href="#user-interface" title="Link to this heading">¶</a></h2>
<section id="creating-a-tls-connection">
<h3>Creating a TLS connection<a class="headerlink" href="#creating-a-tls-connection" title="Link to this heading">¶</a></h3>
<p>First create a new TCP socket and once the connection is established set the
TLS ULP.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">sock</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">socket</span><span class="p">(</span><span class="n">AF_INET</span><span class="p">,</span><span class="w"> </span><span class="n">SOCK_STREAM</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
<span class="n">connect</span><span class="p">(</span><span class="n">sock</span><span class="p">,</span><span class="w"> </span><span class="n">addr</span><span class="p">,</span><span class="w"> </span><span class="n">addrlen</span><span class="p">);</span>
<span class="n">setsockopt</span><span class="p">(</span><span class="n">sock</span><span class="p">,</span><span class="w"> </span><span class="n">SOL_TCP</span><span class="p">,</span><span class="w"> </span><span class="n">TCP_ULP</span><span class="p">,</span><span class="w"> </span><span class="s">"tls"</span><span class="p">,</span><span class="w"> </span><span class="k">sizeof</span><span class="p">(</span><span class="s">"tls"</span><span class="p">));</span>
</pre></div>
</div>
<p>Setting the TLS ULP allows us to set/get TLS socket options. Currently
only the symmetric encryption is handled in the kernel. After the TLS
handshake is complete, we have all the parameters required to move the
data-path to the kernel. There is a separate socket option for moving
the transmit and the receive into the kernel.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/* From linux/tls.h */</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">tls_crypto_info</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">short</span><span class="w"> </span><span class="n">version</span><span class="p">;</span>
<span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">short</span><span class="w"> </span><span class="n">cipher_type</span><span class="p">;</span>
<span class="p">};</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">tls12_crypto_info_aes_gcm_128</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">tls_crypto_info</span><span class="w"> </span><span class="n">info</span><span class="p">;</span>
<span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="n">iv</span><span class="p">[</span><span class="n">TLS_CIPHER_AES_GCM_128_IV_SIZE</span><span class="p">];</span>
<span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="n">key</span><span class="p">[</span><span class="n">TLS_CIPHER_AES_GCM_128_KEY_SIZE</span><span class="p">];</span>
<span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="n">salt</span><span class="p">[</span><span class="n">TLS_CIPHER_AES_GCM_128_SALT_SIZE</span><span class="p">];</span>
<span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="n">rec_seq</span><span class="p">[</span><span class="n">TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE</span><span class="p">];</span>
<span class="p">};</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">tls12_crypto_info_aes_gcm_128</span><span class="w"> </span><span class="n">crypto_info</span><span class="p">;</span>
<span class="n">crypto_info</span><span class="p">.</span><span class="n">info</span><span class="p">.</span><span class="n">version</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">TLS_1_2_VERSION</span><span class="p">;</span>
<span class="n">crypto_info</span><span class="p">.</span><span class="n">info</span><span class="p">.</span><span class="n">cipher_type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">TLS_CIPHER_AES_GCM_128</span><span class="p">;</span>
<span class="n">memcpy</span><span class="p">(</span><span class="n">crypto_info</span><span class="p">.</span><span class="n">iv</span><span class="p">,</span><span class="w"> </span><span class="n">iv_write</span><span class="p">,</span><span class="w"> </span><span class="n">TLS_CIPHER_AES_GCM_128_IV_SIZE</span><span class="p">);</span>
<span class="n">memcpy</span><span class="p">(</span><span class="n">crypto_info</span><span class="p">.</span><span class="n">rec_seq</span><span class="p">,</span><span class="w"> </span><span class="n">seq_number_write</span><span class="p">,</span>
<span class="w"> </span><span class="n">TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE</span><span class="p">);</span>
<span class="n">memcpy</span><span class="p">(</span><span class="n">crypto_info</span><span class="p">.</span><span class="n">key</span><span class="p">,</span><span class="w"> </span><span class="n">cipher_key_write</span><span class="p">,</span><span class="w"> </span><span class="n">TLS_CIPHER_AES_GCM_128_KEY_SIZE</span><span class="p">);</span>
<span class="n">memcpy</span><span class="p">(</span><span class="n">crypto_info</span><span class="p">.</span><span class="n">salt</span><span class="p">,</span><span class="w"> </span><span class="n">implicit_iv_write</span><span class="p">,</span><span class="w"> </span><span class="n">TLS_CIPHER_AES_GCM_128_SALT_SIZE</span><span class="p">);</span>
<span class="n">setsockopt</span><span class="p">(</span><span class="n">sock</span><span class="p">,</span><span class="w"> </span><span class="n">SOL_TLS</span><span class="p">,</span><span class="w"> </span><span class="n">TLS_TX</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">crypto_info</span><span class="p">,</span><span class="w"> </span><span class="k">sizeof</span><span class="p">(</span><span class="n">crypto_info</span><span class="p">));</span>
</pre></div>
</div>
<p>Transmit and receive are set separately, but the setup is the same, using either
TLS_TX or TLS_RX.</p>
</section>
<section id="sending-tls-application-data">
<h3>Sending TLS application data<a class="headerlink" href="#sending-tls-application-data" title="Link to this heading">¶</a></h3>
<p>After setting the TLS_TX socket option all application data sent over this
socket is encrypted using TLS and the parameters provided in the socket option.
For example, we can send an encrypted hello world record as follows:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">msg</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">"hello world</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
<span class="n">send</span><span class="p">(</span><span class="n">sock</span><span class="p">,</span><span class="w"> </span><span class="n">msg</span><span class="p">,</span><span class="w"> </span><span class="n">strlen</span><span class="p">(</span><span class="n">msg</span><span class="p">));</span>
</pre></div>
</div>
<p><code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">send()</span></code> data is directly encrypted from the userspace buffer provided
to the encrypted kernel send buffer if possible.</p>
<p>The sendfile system call will send the file’s data over TLS records of maximum
length (2^14).</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">open</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span><span class="w"> </span><span class="n">O_RDONLY</span><span class="p">);</span>
<span class="n">fstat</span><span class="p">(</span><span class="n">file</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">stat</span><span class="p">);</span>
<span class="n">sendfile</span><span class="p">(</span><span class="n">sock</span><span class="p">,</span><span class="w"> </span><span class="n">file</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">offset</span><span class="p">,</span><span class="w"> </span><span class="n">stat</span><span class="p">.</span><span class="n">st_size</span><span class="p">);</span>
</pre></div>
</div>
<p>TLS records are created and sent after each <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">send()</span></code> call, unless
MSG_MORE is passed. MSG_MORE will delay creation of a record until
MSG_MORE is not passed, or the maximum record size is reached.</p>
<p>The kernel will need to allocate a buffer for the encrypted data.
This buffer is allocated at the time <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">send()</span></code> is called, such that
either the entire <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">send()</span></code> call will return -ENOMEM (or block waiting
for memory), or the encryption will always succeed. If <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">send()</span></code> returns
-ENOMEM and some data was left on the socket buffer from a previous
call using MSG_MORE, the MSG_MORE data is left on the socket buffer.</p>
</section>
<section id="receiving-tls-application-data">
<h3>Receiving TLS application data<a class="headerlink" href="#receiving-tls-application-data" title="Link to this heading">¶</a></h3>
<p>After setting the TLS_RX socket option, all recv family socket calls
are decrypted using TLS parameters provided. A full TLS record must
be received before decryption can happen.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">char</span><span class="w"> </span><span class="n">buffer</span><span class="p">[</span><span class="mi">16384</span><span class="p">];</span>
<span class="n">recv</span><span class="p">(</span><span class="n">sock</span><span class="p">,</span><span class="w"> </span><span class="n">buffer</span><span class="p">,</span><span class="w"> </span><span class="mi">16384</span><span class="p">);</span>
</pre></div>
</div>
<p>Received data is decrypted directly in to the user buffer if it is
large enough, and no additional allocations occur. If the userspace
buffer is too small, data is decrypted in the kernel and copied to
userspace.</p>
<p><code class="docutils literal notranslate"><span class="pre">EINVAL</span></code> is returned if the TLS version in the received message does not
match the version passed in setsockopt.</p>
<p><code class="docutils literal notranslate"><span class="pre">EMSGSIZE</span></code> is returned if the received message is too big.</p>
<p><code class="docutils literal notranslate"><span class="pre">EBADMSG</span></code> is returned if decryption failed for any other reason.</p>
</section>
<section id="send-tls-control-messages">
<h3>Send TLS control messages<a class="headerlink" href="#send-tls-control-messages" title="Link to this heading">¶</a></h3>
<p>Other than application data, TLS has control messages such as alert
messages (record type 21) and handshake messages (record type 22), etc.
These messages can be sent over the socket by providing the TLS record type
via a CMSG. For example the following function sends @data of @length bytes
using a record of type @record_type.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/* send TLS control message using record_type */</span>
<span class="k">static</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="nf">klts_send_ctrl_message</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">sock</span><span class="p">,</span><span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="n">record_type</span><span class="p">,</span>
<span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">data</span><span class="p">,</span><span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">length</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">msghdr</span><span class="w"> </span><span class="n">msg</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">cmsg_len</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">sizeof</span><span class="p">(</span><span class="n">record_type</span><span class="p">);</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">cmsghdr</span><span class="w"> </span><span class="o">*</span><span class="n">cmsg</span><span class="p">;</span>
<span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="n">buf</span><span class="p">[</span><span class="n">CMSG_SPACE</span><span class="p">(</span><span class="n">cmsg_len</span><span class="p">)];</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">iovec</span><span class="w"> </span><span class="n">msg_iov</span><span class="p">;</span><span class="w"> </span><span class="cm">/* Vector of data to send/receive into. */</span>
<span class="w"> </span><span class="n">msg</span><span class="p">.</span><span class="n">msg_control</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">buf</span><span class="p">;</span>
<span class="w"> </span><span class="n">msg</span><span class="p">.</span><span class="n">msg_controllen</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">sizeof</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span>
<span class="w"> </span><span class="n">cmsg</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">CMSG_FIRSTHDR</span><span class="p">(</span><span class="o">&</span><span class="n">msg</span><span class="p">);</span>
<span class="w"> </span><span class="n">cmsg</span><span class="o">-></span><span class="n">cmsg_level</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">SOL_TLS</span><span class="p">;</span>
<span class="w"> </span><span class="n">cmsg</span><span class="o">-></span><span class="n">cmsg_type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">TLS_SET_RECORD_TYPE</span><span class="p">;</span>
<span class="w"> </span><span class="n">cmsg</span><span class="o">-></span><span class="n">cmsg_len</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">CMSG_LEN</span><span class="p">(</span><span class="n">cmsg_len</span><span class="p">);</span>
<span class="w"> </span><span class="o">*</span><span class="n">CMSG_DATA</span><span class="p">(</span><span class="n">cmsg</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">record_type</span><span class="p">;</span>
<span class="w"> </span><span class="n">msg</span><span class="p">.</span><span class="n">msg_controllen</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cmsg</span><span class="o">-></span><span class="n">cmsg_len</span><span class="p">;</span>
<span class="w"> </span><span class="n">msg_iov</span><span class="p">.</span><span class="n">iov_base</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">data</span><span class="p">;</span>
<span class="w"> </span><span class="n">msg_iov</span><span class="p">.</span><span class="n">iov_len</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">length</span><span class="p">;</span>
<span class="w"> </span><span class="n">msg</span><span class="p">.</span><span class="n">msg_iov</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&</span><span class="n">msg_iov</span><span class="p">;</span>
<span class="w"> </span><span class="n">msg</span><span class="p">.</span><span class="n">msg_iovlen</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">sendmsg</span><span class="p">(</span><span class="n">sock</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">msg</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Control message data should be provided unencrypted, and will be
encrypted by the kernel.</p>
</section>
<section id="receiving-tls-control-messages">
<h3>Receiving TLS control messages<a class="headerlink" href="#receiving-tls-control-messages" title="Link to this heading">¶</a></h3>
<p>TLS control messages are passed in the userspace buffer, with message
type passed via cmsg. If no cmsg buffer is provided, an error is
returned if a control message is received. Data messages may be
received without a cmsg buffer set.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">char</span><span class="w"> </span><span class="n">buffer</span><span class="p">[</span><span class="mi">16384</span><span class="p">];</span>
<span class="kt">char</span><span class="w"> </span><span class="n">cmsg</span><span class="p">[</span><span class="n">CMSG_SPACE</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">char</span><span class="p">))];</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">msghdr</span><span class="w"> </span><span class="n">msg</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="n">msg</span><span class="p">.</span><span class="n">msg_control</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cmsg</span><span class="p">;</span>
<span class="n">msg</span><span class="p">.</span><span class="n">msg_controllen</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">sizeof</span><span class="p">(</span><span class="n">cmsg</span><span class="p">);</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">iovec</span><span class="w"> </span><span class="n">msg_iov</span><span class="p">;</span>
<span class="n">msg_iov</span><span class="p">.</span><span class="n">iov_base</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">buffer</span><span class="p">;</span>
<span class="n">msg_iov</span><span class="p">.</span><span class="n">iov_len</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">16384</span><span class="p">;</span>
<span class="n">msg</span><span class="p">.</span><span class="n">msg_iov</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&</span><span class="n">msg_iov</span><span class="p">;</span>
<span class="n">msg</span><span class="p">.</span><span class="n">msg_iovlen</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="kt">int</span><span class="w"> </span><span class="n">ret</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">recvmsg</span><span class="p">(</span><span class="n">sock</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">msg</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="cm">/* flags */</span><span class="p">);</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">cmsghdr</span><span class="w"> </span><span class="o">*</span><span class="n">cmsg</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">CMSG_FIRSTHDR</span><span class="p">(</span><span class="o">&</span><span class="n">msg</span><span class="p">);</span>
<span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">cmsg</span><span class="o">-></span><span class="n">cmsg_level</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">SOL_TLS</span><span class="w"> </span><span class="o">&&</span>
<span class="w"> </span><span class="n">cmsg</span><span class="o">-></span><span class="n">cmsg_type</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">TLS_GET_RECORD_TYPE</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">record_type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">*</span><span class="p">((</span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="p">)</span><span class="n">CMSG_DATA</span><span class="p">(</span><span class="n">cmsg</span><span class="p">));</span>
<span class="w"> </span><span class="c1">// Do something with record_type, and control message data in</span>
<span class="w"> </span><span class="c1">// buffer.</span>
<span class="w"> </span><span class="c1">//</span>
<span class="w"> </span><span class="c1">// Note that record_type may be == to application data (23).</span>
<span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="c1">// Buffer contains application data.</span>
<span class="p">}</span>
</pre></div>
</div>
<p>recv will never return data from mixed types of TLS records.</p>
</section>
<section id="tls-1-3-key-updates">
<h3>TLS 1.3 Key Updates<a class="headerlink" href="#tls-1-3-key-updates" title="Link to this heading">¶</a></h3>
<p>In TLS 1.3, KeyUpdate handshake messages signal that the sender is
updating its TX key. Any message sent after a KeyUpdate will be
encrypted using the new key. The userspace library can pass the new
key to the kernel using the TLS_TX and TLS_RX socket options, as for
the initial keys. TLS version and cipher cannot be changed.</p>
<p>To prevent attempting to decrypt incoming records using the wrong key,
decryption will be paused when a KeyUpdate message is received by the
kernel, until the new key has been provided using the TLS_RX socket
option. Any read occurring after the KeyUpdate has been read and
before the new key is provided will fail with EKEYEXPIRED. poll() will
not report any read events from the socket until the new key is
provided. There is no pausing on the transmit side.</p>
<p>Userspace should make sure that the crypto_info provided has been set
properly. In particular, the kernel will not check for key/nonce
reuse.</p>
<p>The number of successful and failed key updates is tracked in the
<code class="docutils literal notranslate"><span class="pre">TlsTxRekeyOk</span></code>, <code class="docutils literal notranslate"><span class="pre">TlsRxRekeyOk</span></code>, <code class="docutils literal notranslate"><span class="pre">TlsTxRekeyError</span></code>,
<code class="docutils literal notranslate"><span class="pre">TlsRxRekeyError</span></code> statistics. The <code class="docutils literal notranslate"><span class="pre">TlsRxRekeyReceived</span></code> statistic
counts KeyUpdate handshake messages that have been received.</p>
</section>
<section id="integrating-in-to-userspace-tls-library">
<h3>Integrating in to userspace TLS library<a class="headerlink" href="#integrating-in-to-userspace-tls-library" title="Link to this heading">¶</a></h3>
<p>At a high level, the kernel TLS ULP is a replacement for the record
layer of a userspace TLS library.</p>
<p>A patchset to OpenSSL to use ktls as the record layer is
<a class="reference external" href="https://github.com/Mellanox/openssl/commits/tls_rx2">here</a>.</p>
<p><a class="reference external" href="https://github.com/ktls/af_ktls-tool/commits/RX">An example</a>
of calling send directly after a handshake using gnutls.
Since it doesn’t implement a full record layer, control
messages are not supported.</p>
</section>
<section id="optional-optimizations">
<h3>Optional optimizations<a class="headerlink" href="#optional-optimizations" title="Link to this heading">¶</a></h3>
<p>There are certain condition-specific optimizations the TLS ULP can make,
if requested. Those optimizations are either not universally beneficial
or may impact correctness, hence they require an opt-in.
All options are set per-socket using <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">setsockopt()</span></code>, and their
state can be checked using <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">getsockopt()</span></code> and via socket diag (<code class="docutils literal notranslate"><span class="pre">ss</span></code>).</p>
<section id="tls-tx-zerocopy-ro">
<h4>TLS_TX_ZEROCOPY_RO<a class="headerlink" href="#tls-tx-zerocopy-ro" title="Link to this heading">¶</a></h4>
<p>For device offload only. Allow <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">sendfile()</span></code> data to be transmitted directly
to the NIC without making an in-kernel copy. This allows true zero-copy
behavior when device offload is enabled.</p>
<p>The application must make sure that the data is not modified between being
submitted and transmission completing. In other words this is mostly
applicable if the data sent on a socket via <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">sendfile()</span></code> is read-only.</p>
<p>Modifying the data may result in different versions of the data being used
for the original TCP transmission and TCP retransmissions. To the receiver
this will look like TLS records had been tampered with and will result
in record authentication failures.</p>
</section>
<section id="tls-rx-expect-no-pad">
<h4>TLS_RX_EXPECT_NO_PAD<a class="headerlink" href="#tls-rx-expect-no-pad" title="Link to this heading">¶</a></h4>
<p>TLS 1.3 only. Expect the sender to not pad records. This allows the data
to be decrypted directly into user space buffers with TLS 1.3.</p>
<p>This optimization is safe to enable only if the remote end is trusted,
otherwise it is an attack vector to doubling the TLS processing cost.</p>
<p>If the record decrypted turns out to had been padded or is not a data
record it will be decrypted again into a kernel buffer without zero copy.
Such events are counted in the <code class="docutils literal notranslate"><span class="pre">TlsDecryptRetry</span></code> statistic.</p>
</section>
</section>
</section>
<section id="statistics">
<h2>Statistics<a class="headerlink" href="#statistics" title="Link to this heading">¶</a></h2>
<p>TLS implementation exposes the following per-namespace statistics
(<code class="docutils literal notranslate"><span class="pre">/proc/net/tls_stat</span></code>):</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">TlsCurrTxSw</span></code>, <code class="docutils literal notranslate"><span class="pre">TlsCurrRxSw</span></code> -
number of TX and RX sessions currently installed where host handles
cryptography</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">TlsCurrTxDevice</span></code>, <code class="docutils literal notranslate"><span class="pre">TlsCurrRxDevice</span></code> -
number of TX and RX sessions currently installed where NIC handles
cryptography</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">TlsTxSw</span></code>, <code class="docutils literal notranslate"><span class="pre">TlsRxSw</span></code> -
number of TX and RX sessions opened with host cryptography</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">TlsTxDevice</span></code>, <code class="docutils literal notranslate"><span class="pre">TlsRxDevice</span></code> -
number of TX and RX sessions opened with NIC cryptography</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">TlsDecryptError</span></code> -
record decryption failed (e.g. due to incorrect authentication tag)</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">TlsDeviceRxResync</span></code> -
number of RX resyncs sent to NICs handling cryptography</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">TlsDecryptRetry</span></code> -
number of RX records which had to be re-decrypted due to
<code class="docutils literal notranslate"><span class="pre">TLS_RX_EXPECT_NO_PAD</span></code> mis-prediction. Note that this counter will
also increment for non-data records.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">TlsRxNoPadViolation</span></code> -
number of data RX records which had to be re-decrypted due to
<code class="docutils literal notranslate"><span class="pre">TLS_RX_EXPECT_NO_PAD</span></code> mis-prediction.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">TlsTxRekeyOk</span></code>, <code class="docutils literal notranslate"><span class="pre">TlsRxRekeyOk</span></code> -
number of successful rekeys on existing sessions for TX and RX</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">TlsTxRekeyError</span></code>, <code class="docutils literal notranslate"><span class="pre">TlsRxRekeyError</span></code> -
number of failed rekeys on existing sessions for TX and RX</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">TlsRxRekeyReceived</span></code> -
number of received KeyUpdate handshake messages, requiring userspace
to provide a new RX key</p></li>
</ul>
</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/networking/tls.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>| Name | Type | Size | Permission | Actions |
|---|---|---|---|---|
| caif | Folder | 0755 |
|
|
| device_drivers | Folder | 0755 |
|
|
| devlink | Folder | 0755 |
|
|
| diagnostic | Folder | 0755 |
|
|
| dsa | Folder | 0755 |
|
|
| mac80211_hwsim | Folder | 0755 |
|
|
| net_cachelines | Folder | 0755 |
|
|
| pse-pd | Folder | 0755 |
|
|
| 6lowpan.html | File | 9.97 KB | 0644 |
|
| 6pack.html | File | 18.06 KB | 0644 |
|
| af_xdp.html | File | 71.08 KB | 0644 |
|
| alias.html | File | 9.71 KB | 0644 |
|
| arcnet-hardware.html | File | 153.3 KB | 0644 |
|
| arcnet.html | File | 37.48 KB | 0644 |
|
| atm.html | File | 8.24 KB | 0644 |
|
| ax25.html | File | 8.75 KB | 0644 |
|
| bareudp.html | File | 10.56 KB | 0644 |
|
| batman-adv.html | File | 16.81 KB | 0644 |
|
| bonding.html | File | 140.89 KB | 0644 |
|
| bridge.html | File | 53.36 KB | 0644 |
|
| can.html | File | 120.11 KB | 0644 |
|
| can_ucan_protocol.html | File | 25.27 KB | 0644 |
|
| cdc_mbim.html | File | 25.28 KB | 0644 |
|
| checksum-offloads.html | File | 16.15 KB | 0644 |
|
| dctcp.html | File | 10.32 KB | 0644 |
|
| devmem.html | File | 24.33 KB | 0644 |
|
| dns_resolver.html | File | 15.11 KB | 0644 |
|
| driver.html | File | 20.41 KB | 0644 |
|
| eql.html | File | 31.48 KB | 0644 |
|
| ethtool-netlink.html | File | 274 KB | 0644 |
|
| failover.html | File | 8.43 KB | 0644 |
|
| fib_trie.html | File | 16.04 KB | 0644 |
|
| filter.html | File | 42.43 KB | 0644 |
|
| gen_stats.html | File | 14.2 KB | 0644 |
|
| generic-hdlc.html | File | 14.67 KB | 0644 |
|
| generic_netlink.html | File | 8.11 KB | 0644 |
|
| gtp.html | File | 20.55 KB | 0644 |
|
| ieee802154.html | File | 25.03 KB | 0644 |
|
| ila.html | File | 21.79 KB | 0644 |
|
| index.html | File | 108.18 KB | 0644 |
|
| ioam6-sysctl.html | File | 8.48 KB | 0644 |
|
| iou-zcrx.html | File | 16.63 KB | 0644 |
|
| ip-sysctl.html | File | 154.81 KB | 0644 |
|
| ip_dynaddr.html | File | 9.97 KB | 0644 |
|
| ipsec.html | File | 9.71 KB | 0644 |
|
| ipv6.html | File | 9.87 KB | 0644 |
|
| ipvlan.html | File | 16.87 KB | 0644 |
|
| ipvs-sysctl.html | File | 20.73 KB | 0644 |
|
| iso15765-2.html | File | 39.91 KB | 0644 |
|
| j1939.html | File | 99.33 KB | 0644 |
|
| kapi.html | File | 1.78 MB | 0644 |
|
| kcm.html | File | 21.67 KB | 0644 |
|
| l2tp.html | File | 47.74 KB | 0644 |
|
| lapb-module.html | File | 22.56 KB | 0644 |
|
| mac80211-injection.html | File | 12.37 KB | 0644 |
|
| mctp.html | File | 35.16 KB | 0644 |
|
| mpls-sysctl.html | File | 9.64 KB | 0644 |
|
| mptcp-sysctl.html | File | 13.33 KB | 0644 |
|
| mptcp.html | File | 19.74 KB | 0644 |
|
| msg_zerocopy.html | File | 19.72 KB | 0644 |
|
| multi-pf-netdev.html | File | 17.48 KB | 0644 |
|
| multiqueue.html | File | 13.21 KB | 0644 |
|
| napi.html | File | 43.36 KB | 0644 |
|
| net_dim.html | File | 76.45 KB | 0644 |
|
| net_failover.html | File | 16.3 KB | 0644 |
|
| netconsole.html | File | 31.44 KB | 0644 |
|
| netdev-features.html | File | 17.75 KB | 0644 |
|
| netdevices.html | File | 43.33 KB | 0644 |
|
| netfilter-sysctl.html | File | 8.43 KB | 0644 |
|
| netif-msg.html | File | 12.93 KB | 0644 |
|
| netmem.html | File | 14.84 KB | 0644 |
|
| nexthop-group-resilient.html | File | 24.56 KB | 0644 |
|
| nf_conntrack-sysctl.html | File | 15.77 KB | 0644 |
|
| nf_flowtable.html | File | 21.24 KB | 0644 |
|
| nfc.html | File | 13.73 KB | 0644 |
|
| oa-tc6-framework.html | File | 39.07 KB | 0644 |
|
| openvswitch.html | File | 21.15 KB | 0644 |
|
| operstates.html | File | 18.28 KB | 0644 |
|
| packet_mmap.html | File | 55.34 KB | 0644 |
|
| page_pool.html | File | 59.25 KB | 0644 |
|
| phonet.html | File | 16.92 KB | 0644 |
|
| phy-link-topology.html | File | 15.77 KB | 0644 |
|
| phy.html | File | 40.5 KB | 0644 |
|
| pktgen.html | File | 24.97 KB | 0644 |
|
| plip.html | File | 18.56 KB | 0644 |
|
| ppp_generic.html | File | 37.23 KB | 0644 |
|
| proc_net_tcp.html | File | 11.13 KB | 0644 |
|
| psp.html | File | 18.66 KB | 0644 |
|
| radiotap-headers.html | File | 14.73 KB | 0644 |
|
| rds.html | File | 29.39 KB | 0644 |
|
| regulatory.html | File | 18.44 KB | 0644 |
|
| representors.html | File | 25.79 KB | 0644 |
|
| rxrpc.html | File | 130.88 KB | 0644 |
|
| scaling.html | File | 40.25 KB | 0644 |
|
| sctp.html | File | 9.73 KB | 0644 |
|
| secid.html | File | 8.42 KB | 0644 |
|
| seg6-sysctl.html | File | 9.53 KB | 0644 |
|
| segmentation-offloads.html | File | 17.81 KB | 0644 |
|
| sfp-phylink.html | File | 41.09 KB | 0644 |
|
| skbuff.html | File | 29.22 KB | 0644 |
|
| smc-sysctl.html | File | 10.42 KB | 0644 |
|
| snmp_counter.html | File | 91.51 KB | 0644 |
|
| sriov.html | File | 9.46 KB | 0644 |
|
| statistics.html | File | 31.78 KB | 0644 |
|
| strparser.html | File | 19.15 KB | 0644 |
|
| switchdev.html | File | 39.55 KB | 0644 |
|
| sysfs-tagging.html | File | 10.95 KB | 0644 |
|
| tc-actions-env-rules.html | File | 8.87 KB | 0644 |
|
| tc-queue-filters.html | File | 9.33 KB | 0644 |
|
| tcp-thin.html | File | 10.33 KB | 0644 |
|
| tcp_ao.html | File | 35.85 KB | 0644 |
|
| team.html | File | 7.93 KB | 0644 |
|
| timestamping.html | File | 59.83 KB | 0644 |
|
| tipc.html | File | 384.61 KB | 0644 |
|
| tls-handshake.html | File | 21.18 KB | 0644 |
|
| tls-offload.html | File | 42.72 KB | 0644 |
|
| tls.html | File | 39.38 KB | 0644 |
|
| tproxy.html | File | 13.18 KB | 0644 |
|
| tuntap.html | File | 19 KB | 0644 |
|
| udplite.html | File | 23.04 KB | 0644 |
|
| vrf.html | File | 28.46 KB | 0644 |
|
| vxlan.html | File | 11.95 KB | 0644 |
|
| x25-iface.html | File | 10.9 KB | 0644 |
|
| x25.html | File | 10.07 KB | 0644 |
|
| xdp-rx-metadata.html | File | 27.46 KB | 0644 |
|
| xfrm_device.html | File | 19.14 KB | 0644 |
|
| xfrm_proc.html | File | 11.37 KB | 0644 |
|
| xfrm_sync.html | File | 15.85 KB | 0644 |
|
| xfrm_sysctl.html | File | 8.07 KB | 0644 |
|
| xsk-tx-metadata.html | File | 18.64 KB | 0644 |
|