The sole in-tree user of this flag has been retired, so remove this complexity from all drivers. While here, add a helper routine drivers can use to read the current request's IV into a local buffer. Use this routine to replace duplicated code in nearly all drivers. Reviewed by: cem Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D24450
410 lines
14 KiB
Groff
410 lines
14 KiB
Groff
.\" Copyright (c) 2020, Chelsio Inc
|
|
.\"
|
|
.\" Redistribution and use in source and binary forms, with or without
|
|
.\" modification, are permitted provided that the following conditions are met:
|
|
.\"
|
|
.\" 1. Redistributions of source code must retain the above copyright notice,
|
|
.\" this list of conditions and the following disclaimer.
|
|
.\"
|
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer in the
|
|
.\" documentation and/or other materials provided with the distribution.
|
|
.\"
|
|
.\" 3. Neither the name of the Chelsio Inc nor the names of its
|
|
.\" contributors may be used to endorse or promote products derived from
|
|
.\" this software without specific prior written permission.
|
|
.\"
|
|
.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
.\" POSSIBILITY OF SUCH DAMAGE.
|
|
.\"
|
|
.\" * Other names and brands may be claimed as the property of others.
|
|
.\"
|
|
.\" $FreeBSD$
|
|
.\"
|
|
.Dd April 20, 2020
|
|
.Dt CRYPTO_REQUEST 9
|
|
.Os
|
|
.Sh NAME
|
|
.Nm crypto_request
|
|
.Nd symmetric cryptographic operations
|
|
.Sh SYNOPSIS
|
|
.In opencrypto/cryptodev.h
|
|
.Ft int
|
|
.Fn crypto_dispatch "struct cryptop *crp"
|
|
.Ft void
|
|
.Fn crypto_freereq "struct cryptop *crp"
|
|
.Ft "struct cryptop *"
|
|
.Fn crypto_getreq "crypto_session_t cses" "int how"
|
|
.Sh DESCRIPTION
|
|
Each symmetric cryptographic operation in the kernel is described by
|
|
an instance of
|
|
.Vt struct cryptop
|
|
and is associated with an active session.
|
|
.Pp
|
|
New requests are allocated by
|
|
.Fn crypto_getreq .
|
|
.Fa cses
|
|
is a reference to an active session.
|
|
.Fa how
|
|
is passed to
|
|
.Xr malloc 9
|
|
and should be set to either
|
|
.Dv M_NOWAIT
|
|
or
|
|
.Dv M_WAITOK .
|
|
The caller should then set fields in the returned structure to describe
|
|
request-specific parameters.
|
|
Unused fields should be left as-is.
|
|
.Pp
|
|
.Fn crypto_dispatch
|
|
passes a crypto request to the driver attached to the request's session.
|
|
If there are errors in the request's fields, this function may return
|
|
an error to the caller.
|
|
If errors are encountered while servicing the request, they will instead
|
|
be reported to the request's callback function
|
|
.Pq Fa crp_callback
|
|
via
|
|
.Fa crp_etype .
|
|
.Pp
|
|
Note that a request's callback function may be invoked before
|
|
.Fn crypto_dispatch
|
|
returns.
|
|
.Pp
|
|
Once a request has signaled completion by invoking its callback function,
|
|
it should be feed via
|
|
.Fn crypto_freereq .
|
|
.Pp
|
|
Cryptographic operations include several fields to describe the request.
|
|
.Ss Buffer Types
|
|
Requests are associated with a single data buffer that is modified in place.
|
|
The type of the data buffer and the buffer itself are described by the
|
|
following fields:
|
|
.Bl -tag -width crp_buf_type
|
|
.It Fa crp_buf_type
|
|
The type of the data buffer.
|
|
The following types are supported:
|
|
.Bl -tag -width CRYPTO_BUF_CONTIG
|
|
.It Dv CRYPTO_BUF_CONTIG
|
|
An array of bytes mapped into the kernel's address space.
|
|
.It Dv CRYPTO_BUF_UIO
|
|
A scatter/gather list of kernel buffers as described in
|
|
.Xr uio 9 .
|
|
.It Dv CRYPTO_BUF_MBUF
|
|
A network memory buffer as described in
|
|
.Xr mbuf 9 .
|
|
.El
|
|
.It Fa crp_buf
|
|
A pointer to the start of a
|
|
.Dv CRYPTO_BUF_CONTIG
|
|
data buffer.
|
|
.It Fa crp_ilen
|
|
The length of a
|
|
.Dv CRYPTO_BUF_CONTIG
|
|
data buffer
|
|
.It Fa crp_mbuf
|
|
A pointer to a
|
|
.Vt struct mbuf
|
|
for
|
|
.Dv CRYPTO_BUF_MBUF .
|
|
.It Fa crp_uio
|
|
A pointer to a
|
|
.Vt struct uio
|
|
for
|
|
.Dv CRYPTO_BUF_UIO .
|
|
.It Fa crp_olen
|
|
Used with compression and decompression requests to describe the updated
|
|
length of the payload region in the data buffer.
|
|
.Pp
|
|
If a compression request increases the size of the payload,
|
|
then the data buffer is unmodified, the request completes successfully,
|
|
and
|
|
.Fa crp_olen
|
|
is set to the size the compressed data would have used.
|
|
Callers can compare this to the payload region length to determine if
|
|
the compressed data was discarded.
|
|
.El
|
|
.Ss Request Regions
|
|
Each request describes one or more regions in the data buffer using.
|
|
Each region is described by an offset relative to the start of the
|
|
data buffer and a length.
|
|
The length of some regions is the same for all requests belonging to
|
|
a session.
|
|
Those lengths are set in the session parameters of the associated
|
|
session.
|
|
All requests must define a payload region.
|
|
Other regions are only required for specific session modes.
|
|
The following regions are defined:
|
|
.Bl -column "Payload" "crp_payload_start" "crp_payload_length"
|
|
.It Sy Region Ta Sy Start Ta Sy Length Ta Sy Description
|
|
.It AAD Ta Fa crp_aad_start Ta Fa crp_aad_length Ta
|
|
Additional Authenticated Data
|
|
.It IV Ta Fa crp_iv_start Ta Fa csp_ivlen Ta
|
|
Embedded IV or nonce
|
|
.It Payload Ta Fa crp_payload_start Ta Fa crp_payload_length Ta
|
|
Data to encrypt, decrypt, compress, or decompress
|
|
.It Digest Ta Fa crp_digest_start Ta Fa csp_auth_mlen Ta
|
|
Authentication digest, hash, or tag
|
|
.El
|
|
.Pp
|
|
Requests are permitted to operate on only a subset of the data buffer.
|
|
For example,
|
|
requests from IPsec operate on network packets that include headers not
|
|
used as either additional authentication data (AAD) or payload data.
|
|
.Ss Request Operations
|
|
All requests must specify the type of operation to perform in
|
|
.Fa crp_op .
|
|
Available operations depend on the session's mode.
|
|
.Pp
|
|
Compression requests support the following operations:
|
|
.Bl -tag -width CRYPTO_OP_DECOMPRESS
|
|
.It Dv CRYPTO_OP_COMPRESS
|
|
Compress the data in the payload region of the data buffer.
|
|
.It Dv CRYPTO_OP_DECOMPRESS
|
|
Decompress the data in the payload region of the data buffer.
|
|
.El
|
|
.Pp
|
|
Cipher requests support the following operations:
|
|
.Bl -tag -width CRYPTO_OP_DECRYPT
|
|
.It Dv CRYPTO_OP_ENCRYPT
|
|
Encrypt the data in the payload region of the data buffer.
|
|
.It Dv CRYPTO_OP_DECRYPT
|
|
Decrypt the data in the payload region of the data buffer.
|
|
.El
|
|
.Pp
|
|
Digest requests support the following operations:
|
|
.Bl -tag -width CRYPTO_OP_COMPUTE_DIGEST
|
|
.It Dv CRYPTO_OP_COMPUTE_DIGEST
|
|
Calculate a digest over the payload region of the data buffer
|
|
and store the result in the digest region.
|
|
.It Dv CRYPTO_OP_VERIFY_DIGEST
|
|
Calculate a digest over the payload region of the data buffer.
|
|
Compare the calculated digest to the existing digest from the digest region.
|
|
If the digests match,
|
|
complete the request successfully.
|
|
If the digests do not match,
|
|
fail the request with
|
|
.Er EBADMSG .
|
|
.El
|
|
.Pp
|
|
AEAD and Encrypt-then-Authenticate requests support the following
|
|
operations:
|
|
.Bl -tag -width CRYPTO_OP
|
|
.It Dv CRYPTO_OP_ENCRYPT | Dv CRYPTO_OP_COMPUTE_DIGEST
|
|
Encrypt the data in the payload region of the data buffer.
|
|
Calculate a digest over the AAD and payload regions and store the
|
|
result in the data buffer.
|
|
.It Dv CRYPTO_OP_DECRYPT | Dv CRYPTO_OP_VERIFY_DIGEST
|
|
Calculate a digest over the AAD and payload regions of the data buffer.
|
|
Compare the calculated digest to the existing digest from the digest region.
|
|
If the digests match,
|
|
decrypt the payload region.
|
|
If the digests do not match,
|
|
fail the request with
|
|
.Er EBADMSG .
|
|
.El
|
|
.Ss Request IV and/or Nonce
|
|
Some cryptographic operations require an IV or nonce as an input.
|
|
An IV may be stored either in the IV region of the data buffer or in
|
|
.Fa crp_iv .
|
|
By default,
|
|
the IV is assumed to be stored in the IV region.
|
|
If the IV is stored in
|
|
.Fa crp_iv ,
|
|
.Dv CRYPTO_F_IV_SEPARATE
|
|
should be set in
|
|
.Fa crp_flags
|
|
and
|
|
.Fa crp_digest_start
|
|
should be left as zero.
|
|
.Pp
|
|
Requests that store part, but not all, of the IV in the data buffer should
|
|
store the partial IV in the data buffer and pass the full IV separately in
|
|
.Fa crp_iv .
|
|
.Ss Request and Callback Scheduling
|
|
The crypto framework provides multiple methods of scheduling the dispatch
|
|
of requests to drivers along with the processing of driver callbacks.
|
|
Requests use flags in
|
|
.Fa crp_flags
|
|
to select the desired scheduling methods.
|
|
.Pp
|
|
.Fn crypto_dispatch
|
|
can pass the request to the session's driver via three different methods:
|
|
.Bl -enum
|
|
.It
|
|
The request is queued to a taskqueue backed by a pool of worker threads.
|
|
By default the pool is sized to provide one thread for each CPU.
|
|
Worker threads dequeue requests and pass them to the driver
|
|
asynchronously.
|
|
.It
|
|
The request is passed to the driver synchronously in the context of the
|
|
thread invoking
|
|
.Fn crypto_dispatch .
|
|
.It
|
|
The request is queued to a queue of pending requests.
|
|
A single worker thread dequeues requests and passes them to the driver
|
|
asynchronously.
|
|
.El
|
|
.Pp
|
|
To select the first method (taskqueue backed by multiple threads),
|
|
requests should set
|
|
.Dv CRYPTO_F_ASYNC .
|
|
To always use the third method (queue to single worker thread),
|
|
requests should set
|
|
.Dv CRYPTO_F_BATCH .
|
|
If both flags are set,
|
|
.Dv CRYPTO_F_ASYNC
|
|
takes precedence.
|
|
If neither flag is set,
|
|
.Fn crypto_dispatch
|
|
will first attempt the second method (invoke driver synchronously).
|
|
If the driver is blocked,
|
|
the request will be queued using the third method.
|
|
One caveat is that the first method is only used for requests using software
|
|
drivers which use host CPUs to process requests.
|
|
Requests whose session is associated with a hardware driver will ignore
|
|
.Dv CRYPTO_F_ASYNC
|
|
and only use
|
|
.Dv CRYPTO_F_BATCH
|
|
to determine how requests should be scheduled.
|
|
.Pp
|
|
In addition to bypassing synchronous dispatch in
|
|
.Fn crypto_dispatch ,
|
|
.Dv CRYPTO_F_BATCH
|
|
requests additional changes aimed at optimizing batches of requests to
|
|
the same driver.
|
|
When the worker thread processes a request with
|
|
.Dv CRYPTO_F_BATCH ,
|
|
it will search the pending request queue for any other requests for the same
|
|
driver,
|
|
including requests from different sessions.
|
|
If any other requests are present,
|
|
.Dv CRYPTO_HINT_MORE
|
|
is passed to the driver's process method.
|
|
Drivers may use this to batch completion interrupts.
|
|
.Pp
|
|
Callback function scheduling is simpler than request scheduling.
|
|
Callbacks can either be invoked synchronously from
|
|
.Fn crypto_done ,
|
|
or they can be queued to a pool of worker threads.
|
|
This pool of worker threads is also sized to provide one worker thread
|
|
for each CPU by default.
|
|
Note that a callback function invoked synchronously from
|
|
.Fn crypto_done
|
|
must follow the same restrictions placed on threaded interrupt handlers.
|
|
.Pp
|
|
By default,
|
|
callbacks are invoked asynchronously by a worker thread.
|
|
If
|
|
.Dv CRYPTO_F_CBIMM
|
|
is set,
|
|
the callback is always invoked synchronously from
|
|
.Fn crypto_done .
|
|
If
|
|
.Dv CRYPTO_F_CBIFSYNC
|
|
is set,
|
|
the callback is invoked synchronously if the request was processed by a
|
|
software driver or asynchronously if the request was processed by a
|
|
hardware driver.
|
|
.Pp
|
|
If a request was scheduled to the taskqueue via
|
|
.Dv CRYPTO_F_ASYNC ,
|
|
callbacks are always invoked asynchronously ignoring
|
|
.Dv CRYPTO_F_CBIMM
|
|
and
|
|
.Dv CRYPTO_F_CBIFSYNC .
|
|
In this case,
|
|
.Dv CRYPTO_F_ASYNC_KEEPORDER
|
|
may be set to ensure that callbacks for requests on a given session are
|
|
invoked in the same order that requests were queued to the session via
|
|
.Fn crypto_dispatch .
|
|
This flag is used by IPsec to ensure that decrypted network packets are
|
|
passed up the network stack in roughly the same order they were received.
|
|
.Pp
|
|
.Ss Other Request Fields
|
|
In addition to the fields and flags enumerated above,
|
|
.Vt struct cryptop
|
|
includes the following:
|
|
.Bl -tag -width crp_payload_length
|
|
.It Fa crp_session
|
|
A reference to the active session.
|
|
This is set when the request is created by
|
|
.Fn crypto_getreq
|
|
and should not be modified.
|
|
Drivers can use this to fetch driver-specific session state or
|
|
session parameters.
|
|
.It Fa crp_etype
|
|
Error status.
|
|
Either zero on success, or an error if a request fails.
|
|
Set by drivers prior to completing a request via
|
|
.Fn crypto_done .
|
|
.It Fa crp_flags
|
|
A bitmask of flags.
|
|
The following flags are available in addition to flags discussed previously:
|
|
.Bl -tag -width CRYPTO_F_DONE
|
|
.It Dv CRYPTO_F_DONE
|
|
Set by
|
|
.Fa crypto_done
|
|
before calling
|
|
.Fa crp_callback .
|
|
This flag is not very useful and will likely be removed in the future.
|
|
It can only be safely checked from the callback routine at which point
|
|
it is always set.
|
|
.El
|
|
.It Fa crp_cipher_key
|
|
Pointer to a request-specific encryption key.
|
|
If this value is not set,
|
|
the request uses the session encryption key.
|
|
.It Fa crp_auth_key
|
|
Pointer to a request-specific authentication key.
|
|
If this value is not set,
|
|
the request uses the session authentication key.
|
|
.It Fa crp_opaque
|
|
An opaque pointer.
|
|
This pointer permits users of the cryptographic framework to store
|
|
information about a request to be used in the callback.
|
|
.It Fa crp_callback
|
|
Callback function.
|
|
This must point to a callback function of type
|
|
.Vt void (*)(struct cryptop *) .
|
|
The callback function should inspect
|
|
.Fa crp_etype
|
|
to determine the status of the completed operation.
|
|
It should also arrange for the request to be freed via
|
|
.Fn crypto_freereq .
|
|
.El
|
|
.Sh RETURN VALUES
|
|
.Fn crypto_dispatch
|
|
returns an error if the request contained invalid fields,
|
|
or zero if the request was valid.
|
|
.Fn crypto_getreq
|
|
returns a pointer to a new request structure on success,
|
|
or
|
|
.Dv NULL
|
|
on failure.
|
|
.Dv NULL
|
|
can only be returned if
|
|
.Dv M_NOWAIT
|
|
was passed in
|
|
.Fa how .
|
|
.Sh SEE ALSO
|
|
.Xr ipsec 4 ,
|
|
.Xr crypto 7 ,
|
|
.Xr crypto 9 ,
|
|
.Xr crypto_session 9 ,
|
|
.Xr mbuf 9
|
|
.Xr uio 9
|
|
.Sh BUGS
|
|
Not all drivers properly handle mixing session and per-request keys
|
|
within a single session.
|
|
Consumers should either use a single key for a session specified in
|
|
the session parameters or always use per-request keys.
|