OCF: Remove support for asymmetric cryptographic operations.
There haven't been any non-obscure drivers that supported this functionality and it has been impossible to test to ensure that it still works. The only known consumer of this interface was the engine in OpenSSL < 1.1. Modern OpenSSL versions do not include support for this interface as it was not well-documented. Reviewed by: cem Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D29736
This commit is contained in:
parent
89df484739
commit
76681661be
@ -40,6 +40,13 @@
|
|||||||
# xargs -n1 | sort | uniq -d;
|
# xargs -n1 | sort | uniq -d;
|
||||||
# done
|
# done
|
||||||
|
|
||||||
|
# 20210412: Remove kernel asymmetric crypto
|
||||||
|
OLD_FILES+=usr/share/man/man9/crypto_asym.9
|
||||||
|
OLD_FILES+=usr/share/man/man9/crypto_kdispatch.9
|
||||||
|
OLD_FILES+=usr/share/man/man9/crypto_kdone.9
|
||||||
|
OLD_FILES+=usr/share/man/man9/crypto_kregister.9
|
||||||
|
OLD_FILES+=usr/share/man/man9/CRYPTODEV_KPROCESS.9
|
||||||
|
|
||||||
# 20210410: remove unused libexec/rc.d/archdep
|
# 20210410: remove unused libexec/rc.d/archdep
|
||||||
OLD_FILES+=etc/rc.d/archdep
|
OLD_FILES+=etc/rc.d/archdep
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd November 24, 2020
|
.Dd April 12, 2021
|
||||||
.Dt CRYPTO 4
|
.Dt CRYPTO 4
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -93,53 +93,32 @@ then issue
|
|||||||
calls on the descriptor.
|
calls on the descriptor.
|
||||||
User-mode access to
|
User-mode access to
|
||||||
.Pa /dev/crypto
|
.Pa /dev/crypto
|
||||||
is controlled by two
|
is controlled by the
|
||||||
|
.Ic kern.cryptodevallowsoft
|
||||||
.Xr sysctl 8
|
.Xr sysctl 8
|
||||||
variables:
|
variable.
|
||||||
.Ic kern.userasymcrypto
|
If this variable is zero,
|
||||||
and
|
then user-mode sessions are only permitted to use cryptography coprocessors.
|
||||||
.Ic kern.cryptodevallowsoft .
|
|
||||||
.Pp
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
device provides two distinct modes of operation: one mode for
|
|
||||||
symmetric-keyed cryptographic requests and digests, and a second mode for
|
|
||||||
both asymmetric-key (public-key/private-key) requests and
|
|
||||||
modular arithmetic (for Diffie-Hellman key exchange and other
|
|
||||||
cryptographic protocols).
|
|
||||||
The two modes are described separately below.
|
|
||||||
.Sh DEPRECATION NOTICE
|
|
||||||
The asymmetric-key operations supported by this interface will not be
|
|
||||||
present in
|
|
||||||
.Fx 14.0
|
|
||||||
and later.
|
|
||||||
.Sh THEORY OF OPERATION
|
.Sh THEORY OF OPERATION
|
||||||
Regardless of whether symmetric-key or asymmetric-key operations are
|
Use of the device requires a basic series of steps:
|
||||||
to be performed, use of the device requires a basic series of steps:
|
|
||||||
.Bl -enum
|
.Bl -enum
|
||||||
.It
|
.It
|
||||||
Open the
|
Open the
|
||||||
.Pa /dev/crypto
|
.Pa /dev/crypto
|
||||||
device.
|
device.
|
||||||
.It
|
.It
|
||||||
If any symmetric-keyed cryptographic or digest operations will be performed,
|
Create a session with
|
||||||
create a session with
|
|
||||||
.Dv CIOCGSESSION
|
.Dv CIOCGSESSION
|
||||||
or
|
or
|
||||||
.Dv CIOCGSESSION2 .
|
.Dv CIOCGSESSION2 .
|
||||||
Most applications will require at least one symmetric session.
|
Applications will require at least one symmetric session.
|
||||||
Since cipher and MAC keys are tied to sessions, many
|
Since cipher and MAC keys are tied to sessions, many
|
||||||
applications will require more.
|
applications will require more.
|
||||||
Asymmetric operations do not use sessions.
|
|
||||||
.It
|
.It
|
||||||
Submit requests, synchronously with
|
Submit requests, synchronously with
|
||||||
.Dv CIOCCRYPT
|
.Dv CIOCCRYPT
|
||||||
(symmetric),
|
|
||||||
.Dv CIOCCRYPTAEAD
|
|
||||||
(symmetric),
|
|
||||||
or
|
or
|
||||||
.Dv CIOCKEY
|
.Dv CIOCCRYPTAEAD .
|
||||||
(asymmetric).
|
|
||||||
.It
|
.It
|
||||||
Optionally destroy a session with
|
Optionally destroy a session with
|
||||||
.Dv CIOCFSESSION .
|
.Dv CIOCFSESSION .
|
||||||
@ -151,22 +130,27 @@ This will automatically close any remaining sessions associated with the
|
|||||||
file desriptor.
|
file desriptor.
|
||||||
.El
|
.El
|
||||||
.Sh SYMMETRIC-KEY OPERATION
|
.Sh SYMMETRIC-KEY OPERATION
|
||||||
The symmetric-key operation mode provides a context-based API
|
.Nm cryptodev
|
||||||
|
provides a context-based API
|
||||||
to traditional symmetric-key encryption (or privacy) algorithms,
|
to traditional symmetric-key encryption (or privacy) algorithms,
|
||||||
or to keyed and unkeyed one-way hash (HMAC and MAC) algorithms.
|
keyed and unkeyed one-way hash (HMAC and MAC) algorithms,
|
||||||
The symmetric-key mode also permits encrypt-then-authenticate fused operation,
|
encrypt-then-authenticate (ETA) fused operations,
|
||||||
where the hardware performs both a privacy algorithm and an integrity-check
|
and authenticated encryption with additional data (AEAD) operations.
|
||||||
|
For ETA operations,
|
||||||
|
drivers perform both a privacy algorithm and an integrity-check
|
||||||
algorithm in a single pass over the data: either a fused
|
algorithm in a single pass over the data: either a fused
|
||||||
encrypt/HMAC-generate operation, or a fused HMAC-verify/decrypt operation.
|
encrypt/HMAC-generate operation, or a fused HMAC-verify/decrypt operation.
|
||||||
|
Similarly, for AEAD operations,
|
||||||
|
drivers perform either an encrypt/MAC-generate operation
|
||||||
|
or a MAC-verify/decrypt operation.
|
||||||
.Pp
|
.Pp
|
||||||
To use symmetric mode, you must first create a session specifying
|
The algorithm(s) and key(s) to use are specified when a session is
|
||||||
the algorithm(s) and key(s) to use; then issue encrypt or decrypt
|
created.
|
||||||
requests against the session.
|
Individual requests are able to specify per-request initialization vectors
|
||||||
|
or nonces.
|
||||||
.Ss Algorithms
|
.Ss Algorithms
|
||||||
For a list of supported algorithms, see
|
For a list of supported algorithms, see
|
||||||
.Xr crypto 7
|
.Xr crypto 7 .
|
||||||
and
|
|
||||||
.Xr crypto 9 .
|
|
||||||
.Ss IOCTL Request Descriptions
|
.Ss IOCTL Request Descriptions
|
||||||
.\"
|
.\"
|
||||||
.Bl -tag -width CIOCGSESSION
|
.Bl -tag -width CIOCGSESSION
|
||||||
@ -216,11 +200,13 @@ privacy algorithm, integrity algorithm, and keys specified in
|
|||||||
The special value 0 for either privacy or integrity
|
The special value 0 for either privacy or integrity
|
||||||
is reserved to indicate that the indicated operation (privacy or integrity)
|
is reserved to indicate that the indicated operation (privacy or integrity)
|
||||||
is not desired for this session.
|
is not desired for this session.
|
||||||
|
ETA sessions specify both privacy and integrity algorithms.
|
||||||
|
AEAD sessions specify only a privacy algorithm.
|
||||||
.Pp
|
.Pp
|
||||||
Multiple sessions may be bound to a single file descriptor.
|
Multiple sessions may be bound to a single file descriptor.
|
||||||
The session ID returned in
|
The session ID returned in
|
||||||
.Fa sessp-\*[Gt]ses
|
.Fa sessp-\*[Gt]ses
|
||||||
is supplied as a required field in the symmetric-operation structure
|
is supplied as a required field in the operation structure
|
||||||
.Fa crypt_op
|
.Fa crypt_op
|
||||||
for future encryption or hashing requests.
|
for future encryption or hashing requests.
|
||||||
.\" .Pp
|
.\" .Pp
|
||||||
@ -229,7 +215,7 @@ for future encryption or hashing requests.
|
|||||||
.\" .Nx
|
.\" .Nx
|
||||||
.\" extension.
|
.\" extension.
|
||||||
.Pp
|
.Pp
|
||||||
For non-zero symmetric-key privacy algorithms, the privacy algorithm
|
For non-zero privacy algorithms, the privacy algorithm
|
||||||
must be specified in
|
must be specified in
|
||||||
.Fa sessp-\*[Gt]cipher ,
|
.Fa sessp-\*[Gt]cipher ,
|
||||||
the key length in
|
the key length in
|
||||||
@ -290,7 +276,7 @@ struct crypt_op {
|
|||||||
};
|
};
|
||||||
|
|
||||||
.Ed
|
.Ed
|
||||||
Request a symmetric-key (or hash) operation.
|
Request an encryption/decryption (or hash) operation.
|
||||||
To encrypt, set
|
To encrypt, set
|
||||||
.Fa cr_op-\*[Gt]op
|
.Fa cr_op-\*[Gt]op
|
||||||
to
|
to
|
||||||
@ -344,75 +330,6 @@ to include in the authentication mode.
|
|||||||
Destroys the session identified by
|
Destroys the session identified by
|
||||||
.Fa ses_id .
|
.Fa ses_id .
|
||||||
.El
|
.El
|
||||||
.\"
|
|
||||||
.Sh ASYMMETRIC-KEY OPERATION
|
|
||||||
.Ss Asymmetric-key algorithms
|
|
||||||
Contingent upon hardware support, the following asymmetric
|
|
||||||
(public-key/private-key; or key-exchange subroutine) operations may
|
|
||||||
also be available:
|
|
||||||
.Pp
|
|
||||||
.Bl -column "CRK_DH_COMPUTE_KEY" "Input parameter" "Output parameter" -offset indent -compact
|
|
||||||
.It Em "Algorithm" Ta "Input parameter" Ta "Output parameter"
|
|
||||||
.It Em " " Ta "Count" Ta "Count"
|
|
||||||
.It Dv CRK_MOD_EXP Ta 3 Ta 1
|
|
||||||
.It Dv CRK_MOD_EXP_CRT Ta 6 Ta 1
|
|
||||||
.It Dv CRK_DSA_SIGN Ta 5 Ta 2
|
|
||||||
.It Dv CRK_DSA_VERIFY Ta 7 Ta 0
|
|
||||||
.It Dv CRK_DH_COMPUTE_KEY Ta 3 Ta 1
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
See below for discussion of the input and output parameter counts.
|
|
||||||
.Ss Asymmetric-key commands
|
|
||||||
.Bl -tag -width CIOCKEY
|
|
||||||
.It Dv CIOCASYMFEAT Fa int *feature_mask
|
|
||||||
Returns a bitmask of supported asymmetric-key operations.
|
|
||||||
Each of the above-listed asymmetric operations is present
|
|
||||||
if and only if the bit position numbered by the code for that operation
|
|
||||||
is set.
|
|
||||||
For example,
|
|
||||||
.Dv CRK_MOD_EXP
|
|
||||||
is available if and only if the bit
|
|
||||||
.Pq 1 \*[Lt]\*[Lt] Dv CRK_MOD_EXP
|
|
||||||
is set.
|
|
||||||
.It Dv CIOCKEY Fa struct crypt_kop *kop
|
|
||||||
.Bd -literal
|
|
||||||
struct crypt_kop {
|
|
||||||
u_int crk_op; /* e.g. CRK_MOD_EXP */
|
|
||||||
u_int crk_status; /* return status */
|
|
||||||
u_short crk_iparams; /* # of input params */
|
|
||||||
u_short crk_oparams; /* # of output params */
|
|
||||||
u_int crk_pad1;
|
|
||||||
struct crparam crk_param[CRK_MAXPARAM];
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Bignum parameter, in packed bytes. */
|
|
||||||
struct crparam {
|
|
||||||
void * crp_p;
|
|
||||||
u_int crp_nbits;
|
|
||||||
};
|
|
||||||
|
|
||||||
.Ed
|
|
||||||
Performs an asymmetric-key operation from the list above.
|
|
||||||
The specific operation is supplied in
|
|
||||||
.Fa kop-\*[Gt]crk_op ;
|
|
||||||
final status for the operation is returned in
|
|
||||||
.Fa kop-\*[Gt]crk_status .
|
|
||||||
The number of input arguments and the number of output arguments
|
|
||||||
is specified in
|
|
||||||
.Fa kop-\*[Gt]crk_iparams
|
|
||||||
and
|
|
||||||
.Fa kop-\*[Gt]crk_iparams ,
|
|
||||||
respectively.
|
|
||||||
The field
|
|
||||||
.Fa crk_param[]
|
|
||||||
must be filled in with exactly
|
|
||||||
.Fa kop-\*[Gt]crk_iparams + kop-\*[Gt]crk_oparams
|
|
||||||
arguments, each encoded as a
|
|
||||||
.Fa struct crparam
|
|
||||||
(address, bitlength) pair.
|
|
||||||
.Pp
|
|
||||||
The semantics of these arguments are currently undocumented.
|
|
||||||
.El
|
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr aesni 4 ,
|
.Xr aesni 4 ,
|
||||||
.Xr hifn 4 ,
|
.Xr hifn 4 ,
|
||||||
@ -444,5 +361,3 @@ must follow whether privacy or integrity algorithms were specified for
|
|||||||
session: if you request a
|
session: if you request a
|
||||||
.No non- Ns Dv NULL
|
.No non- Ns Dv NULL
|
||||||
algorithm, you must supply a suitably-sized buffer.
|
algorithm, you must supply a suitably-sized buffer.
|
||||||
.Pp
|
|
||||||
The scheme for passing arguments for asymmetric requests is baroque.
|
|
||||||
|
@ -72,7 +72,6 @@ MAN= accept_filter.9 \
|
|||||||
cr_seeothergids.9 \
|
cr_seeothergids.9 \
|
||||||
cr_seeotheruids.9 \
|
cr_seeotheruids.9 \
|
||||||
crypto.9 \
|
crypto.9 \
|
||||||
crypto_asym.9 \
|
|
||||||
crypto_buffer.9 \
|
crypto_buffer.9 \
|
||||||
crypto_driver.9 \
|
crypto_driver.9 \
|
||||||
crypto_request.9 \
|
crypto_request.9 \
|
||||||
@ -913,10 +912,6 @@ MLINKS+=cpuset.9 CPUSET_T_INITIALIZER.9 \
|
|||||||
cpuset.9 CPU_COPY_STORE_REL.9
|
cpuset.9 CPU_COPY_STORE_REL.9
|
||||||
MLINKS+=critical_enter.9 critical.9 \
|
MLINKS+=critical_enter.9 critical.9 \
|
||||||
critical_enter.9 critical_exit.9
|
critical_enter.9 critical_exit.9
|
||||||
MLINKS+=crypto_asym.9 crypto_kdispatch.9 \
|
|
||||||
crypto_asym.9 crypto_kdone.9 \
|
|
||||||
crypto_asym.9 crypto_kregister.9 \
|
|
||||||
crypto_asym.9 CRYPTODEV_KPROCESS.9
|
|
||||||
MLINKS+=crypto_buffer.9 crypto_apply.9 \
|
MLINKS+=crypto_buffer.9 crypto_apply.9 \
|
||||||
crypto_buffer.9 crypto_apply_buf.9 \
|
crypto_buffer.9 crypto_apply_buf.9 \
|
||||||
crypto_buffer.9 crypto_buffer_contiguous_segment.9 \
|
crypto_buffer.9 crypto_buffer_contiguous_segment.9 \
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd March 18, 2021
|
.Dd April 12, 2021
|
||||||
.Dt CRYPTO 9
|
.Dt CRYPTO 9
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -35,15 +35,10 @@ through the
|
|||||||
device.
|
device.
|
||||||
.Pp
|
.Pp
|
||||||
.Nm
|
.Nm
|
||||||
supports two modes of operation:
|
supports encryption and decryption operations
|
||||||
one mode for symmetric-keyed cryptographic requests and digest,
|
|
||||||
and a second mode for asymmetric-key requests and modular arithmetic.
|
|
||||||
.Ss Symmetric-Key Mode
|
|
||||||
Symmetric-key operations include encryption and decryption operations
|
|
||||||
using block and stream ciphers as well as computation and verification
|
using block and stream ciphers as well as computation and verification
|
||||||
of message authentication codes (MACs).
|
of message authentication codes (MACs).
|
||||||
In this mode,
|
Consumers allocate sessions to describe a transform as discussed in
|
||||||
consumers allocate sessions to describe a transform as discussed in
|
|
||||||
.Xr crypto_session 9 .
|
.Xr crypto_session 9 .
|
||||||
Consumers then allocate request objects to describe each transformation
|
Consumers then allocate request objects to describe each transformation
|
||||||
such as encrypting a network packet or decrypting a disk sector.
|
such as encrypting a network packet or decrypting a disk sector.
|
||||||
@ -56,18 +51,6 @@ consumers.
|
|||||||
describes the interfaces drivers use to register with the framework,
|
describes the interfaces drivers use to register with the framework,
|
||||||
helper routines the framework provides to faciliate request processing,
|
helper routines the framework provides to faciliate request processing,
|
||||||
and the interfaces drivers are required to provide.
|
and the interfaces drivers are required to provide.
|
||||||
.Ss Asymmetric-Key Mode
|
|
||||||
Assymteric-key operations do not use sessions.
|
|
||||||
Instead,
|
|
||||||
these operations perform individual mathematical operations using a set
|
|
||||||
of input and output parameters.
|
|
||||||
These operations are described in
|
|
||||||
.Xr crypto_asym 9 .
|
|
||||||
Drivers that support asymmetric operations use additional interfaces
|
|
||||||
described in
|
|
||||||
.Xr crypto_asym 9
|
|
||||||
in addition to the base interfaces described in
|
|
||||||
.Xr crypto_driver 9 .
|
|
||||||
.Ss Callbacks
|
.Ss Callbacks
|
||||||
Since the consumers may not be associated with a process, drivers may
|
Since the consumers may not be associated with a process, drivers may
|
||||||
not
|
not
|
||||||
@ -83,10 +66,9 @@ Errors are reported to the callback function.
|
|||||||
Session initialization does not use callbacks and returns errors
|
Session initialization does not use callbacks and returns errors
|
||||||
synchronously.
|
synchronously.
|
||||||
.Ss Session Migration
|
.Ss Session Migration
|
||||||
For symmetric-key operations,
|
Operations may fail with a specific error code,
|
||||||
a specific error code,
|
|
||||||
.Er EAGAIN ,
|
.Er EAGAIN ,
|
||||||
is used to indicate that a session handle has changed and that the
|
to indicate that a session handle has changed and that the
|
||||||
request may be re-submitted immediately with the new session.
|
request may be re-submitted immediately with the new session.
|
||||||
The consumer should update its saved copy of the session handle
|
The consumer should update its saved copy of the session handle
|
||||||
to the value of
|
to the value of
|
||||||
@ -95,9 +77,6 @@ so that future requests use the new session.
|
|||||||
.Ss Supported Algorithms
|
.Ss Supported Algorithms
|
||||||
More details on some algorithms may be found in
|
More details on some algorithms may be found in
|
||||||
.Xr crypto 7 .
|
.Xr crypto 7 .
|
||||||
These algorithms are used for symmetric-mode operations.
|
|
||||||
Asymmetric-mode operations support operations described in
|
|
||||||
.Xr crypto_asym 9 .
|
|
||||||
.Pp
|
.Pp
|
||||||
The following authentication algorithms are supported:
|
The following authentication algorithms are supported:
|
||||||
.Pp
|
.Pp
|
||||||
@ -156,7 +135,6 @@ most of the framework code
|
|||||||
.Xr crypto 4 ,
|
.Xr crypto 4 ,
|
||||||
.Xr ipsec 4 ,
|
.Xr ipsec 4 ,
|
||||||
.Xr crypto 7 ,
|
.Xr crypto 7 ,
|
||||||
.Xr crypto_asym 9 ,
|
|
||||||
.Xr crypto_driver 9 ,
|
.Xr crypto_driver 9 ,
|
||||||
.Xr crypto_request 9 ,
|
.Xr crypto_request 9 ,
|
||||||
.Xr crypto_session 9 ,
|
.Xr crypto_session 9 ,
|
||||||
|
@ -1,178 +0,0 @@
|
|||||||
.\" 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 March 27, 2020
|
|
||||||
.Dt CRYPTO_ASYM 9
|
|
||||||
.Os
|
|
||||||
.Sh NAME
|
|
||||||
.Nm crypto_asym
|
|
||||||
.Nd asymmetric cryptographic operations
|
|
||||||
.Sh SYNOPSIS
|
|
||||||
.In opencrypto/cryptodev.h
|
|
||||||
.Ft int
|
|
||||||
.Fn crypto_kdispatch "struct cryptkop *krp"
|
|
||||||
.Ft void
|
|
||||||
.Fn crypto_kdone "struct cryptkop *krp"
|
|
||||||
.Ft int
|
|
||||||
.Fn crypto_kregister "uint32_t driverid" "int kalg" "uint32_t flags"
|
|
||||||
.Ft int
|
|
||||||
.Fn CRYPTODEV_KPROCESS "device_t dev" "struct cryptop *krp" "int flags"
|
|
||||||
.Sh DESCRIPTION
|
|
||||||
The in-kernel cryptographic kernel framework supports asymmetric
|
|
||||||
requests (keying requests) in addition to symmetric operations.
|
|
||||||
There are currently no in-kernel users of these requests,
|
|
||||||
but applications can make requests of hardware drivers via the
|
|
||||||
.Pa /dev/crypto
|
|
||||||
device .
|
|
||||||
.Pp
|
|
||||||
Some APIs are shared with the framework's symmetric request support.
|
|
||||||
This manual describes the APIs and data structures unique to
|
|
||||||
asymmetric requests.
|
|
||||||
.Pp
|
|
||||||
.Ss Request Objects
|
|
||||||
A request is described by a
|
|
||||||
.Vt struct cryptkop
|
|
||||||
containing the following fields:
|
|
||||||
.Bl -tag -width "krp_callback"
|
|
||||||
.It Fa krp_op
|
|
||||||
Operation to perform.
|
|
||||||
Available operations include
|
|
||||||
.Dv CRK_MOD_EXP ,
|
|
||||||
.Dv CRK_MOD_EXP_CRT ,
|
|
||||||
.Dv CRK_DSA_SIGN ,
|
|
||||||
.Dv CRK_DSA_VERIFY ,
|
|
||||||
and
|
|
||||||
.Dv CRK_DH_COMPUTE_KEY .
|
|
||||||
.It Fa krp_status
|
|
||||||
Error status.
|
|
||||||
Either zero on success,
|
|
||||||
or an error if an operation fails.
|
|
||||||
Set by drivers prior to completing a request via
|
|
||||||
.Fn crypto_kdone .
|
|
||||||
.It Fa krp_iparams
|
|
||||||
Count of input parameters.
|
|
||||||
.It Fa krp_oparams
|
|
||||||
Count of output parameters.
|
|
||||||
.It Fa krp_crid
|
|
||||||
Requested device.
|
|
||||||
.It Fa krp_hid
|
|
||||||
Device used to complete the request.
|
|
||||||
.It Fa krp_param
|
|
||||||
Array of parameters.
|
|
||||||
The array contains the input parameters first followed by the output
|
|
||||||
parameters.
|
|
||||||
Each parameter is stored as a bignum.
|
|
||||||
Each bignum is described by a
|
|
||||||
.Vt struct crparam
|
|
||||||
containing the following fields:
|
|
||||||
.Bl -tag -width "crp_nbits"
|
|
||||||
.It Fa crp_p
|
|
||||||
Pointer to array of packed bytes.
|
|
||||||
.It Fa crp_nbits
|
|
||||||
Size of bignum in bits.
|
|
||||||
.El
|
|
||||||
.It Fa krp_callback
|
|
||||||
Callback function.
|
|
||||||
This must point to a callback function of type
|
|
||||||
.Vt void (*)(struct cryptkop *) .
|
|
||||||
The callback function should inspect
|
|
||||||
.Fa krp_status
|
|
||||||
to determine the status of the completed operation.
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
New requests should be initialized to zero before setting fields to
|
|
||||||
appropriate values.
|
|
||||||
Once the request has been populated,
|
|
||||||
it should be passed to
|
|
||||||
.Fn crypto_kdispatch .
|
|
||||||
.Pp
|
|
||||||
.Fn crypto_kdispatch
|
|
||||||
will choose a device driver to perform the operation described by
|
|
||||||
.Fa krp
|
|
||||||
and invoke that driver's
|
|
||||||
.Fn CRYPTO_KPROCESS
|
|
||||||
method.
|
|
||||||
.Ss Driver API
|
|
||||||
Drivers register support for asymmetric operations by calling
|
|
||||||
.Fn crypto_kregister
|
|
||||||
for each supported algorithm.
|
|
||||||
.Fa driverid
|
|
||||||
should be the value returned by an earlier call to
|
|
||||||
.Fn crypto_get_driverid .
|
|
||||||
.Fa kalg
|
|
||||||
should list one of the operations that can be set in
|
|
||||||
.Fa krp_op .
|
|
||||||
.Fa flags
|
|
||||||
is a bitmask of zero or more of the following values:
|
|
||||||
.Bl -tag -width "CRYPTO_ALG_FLAG_RNG_ENABLE"
|
|
||||||
.It Dv CRYPTO_ALG_FLAG_RNG_ENABLE
|
|
||||||
Device has a hardware RNG for DH/DSA.
|
|
||||||
.It Dv CRYPTO_ALG_FLAG_DSA_SHA
|
|
||||||
Device can compute a SHA digest of a message.
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
Drivers unregister with the framework via
|
|
||||||
.Fn crypto_unregister_all .
|
|
||||||
.Pp
|
|
||||||
Similar to
|
|
||||||
.Fn CRYPTO_PROCESS ,
|
|
||||||
.Fn CRYPTO_KPROCESS
|
|
||||||
should complete the request or schedule it for asynchronous
|
|
||||||
completion.
|
|
||||||
If this method is not able to complete a request due to insufficient
|
|
||||||
resources,
|
|
||||||
it can defer the request (and future asymmetric requests) by returning
|
|
||||||
.Dv ERESTART .
|
|
||||||
Once resources are available,
|
|
||||||
the driver should invoke
|
|
||||||
.Fn crypto_unblock
|
|
||||||
with
|
|
||||||
.Dv CRYPTO_ASYMQ
|
|
||||||
to resume processing of asymmetric requests.
|
|
||||||
.Pp
|
|
||||||
Once a request is completed,
|
|
||||||
the driver should set
|
|
||||||
.Fa krp_status
|
|
||||||
and then call
|
|
||||||
.Fn crypto_kdone .
|
|
||||||
.Sh RETURN VALUES
|
|
||||||
.Fn crypto_kdispatch ,
|
|
||||||
.Fn crypto_kregister ,
|
|
||||||
and
|
|
||||||
.Fn CRYPTODEV_KPROCESS
|
|
||||||
return zero on success or an error on failure.
|
|
||||||
.Sh SEE ALSO
|
|
||||||
.Xr crypto 7 ,
|
|
||||||
.Xr crypto 9 ,
|
|
||||||
.Xr crypto_driver 9 ,
|
|
||||||
.Xr crypto_request 9 ,
|
|
||||||
.Xr crypto_session 9
|
|
@ -30,7 +30,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd June 9, 2020
|
.Dd April 12, 2021
|
||||||
.Dt CRYPTO_DRIVER 9
|
.Dt CRYPTO_DRIVER 9
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -285,13 +285,10 @@ is the value returned by
|
|||||||
.Fn crypto_get_driverid .
|
.Fn crypto_get_driverid .
|
||||||
.Fa what
|
.Fa what
|
||||||
indicates which types of requests the driver is able to handle again:
|
indicates which types of requests the driver is able to handle again:
|
||||||
.Bl -tag -width "CRYPTO_ASYMQ"
|
.Bl -tag -width "CRYPTO_SYMQ"
|
||||||
.It Dv CRYPTO_SYMQ
|
.It Dv CRYPTO_SYMQ
|
||||||
indicates that the driver is able to handle symmetric requests passed to
|
indicates that the driver is able to handle symmetric requests passed to
|
||||||
.Fn CRYPTODEV_PROCESS .
|
.Fn CRYPTODEV_PROCESS .
|
||||||
.It Dv CRYPTO_ASYMQ
|
|
||||||
indicates that the driver is able to handle asymmetric requests passed to
|
|
||||||
.Fn CRYPTODEV_KPROCESS .
|
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
.Pp
|
.Pp
|
||||||
|
@ -2252,7 +2252,7 @@ hifn_intr(void *arg)
|
|||||||
HIFN_UNLOCK(sc);
|
HIFN_UNLOCK(sc);
|
||||||
|
|
||||||
if (sc->sc_needwakeup) { /* XXX check high watermark */
|
if (sc->sc_needwakeup) { /* XXX check high watermark */
|
||||||
int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);
|
int wakeup = sc->sc_needwakeup & CRYPTO_SYMQ;
|
||||||
#ifdef HIFN_DEBUG
|
#ifdef HIFN_DEBUG
|
||||||
if (hifn_debug)
|
if (hifn_debug)
|
||||||
device_printf(sc->sc_dev,
|
device_printf(sc->sc_dev,
|
||||||
|
@ -385,8 +385,6 @@ safe_attach(device_t dev)
|
|||||||
#if 0
|
#if 0
|
||||||
printf(" key");
|
printf(" key");
|
||||||
sc->sc_flags |= SAFE_FLAGS_KEY;
|
sc->sc_flags |= SAFE_FLAGS_KEY;
|
||||||
crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0);
|
|
||||||
crypto_kregister(sc->sc_cid, CRK_MOD_EXP_CRT, 0);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (sc->sc_devinfo & SAFE_DEVINFO_DES) {
|
if (sc->sc_devinfo & SAFE_DEVINFO_DES) {
|
||||||
@ -584,7 +582,7 @@ safe_intr(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sc->sc_needwakeup) { /* XXX check high watermark */
|
if (sc->sc_needwakeup) { /* XXX check high watermark */
|
||||||
int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);
|
int wakeup = sc->sc_needwakeup & CRYPTO_SYMQ;
|
||||||
DPRINTF(("%s: wakeup crypto %x\n", __func__,
|
DPRINTF(("%s: wakeup crypto %x\n", __func__,
|
||||||
sc->sc_needwakeup));
|
sc->sc_needwakeup));
|
||||||
sc->sc_needwakeup &= ~wakeup;
|
sc->sc_needwakeup &= ~wakeup;
|
||||||
|
@ -281,7 +281,7 @@ nlm_xlpsec_msgring_handler(int vc, int size, int code, int src_id,
|
|||||||
atomic_add_int(&creditleft, sc->sec_msgsz);
|
atomic_add_int(&creditleft, sc->sec_msgsz);
|
||||||
if (creditleft >= (NLM_CRYPTO_LEFT_REQS)) {
|
if (creditleft >= (NLM_CRYPTO_LEFT_REQS)) {
|
||||||
crypto_unblock(sc->sc_cid, sc->sc_needwakeup);
|
crypto_unblock(sc->sc_cid, sc->sc_needwakeup);
|
||||||
sc->sc_needwakeup &= (~(CRYPTO_SYMQ | CRYPTO_ASYMQ));
|
sc->sc_needwakeup &= ~CRYPTO_SYMQ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cmd->hash_dst_len != 0) {
|
if (cmd->hash_dst_len != 0) {
|
||||||
|
@ -98,8 +98,7 @@ SDT_PROVIDER_DEFINE(opencrypto);
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Crypto drivers register themselves by allocating a slot in the
|
* Crypto drivers register themselves by allocating a slot in the
|
||||||
* crypto_drivers table with crypto_get_driverid() and then registering
|
* crypto_drivers table with crypto_get_driverid().
|
||||||
* each asym algorithm they support with crypto_kregister().
|
|
||||||
*/
|
*/
|
||||||
static struct mtx crypto_drivers_mtx; /* lock on driver table */
|
static struct mtx crypto_drivers_mtx; /* lock on driver table */
|
||||||
#define CRYPTO_DRIVER_LOCK() mtx_lock(&crypto_drivers_mtx)
|
#define CRYPTO_DRIVER_LOCK() mtx_lock(&crypto_drivers_mtx)
|
||||||
@ -118,13 +117,10 @@ struct cryptocap {
|
|||||||
device_t cc_dev;
|
device_t cc_dev;
|
||||||
uint32_t cc_hid;
|
uint32_t cc_hid;
|
||||||
uint32_t cc_sessions; /* (d) # of sessions */
|
uint32_t cc_sessions; /* (d) # of sessions */
|
||||||
uint32_t cc_koperations; /* (d) # os asym operations */
|
|
||||||
uint8_t cc_kalg[CRK_ALGORITHM_MAX + 1];
|
|
||||||
|
|
||||||
int cc_flags; /* (d) flags */
|
int cc_flags; /* (d) flags */
|
||||||
#define CRYPTOCAP_F_CLEANUP 0x80000000 /* needs resource cleanup */
|
#define CRYPTOCAP_F_CLEANUP 0x80000000 /* needs resource cleanup */
|
||||||
int cc_qblocked; /* (q) symmetric q blocked */
|
int cc_qblocked; /* (q) symmetric q blocked */
|
||||||
int cc_kqblocked; /* (q) asymmetric q blocked */
|
|
||||||
size_t cc_session_size;
|
size_t cc_session_size;
|
||||||
volatile int cc_refs;
|
volatile int cc_refs;
|
||||||
};
|
};
|
||||||
@ -139,16 +135,8 @@ struct crypto_session {
|
|||||||
/* Driver softc follows. */
|
/* Driver softc follows. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* There are two queues for crypto requests; one for symmetric (e.g.
|
|
||||||
* cipher) operations and one for asymmetric (e.g. MOD)operations.
|
|
||||||
* A single mutex is used to lock access to both queues. We could
|
|
||||||
* have one per-queue but having one simplifies handling of block/unblock
|
|
||||||
* operations.
|
|
||||||
*/
|
|
||||||
static int crp_sleep = 0;
|
static int crp_sleep = 0;
|
||||||
static TAILQ_HEAD(cryptop_q ,cryptop) crp_q; /* request queues */
|
static TAILQ_HEAD(cryptop_q ,cryptop) crp_q; /* request queues */
|
||||||
static TAILQ_HEAD(,cryptkop) crp_kq;
|
|
||||||
static struct mtx crypto_q_mtx;
|
static struct mtx crypto_q_mtx;
|
||||||
#define CRYPTO_Q_LOCK() mtx_lock(&crypto_q_mtx)
|
#define CRYPTO_Q_LOCK() mtx_lock(&crypto_q_mtx)
|
||||||
#define CRYPTO_Q_UNLOCK() mtx_unlock(&crypto_q_mtx)
|
#define CRYPTO_Q_UNLOCK() mtx_unlock(&crypto_q_mtx)
|
||||||
@ -172,7 +160,6 @@ struct crypto_ret_worker {
|
|||||||
|
|
||||||
TAILQ_HEAD(,cryptop) crp_ordered_ret_q; /* ordered callback queue for symetric jobs */
|
TAILQ_HEAD(,cryptop) crp_ordered_ret_q; /* ordered callback queue for symetric jobs */
|
||||||
TAILQ_HEAD(,cryptop) crp_ret_q; /* callback queue for symetric jobs */
|
TAILQ_HEAD(,cryptop) crp_ret_q; /* callback queue for symetric jobs */
|
||||||
TAILQ_HEAD(,cryptkop) crp_ret_kq; /* callback queue for asym jobs */
|
|
||||||
|
|
||||||
uint32_t reorder_ops; /* total ordered sym jobs received */
|
uint32_t reorder_ops; /* total ordered sym jobs received */
|
||||||
uint32_t reorder_cur_seq; /* current sym job dispatched */
|
uint32_t reorder_cur_seq; /* current sym job dispatched */
|
||||||
@ -201,16 +188,6 @@ SYSCTL_INT(_kern, OID_AUTO, crypto_workers_num, CTLFLAG_RDTUN,
|
|||||||
|
|
||||||
static uma_zone_t cryptop_zone;
|
static uma_zone_t cryptop_zone;
|
||||||
|
|
||||||
int crypto_userasymcrypto = 1;
|
|
||||||
SYSCTL_INT(_kern_crypto, OID_AUTO, asym_enable, CTLFLAG_RW,
|
|
||||||
&crypto_userasymcrypto, 0,
|
|
||||||
"Enable user-mode access to asymmetric crypto support");
|
|
||||||
#ifdef COMPAT_FREEBSD12
|
|
||||||
SYSCTL_INT(_kern, OID_AUTO, userasymcrypto, CTLFLAG_RW,
|
|
||||||
&crypto_userasymcrypto, 0,
|
|
||||||
"Enable/disable user-mode access to asymmetric crypto support");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int crypto_devallowsoft = 0;
|
int crypto_devallowsoft = 0;
|
||||||
SYSCTL_INT(_kern_crypto, OID_AUTO, allow_soft, CTLFLAG_RW,
|
SYSCTL_INT(_kern_crypto, OID_AUTO, allow_soft, CTLFLAG_RW,
|
||||||
&crypto_devallowsoft, 0,
|
&crypto_devallowsoft, 0,
|
||||||
@ -228,7 +205,6 @@ static struct proc *cryptoproc;
|
|||||||
static void crypto_ret_proc(struct crypto_ret_worker *ret_worker);
|
static void crypto_ret_proc(struct crypto_ret_worker *ret_worker);
|
||||||
static void crypto_destroy(void);
|
static void crypto_destroy(void);
|
||||||
static int crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint);
|
static int crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint);
|
||||||
static int crypto_kinvoke(struct cryptkop *krp);
|
|
||||||
static void crypto_task_invoke(void *ctx, int pending);
|
static void crypto_task_invoke(void *ctx, int pending);
|
||||||
static void crypto_batch_enqueue(struct cryptop *crp);
|
static void crypto_batch_enqueue(struct cryptop *crp);
|
||||||
|
|
||||||
@ -308,8 +284,6 @@ cap_rele(struct cryptocap *cap)
|
|||||||
|
|
||||||
KASSERT(cap->cc_sessions == 0,
|
KASSERT(cap->cc_sessions == 0,
|
||||||
("freeing crypto driver with active sessions"));
|
("freeing crypto driver with active sessions"));
|
||||||
KASSERT(cap->cc_koperations == 0,
|
|
||||||
("freeing crypto driver with active key operations"));
|
|
||||||
|
|
||||||
free(cap, M_CRYPTO_DATA);
|
free(cap, M_CRYPTO_DATA);
|
||||||
}
|
}
|
||||||
@ -324,7 +298,6 @@ crypto_init(void)
|
|||||||
MTX_DEF|MTX_QUIET);
|
MTX_DEF|MTX_QUIET);
|
||||||
|
|
||||||
TAILQ_INIT(&crp_q);
|
TAILQ_INIT(&crp_q);
|
||||||
TAILQ_INIT(&crp_kq);
|
|
||||||
mtx_init(&crypto_q_mtx, "crypto", "crypto op queues", MTX_DEF);
|
mtx_init(&crypto_q_mtx, "crypto", "crypto op queues", MTX_DEF);
|
||||||
|
|
||||||
cryptop_zone = uma_zcreate("cryptop",
|
cryptop_zone = uma_zcreate("cryptop",
|
||||||
@ -358,7 +331,6 @@ crypto_init(void)
|
|||||||
FOREACH_CRYPTO_RETW(ret_worker) {
|
FOREACH_CRYPTO_RETW(ret_worker) {
|
||||||
TAILQ_INIT(&ret_worker->crp_ordered_ret_q);
|
TAILQ_INIT(&ret_worker->crp_ordered_ret_q);
|
||||||
TAILQ_INIT(&ret_worker->crp_ret_q);
|
TAILQ_INIT(&ret_worker->crp_ret_q);
|
||||||
TAILQ_INIT(&ret_worker->crp_ret_kq);
|
|
||||||
|
|
||||||
ret_worker->reorder_ops = 0;
|
ret_worker->reorder_ops = 0;
|
||||||
ret_worker->reorder_cur_seq = 0;
|
ret_worker->reorder_cur_seq = 0;
|
||||||
@ -1114,43 +1086,6 @@ crypto_getcaps(int hid)
|
|||||||
return (flags);
|
return (flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Register support for a key-related algorithm. This routine
|
|
||||||
* is called once for each algorithm supported a driver.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
crypto_kregister(uint32_t driverid, int kalg, uint32_t flags)
|
|
||||||
{
|
|
||||||
struct cryptocap *cap;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
CRYPTO_DRIVER_LOCK();
|
|
||||||
|
|
||||||
cap = crypto_checkdriver(driverid);
|
|
||||||
if (cap != NULL &&
|
|
||||||
(CRK_ALGORITM_MIN <= kalg && kalg <= CRK_ALGORITHM_MAX)) {
|
|
||||||
/*
|
|
||||||
* XXX Do some performance testing to determine placing.
|
|
||||||
* XXX We probably need an auxiliary data structure that
|
|
||||||
* XXX describes relative performances.
|
|
||||||
*/
|
|
||||||
|
|
||||||
cap->cc_kalg[kalg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
|
|
||||||
if (bootverbose)
|
|
||||||
printf("crypto: %s registers key alg %u flags %u\n"
|
|
||||||
, device_get_nameunit(cap->cc_dev)
|
|
||||||
, kalg
|
|
||||||
, flags
|
|
||||||
);
|
|
||||||
gone_in_dev(cap->cc_dev, 14, "asymmetric crypto");
|
|
||||||
err = 0;
|
|
||||||
} else
|
|
||||||
err = EINVAL;
|
|
||||||
|
|
||||||
CRYPTO_DRIVER_UNLOCK();
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unregister all algorithms associated with a crypto driver.
|
* Unregister all algorithms associated with a crypto driver.
|
||||||
* If there are pending sessions using it, leave enough information
|
* If there are pending sessions using it, leave enough information
|
||||||
@ -1177,7 +1112,7 @@ crypto_unregister_all(uint32_t driverid)
|
|||||||
* XXX: This doesn't do anything to kick sessions that
|
* XXX: This doesn't do anything to kick sessions that
|
||||||
* have no pending operations.
|
* have no pending operations.
|
||||||
*/
|
*/
|
||||||
while (cap->cc_sessions != 0 || cap->cc_koperations != 0)
|
while (cap->cc_sessions != 0)
|
||||||
mtx_sleep(cap, &crypto_drivers_mtx, 0, "cryunreg", 0);
|
mtx_sleep(cap, &crypto_drivers_mtx, 0, "cryunreg", 0);
|
||||||
CRYPTO_DRIVER_UNLOCK();
|
CRYPTO_DRIVER_UNLOCK();
|
||||||
cap_rele(cap);
|
cap_rele(cap);
|
||||||
@ -1200,8 +1135,6 @@ crypto_unblock(uint32_t driverid, int what)
|
|||||||
if (cap != NULL) {
|
if (cap != NULL) {
|
||||||
if (what & CRYPTO_SYMQ)
|
if (what & CRYPTO_SYMQ)
|
||||||
cap->cc_qblocked = 0;
|
cap->cc_qblocked = 0;
|
||||||
if (what & CRYPTO_ASYMQ)
|
|
||||||
cap->cc_kqblocked = 0;
|
|
||||||
if (crp_sleep)
|
if (crp_sleep)
|
||||||
wakeup_one(&crp_q);
|
wakeup_one(&crp_q);
|
||||||
err = 0;
|
err = 0;
|
||||||
@ -1499,189 +1432,6 @@ crypto_batch_enqueue(struct cryptop *crp)
|
|||||||
CRYPTO_Q_UNLOCK();
|
CRYPTO_Q_UNLOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Add an asymetric crypto request to a queue,
|
|
||||||
* to be processed by the kernel thread.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
crypto_kdispatch(struct cryptkop *krp)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
|
|
||||||
CRYPTOSTAT_INC(cs_kops);
|
|
||||||
|
|
||||||
krp->krp_cap = NULL;
|
|
||||||
error = crypto_kinvoke(krp);
|
|
||||||
if (error == ERESTART) {
|
|
||||||
CRYPTO_Q_LOCK();
|
|
||||||
TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);
|
|
||||||
if (crp_sleep)
|
|
||||||
wakeup_one(&crp_q);
|
|
||||||
CRYPTO_Q_UNLOCK();
|
|
||||||
error = 0;
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Verify a driver is suitable for the specified operation.
|
|
||||||
*/
|
|
||||||
static __inline int
|
|
||||||
kdriver_suitable(const struct cryptocap *cap, const struct cryptkop *krp)
|
|
||||||
{
|
|
||||||
return (cap->cc_kalg[krp->krp_op] & CRYPTO_ALG_FLAG_SUPPORTED) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Select a driver for an asym operation. The driver must
|
|
||||||
* support the necessary algorithm. The caller can constrain
|
|
||||||
* which device is selected with the flags parameter. The
|
|
||||||
* algorithm we use here is pretty stupid; just use the first
|
|
||||||
* driver that supports the algorithms we need. If there are
|
|
||||||
* multiple suitable drivers we choose the driver with the
|
|
||||||
* fewest active operations. We prefer hardware-backed
|
|
||||||
* drivers to software ones when either may be used.
|
|
||||||
*/
|
|
||||||
static struct cryptocap *
|
|
||||||
crypto_select_kdriver(const struct cryptkop *krp, int flags)
|
|
||||||
{
|
|
||||||
struct cryptocap *cap, *best;
|
|
||||||
int match, hid;
|
|
||||||
|
|
||||||
CRYPTO_DRIVER_ASSERT();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Look first for hardware crypto devices if permitted.
|
|
||||||
*/
|
|
||||||
if (flags & CRYPTOCAP_F_HARDWARE)
|
|
||||||
match = CRYPTOCAP_F_HARDWARE;
|
|
||||||
else
|
|
||||||
match = CRYPTOCAP_F_SOFTWARE;
|
|
||||||
best = NULL;
|
|
||||||
again:
|
|
||||||
for (hid = 0; hid < crypto_drivers_size; hid++) {
|
|
||||||
/*
|
|
||||||
* If there is no driver for this slot, or the driver
|
|
||||||
* is not appropriate (hardware or software based on
|
|
||||||
* match), then skip.
|
|
||||||
*/
|
|
||||||
cap = crypto_drivers[hid];
|
|
||||||
if (cap == NULL ||
|
|
||||||
(cap->cc_flags & match) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* verify all the algorithms are supported. */
|
|
||||||
if (kdriver_suitable(cap, krp)) {
|
|
||||||
if (best == NULL ||
|
|
||||||
cap->cc_koperations < best->cc_koperations)
|
|
||||||
best = cap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (best != NULL)
|
|
||||||
return best;
|
|
||||||
if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) {
|
|
||||||
/* sort of an Algol 68-style for loop */
|
|
||||||
match = CRYPTOCAP_F_SOFTWARE;
|
|
||||||
goto again;
|
|
||||||
}
|
|
||||||
return best;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Choose a driver for an asymmetric crypto request.
|
|
||||||
*/
|
|
||||||
static struct cryptocap *
|
|
||||||
crypto_lookup_kdriver(struct cryptkop *krp)
|
|
||||||
{
|
|
||||||
struct cryptocap *cap;
|
|
||||||
uint32_t crid;
|
|
||||||
|
|
||||||
/* If this request is requeued, it might already have a driver. */
|
|
||||||
cap = krp->krp_cap;
|
|
||||||
if (cap != NULL)
|
|
||||||
return (cap);
|
|
||||||
|
|
||||||
/* Use krp_crid to choose a driver. */
|
|
||||||
crid = krp->krp_crid;
|
|
||||||
if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
|
|
||||||
cap = crypto_checkdriver(crid);
|
|
||||||
if (cap != NULL) {
|
|
||||||
/*
|
|
||||||
* Driver present, it must support the
|
|
||||||
* necessary algorithm and, if s/w drivers are
|
|
||||||
* excluded, it must be registered as
|
|
||||||
* hardware-backed.
|
|
||||||
*/
|
|
||||||
if (!kdriver_suitable(cap, krp) ||
|
|
||||||
(!crypto_devallowsoft &&
|
|
||||||
(cap->cc_flags & CRYPTOCAP_F_HARDWARE) == 0))
|
|
||||||
cap = NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* No requested driver; select based on crid flags.
|
|
||||||
*/
|
|
||||||
if (!crypto_devallowsoft) /* NB: disallow s/w drivers */
|
|
||||||
crid &= ~CRYPTOCAP_F_SOFTWARE;
|
|
||||||
cap = crypto_select_kdriver(krp, crid);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cap != NULL) {
|
|
||||||
krp->krp_cap = cap_ref(cap);
|
|
||||||
krp->krp_hid = cap->cc_hid;
|
|
||||||
}
|
|
||||||
return (cap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Dispatch an asymmetric crypto request.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
crypto_kinvoke(struct cryptkop *krp)
|
|
||||||
{
|
|
||||||
struct cryptocap *cap = NULL;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
KASSERT(krp != NULL, ("%s: krp == NULL", __func__));
|
|
||||||
KASSERT(krp->krp_callback != NULL,
|
|
||||||
("%s: krp->crp_callback == NULL", __func__));
|
|
||||||
|
|
||||||
CRYPTO_DRIVER_LOCK();
|
|
||||||
cap = crypto_lookup_kdriver(krp);
|
|
||||||
if (cap == NULL) {
|
|
||||||
CRYPTO_DRIVER_UNLOCK();
|
|
||||||
krp->krp_status = ENODEV;
|
|
||||||
crypto_kdone(krp);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the device is blocked, return ERESTART to requeue it.
|
|
||||||
*/
|
|
||||||
if (cap->cc_kqblocked) {
|
|
||||||
/*
|
|
||||||
* XXX: Previously this set krp_status to ERESTART and
|
|
||||||
* invoked crypto_kdone but the caller would still
|
|
||||||
* requeue it.
|
|
||||||
*/
|
|
||||||
CRYPTO_DRIVER_UNLOCK();
|
|
||||||
return (ERESTART);
|
|
||||||
}
|
|
||||||
|
|
||||||
cap->cc_koperations++;
|
|
||||||
CRYPTO_DRIVER_UNLOCK();
|
|
||||||
error = CRYPTODEV_KPROCESS(cap->cc_dev, krp, 0);
|
|
||||||
if (error == ERESTART) {
|
|
||||||
CRYPTO_DRIVER_LOCK();
|
|
||||||
cap->cc_koperations--;
|
|
||||||
CRYPTO_DRIVER_UNLOCK();
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
KASSERT(error == 0, ("error %d returned from crypto_kprocess", error));
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
crypto_task_invoke(void *ctx, int pending)
|
crypto_task_invoke(void *ctx, int pending)
|
||||||
{
|
{
|
||||||
@ -1894,62 +1644,6 @@ crypto_done(struct cryptop *crp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Invoke the callback on behalf of the driver.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
crypto_kdone(struct cryptkop *krp)
|
|
||||||
{
|
|
||||||
struct crypto_ret_worker *ret_worker;
|
|
||||||
struct cryptocap *cap;
|
|
||||||
|
|
||||||
if (krp->krp_status != 0)
|
|
||||||
CRYPTOSTAT_INC(cs_kerrs);
|
|
||||||
cap = krp->krp_cap;
|
|
||||||
if (cap != NULL) {
|
|
||||||
CRYPTO_DRIVER_LOCK();
|
|
||||||
KASSERT(cap->cc_koperations > 0, ("cc_koperations == 0"));
|
|
||||||
cap->cc_koperations--;
|
|
||||||
if (cap->cc_koperations == 0 &&
|
|
||||||
cap->cc_flags & CRYPTOCAP_F_CLEANUP)
|
|
||||||
wakeup(cap);
|
|
||||||
CRYPTO_DRIVER_UNLOCK();
|
|
||||||
krp->krp_cap = NULL;
|
|
||||||
cap_rele(cap);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret_worker = CRYPTO_RETW(0);
|
|
||||||
|
|
||||||
CRYPTO_RETW_LOCK(ret_worker);
|
|
||||||
if (TAILQ_EMPTY(&ret_worker->crp_ret_kq))
|
|
||||||
wakeup_one(&ret_worker->crp_ret_q); /* shared wait channel */
|
|
||||||
TAILQ_INSERT_TAIL(&ret_worker->crp_ret_kq, krp, krp_next);
|
|
||||||
CRYPTO_RETW_UNLOCK(ret_worker);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
crypto_getfeat(int *featp)
|
|
||||||
{
|
|
||||||
int hid, kalg, feat = 0;
|
|
||||||
|
|
||||||
CRYPTO_DRIVER_LOCK();
|
|
||||||
for (hid = 0; hid < crypto_drivers_size; hid++) {
|
|
||||||
const struct cryptocap *cap = crypto_drivers[hid];
|
|
||||||
|
|
||||||
if (cap == NULL ||
|
|
||||||
((cap->cc_flags & CRYPTOCAP_F_SOFTWARE) &&
|
|
||||||
!crypto_devallowsoft)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (kalg = 0; kalg < CRK_ALGORITHM_MAX; kalg++)
|
|
||||||
if (cap->cc_kalg[kalg] & CRYPTO_ALG_FLAG_SUPPORTED)
|
|
||||||
feat |= 1 << kalg;
|
|
||||||
}
|
|
||||||
CRYPTO_DRIVER_UNLOCK();
|
|
||||||
*featp = feat;
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Terminate a thread at module unload. The process that
|
* Terminate a thread at module unload. The process that
|
||||||
* initiated this is waiting for us to signal that we're gone;
|
* initiated this is waiting for us to signal that we're gone;
|
||||||
@ -1975,7 +1669,6 @@ static void
|
|||||||
crypto_proc(void)
|
crypto_proc(void)
|
||||||
{
|
{
|
||||||
struct cryptop *crp, *submit;
|
struct cryptop *crp, *submit;
|
||||||
struct cryptkop *krp;
|
|
||||||
struct cryptocap *cap;
|
struct cryptocap *cap;
|
||||||
int result, hint;
|
int result, hint;
|
||||||
|
|
||||||
@ -2046,46 +1739,7 @@ crypto_proc(void)
|
|||||||
TAILQ_INSERT_HEAD(&crp_q, submit, crp_next);
|
TAILQ_INSERT_HEAD(&crp_q, submit, crp_next);
|
||||||
CRYPTOSTAT_INC(cs_blocks);
|
CRYPTOSTAT_INC(cs_blocks);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
|
||||||
/* As above, but for key ops */
|
|
||||||
TAILQ_FOREACH(krp, &crp_kq, krp_next) {
|
|
||||||
cap = krp->krp_cap;
|
|
||||||
if (cap->cc_flags & CRYPTOCAP_F_CLEANUP) {
|
|
||||||
/*
|
|
||||||
* Operation needs to be migrated,
|
|
||||||
* clear krp_cap so a new driver is
|
|
||||||
* selected.
|
|
||||||
*/
|
|
||||||
krp->krp_cap = NULL;
|
|
||||||
cap_rele(cap);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!cap->cc_kqblocked)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (krp != NULL) {
|
|
||||||
TAILQ_REMOVE(&crp_kq, krp, krp_next);
|
|
||||||
CRYPTO_Q_UNLOCK();
|
|
||||||
result = crypto_kinvoke(krp);
|
|
||||||
CRYPTO_Q_LOCK();
|
|
||||||
if (result == ERESTART) {
|
|
||||||
/*
|
|
||||||
* The driver ran out of resources, mark the
|
|
||||||
* driver ``blocked'' for cryptkop's and put
|
|
||||||
* the request back in the queue. It would
|
|
||||||
* best to put the request back where we got
|
|
||||||
* it but that's hard so for now we put it
|
|
||||||
* at the front. This should be ok; putting
|
|
||||||
* it at the end does not work.
|
|
||||||
*/
|
|
||||||
krp->krp_cap->cc_kqblocked = 1;
|
|
||||||
TAILQ_INSERT_HEAD(&crp_kq, krp, krp_next);
|
|
||||||
CRYPTOSTAT_INC(cs_kblocks);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (submit == NULL && krp == NULL) {
|
|
||||||
/*
|
/*
|
||||||
* Nothing more to be processed. Sleep until we're
|
* Nothing more to be processed. Sleep until we're
|
||||||
* woken because there are more ops to process.
|
* woken because there are more ops to process.
|
||||||
@ -2120,7 +1774,6 @@ static void
|
|||||||
crypto_ret_proc(struct crypto_ret_worker *ret_worker)
|
crypto_ret_proc(struct crypto_ret_worker *ret_worker)
|
||||||
{
|
{
|
||||||
struct cryptop *crpt;
|
struct cryptop *crpt;
|
||||||
struct cryptkop *krpt;
|
|
||||||
|
|
||||||
CRYPTO_RETW_LOCK(ret_worker);
|
CRYPTO_RETW_LOCK(ret_worker);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -2141,19 +1794,13 @@ crypto_ret_proc(struct crypto_ret_worker *ret_worker)
|
|||||||
TAILQ_REMOVE(&ret_worker->crp_ret_q, crpt, crp_next);
|
TAILQ_REMOVE(&ret_worker->crp_ret_q, crpt, crp_next);
|
||||||
}
|
}
|
||||||
|
|
||||||
krpt = TAILQ_FIRST(&ret_worker->crp_ret_kq);
|
if (crpt != NULL) {
|
||||||
if (krpt != NULL)
|
|
||||||
TAILQ_REMOVE(&ret_worker->crp_ret_kq, krpt, krp_next);
|
|
||||||
|
|
||||||
if (crpt != NULL || krpt != NULL) {
|
|
||||||
CRYPTO_RETW_UNLOCK(ret_worker);
|
CRYPTO_RETW_UNLOCK(ret_worker);
|
||||||
/*
|
/*
|
||||||
* Run callbacks unlocked.
|
* Run callbacks unlocked.
|
||||||
*/
|
*/
|
||||||
if (crpt != NULL)
|
if (crpt != NULL)
|
||||||
crpt->crp_callback(crpt);
|
crpt->crp_callback(crpt);
|
||||||
if (krpt != NULL)
|
|
||||||
krpt->krp_callback(krpt);
|
|
||||||
CRYPTO_RETW_LOCK(ret_worker);
|
CRYPTO_RETW_LOCK(ret_worker);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
@ -2178,25 +1825,21 @@ db_show_drivers(void)
|
|||||||
{
|
{
|
||||||
int hid;
|
int hid;
|
||||||
|
|
||||||
db_printf("%12s %4s %4s %8s %2s %2s\n"
|
db_printf("%12s %4s %8s %2s\n"
|
||||||
, "Device"
|
, "Device"
|
||||||
, "Ses"
|
, "Ses"
|
||||||
, "Kops"
|
|
||||||
, "Flags"
|
, "Flags"
|
||||||
, "QB"
|
, "QB"
|
||||||
, "KB"
|
|
||||||
);
|
);
|
||||||
for (hid = 0; hid < crypto_drivers_size; hid++) {
|
for (hid = 0; hid < crypto_drivers_size; hid++) {
|
||||||
const struct cryptocap *cap = crypto_drivers[hid];
|
const struct cryptocap *cap = crypto_drivers[hid];
|
||||||
if (cap == NULL)
|
if (cap == NULL)
|
||||||
continue;
|
continue;
|
||||||
db_printf("%-12s %4u %4u %08x %2u %2u\n"
|
db_printf("%-12s %4u %08x %2u\n"
|
||||||
, device_get_nameunit(cap->cc_dev)
|
, device_get_nameunit(cap->cc_dev)
|
||||||
, cap->cc_sessions
|
, cap->cc_sessions
|
||||||
, cap->cc_koperations
|
|
||||||
, cap->cc_flags
|
, cap->cc_flags
|
||||||
, cap->cc_qblocked
|
, cap->cc_qblocked
|
||||||
, cap->cc_kqblocked
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2239,41 +1882,6 @@ DB_SHOW_COMMAND(crypto, db_show_crypto)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DB_SHOW_COMMAND(kcrypto, db_show_kcrypto)
|
|
||||||
{
|
|
||||||
struct cryptkop *krp;
|
|
||||||
struct crypto_ret_worker *ret_worker;
|
|
||||||
|
|
||||||
db_show_drivers();
|
|
||||||
db_printf("\n");
|
|
||||||
|
|
||||||
db_printf("%4s %5s %4s %4s %8s %4s %8s\n",
|
|
||||||
"Op", "Status", "#IP", "#OP", "CRID", "HID", "Callback");
|
|
||||||
TAILQ_FOREACH(krp, &crp_kq, krp_next) {
|
|
||||||
db_printf("%4u %5u %4u %4u %08x %4u %8p\n"
|
|
||||||
, krp->krp_op
|
|
||||||
, krp->krp_status
|
|
||||||
, krp->krp_iparams, krp->krp_oparams
|
|
||||||
, krp->krp_crid, krp->krp_hid
|
|
||||||
, krp->krp_callback
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret_worker = CRYPTO_RETW(0);
|
|
||||||
if (!TAILQ_EMPTY(&ret_worker->crp_ret_q)) {
|
|
||||||
db_printf("%4s %5s %8s %4s %8s\n",
|
|
||||||
"Op", "Status", "CRID", "HID", "Callback");
|
|
||||||
TAILQ_FOREACH(krp, &ret_worker->crp_ret_kq, krp_next) {
|
|
||||||
db_printf("%4u %5u %08x %4u %8p\n"
|
|
||||||
, krp->krp_op
|
|
||||||
, krp->krp_status
|
|
||||||
, krp->krp_crid, krp->krp_hid
|
|
||||||
, krp->krp_callback
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int crypto_modevent(module_t mod, int type, void *unused);
|
int crypto_modevent(module_t mod, int type, void *unused);
|
||||||
|
@ -127,25 +127,9 @@ struct crypt_aead32 {
|
|||||||
uint32_t iv;
|
uint32_t iv;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct crparam32 {
|
|
||||||
uint32_t crp_p;
|
|
||||||
u_int crp_nbits;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct crypt_kop32 {
|
|
||||||
u_int crk_op;
|
|
||||||
u_int crk_status;
|
|
||||||
u_short crk_iparams;
|
|
||||||
u_short crk_oparams;
|
|
||||||
u_int crk_crid;
|
|
||||||
struct crparam32 crk_param[CRK_MAXPARAM];
|
|
||||||
};
|
|
||||||
|
|
||||||
#define CIOCGSESSION32 _IOWR('c', 101, struct session_op32)
|
#define CIOCGSESSION32 _IOWR('c', 101, struct session_op32)
|
||||||
#define CIOCCRYPT32 _IOWR('c', 103, struct crypt_op32)
|
#define CIOCCRYPT32 _IOWR('c', 103, struct crypt_op32)
|
||||||
#define CIOCKEY32 _IOWR('c', 104, struct crypt_kop32)
|
|
||||||
#define CIOCGSESSION232 _IOWR('c', 106, struct session2_op32)
|
#define CIOCGSESSION232 _IOWR('c', 106, struct session2_op32)
|
||||||
#define CIOCKEY232 _IOWR('c', 107, struct crypt_kop32)
|
|
||||||
#define CIOCCRYPTAEAD32 _IOWR('c', 109, struct crypt_aead32)
|
#define CIOCCRYPTAEAD32 _IOWR('c', 109, struct crypt_aead32)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -253,50 +237,6 @@ crypt_aead_to_32(const struct crypt_aead *from, struct crypt_aead32 *to)
|
|||||||
PTROUT_CP(*from, *to, tag);
|
PTROUT_CP(*from, *to, tag);
|
||||||
PTROUT_CP(*from, *to, iv);
|
PTROUT_CP(*from, *to, iv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
crparam_from_32(const struct crparam32 *from, struct crparam *to)
|
|
||||||
{
|
|
||||||
|
|
||||||
PTRIN_CP(*from, *to, crp_p);
|
|
||||||
CP(*from, *to, crp_nbits);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
crparam_to_32(const struct crparam *from, struct crparam32 *to)
|
|
||||||
{
|
|
||||||
|
|
||||||
PTROUT_CP(*from, *to, crp_p);
|
|
||||||
CP(*from, *to, crp_nbits);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
crypt_kop_from_32(const struct crypt_kop32 *from, struct crypt_kop *to)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
CP(*from, *to, crk_op);
|
|
||||||
CP(*from, *to, crk_status);
|
|
||||||
CP(*from, *to, crk_iparams);
|
|
||||||
CP(*from, *to, crk_oparams);
|
|
||||||
CP(*from, *to, crk_crid);
|
|
||||||
for (i = 0; i < CRK_MAXPARAM; i++)
|
|
||||||
crparam_from_32(&from->crk_param[i], &to->crk_param[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
crypt_kop_to_32(const struct crypt_kop *from, struct crypt_kop32 *to)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
CP(*from, *to, crk_op);
|
|
||||||
CP(*from, *to, crk_status);
|
|
||||||
CP(*from, *to, crk_iparams);
|
|
||||||
CP(*from, *to, crk_oparams);
|
|
||||||
CP(*from, *to, crk_crid);
|
|
||||||
for (i = 0; i < CRK_MAXPARAM; i++)
|
|
||||||
crparam_to_32(&from->crk_param[i], &to->crk_param[i]);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -356,11 +296,6 @@ SYSCTL_BOOL(_kern_crypto, OID_AUTO, cryptodev_separate_aad, CTLFLAG_RW,
|
|||||||
&use_separate_aad, 0,
|
&use_separate_aad, 0,
|
||||||
"Use separate AAD buffer for /dev/crypto requests.");
|
"Use separate AAD buffer for /dev/crypto requests.");
|
||||||
|
|
||||||
static struct timeval warninterval = { .tv_sec = 60, .tv_usec = 0 };
|
|
||||||
SYSCTL_TIMEVAL_SEC(_kern, OID_AUTO, cryptodev_warn_interval, CTLFLAG_RW,
|
|
||||||
&warninterval,
|
|
||||||
"Delay in seconds between warnings of deprecated /dev/crypto algorithms");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check a crypto identifier to see if it requested
|
* Check a crypto identifier to see if it requested
|
||||||
* a software device/driver. This can be done either
|
* a software device/driver. This can be done either
|
||||||
@ -1208,131 +1143,6 @@ cryptodev_aead(struct csession *cse, struct crypt_aead *caead)
|
|||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
cryptodevkey_cb(struct cryptkop *krp)
|
|
||||||
{
|
|
||||||
|
|
||||||
wakeup_one(krp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
cryptodev_key(struct crypt_kop *kop)
|
|
||||||
{
|
|
||||||
struct cryptkop *krp = NULL;
|
|
||||||
int error = EINVAL;
|
|
||||||
int in, out, size, i;
|
|
||||||
|
|
||||||
if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) {
|
|
||||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
|
||||||
return (EFBIG);
|
|
||||||
}
|
|
||||||
|
|
||||||
in = kop->crk_iparams;
|
|
||||||
out = kop->crk_oparams;
|
|
||||||
switch (kop->crk_op) {
|
|
||||||
case CRK_MOD_EXP:
|
|
||||||
if (in == 3 && out == 1)
|
|
||||||
break;
|
|
||||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
|
||||||
return (EINVAL);
|
|
||||||
case CRK_MOD_EXP_CRT:
|
|
||||||
if (in == 6 && out == 1)
|
|
||||||
break;
|
|
||||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
|
||||||
return (EINVAL);
|
|
||||||
case CRK_DSA_SIGN:
|
|
||||||
if (in == 5 && out == 2)
|
|
||||||
break;
|
|
||||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
|
||||||
return (EINVAL);
|
|
||||||
case CRK_DSA_VERIFY:
|
|
||||||
if (in == 7 && out == 0)
|
|
||||||
break;
|
|
||||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
|
||||||
return (EINVAL);
|
|
||||||
case CRK_DH_COMPUTE_KEY:
|
|
||||||
if (in == 3 && out == 1)
|
|
||||||
break;
|
|
||||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
|
||||||
return (EINVAL);
|
|
||||||
default:
|
|
||||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
|
||||||
return (EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
krp = malloc(sizeof(*krp), M_XDATA, M_WAITOK | M_ZERO);
|
|
||||||
krp->krp_op = kop->crk_op;
|
|
||||||
krp->krp_status = kop->crk_status;
|
|
||||||
krp->krp_iparams = kop->crk_iparams;
|
|
||||||
krp->krp_oparams = kop->crk_oparams;
|
|
||||||
krp->krp_crid = kop->crk_crid;
|
|
||||||
krp->krp_status = 0;
|
|
||||||
krp->krp_callback = cryptodevkey_cb;
|
|
||||||
|
|
||||||
for (i = 0; i < CRK_MAXPARAM; i++) {
|
|
||||||
if (kop->crk_param[i].crp_nbits > 65536) {
|
|
||||||
/* Limit is the same as in OpenBSD */
|
|
||||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits;
|
|
||||||
}
|
|
||||||
for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) {
|
|
||||||
size = (krp->krp_param[i].crp_nbits + 7) / 8;
|
|
||||||
if (size == 0)
|
|
||||||
continue;
|
|
||||||
krp->krp_param[i].crp_p = malloc(size, M_XDATA, M_WAITOK);
|
|
||||||
if (i >= krp->krp_iparams)
|
|
||||||
continue;
|
|
||||||
error = copyin(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p, size);
|
|
||||||
if (error) {
|
|
||||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
error = crypto_kdispatch(krp);
|
|
||||||
if (error) {
|
|
||||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
error = tsleep(krp, PSOCK, "crydev", 0);
|
|
||||||
if (error) {
|
|
||||||
/* XXX can this happen? if so, how do we recover? */
|
|
||||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
kop->crk_crid = krp->krp_hid; /* device that did the work */
|
|
||||||
if (krp->krp_status != 0) {
|
|
||||||
error = krp->krp_status;
|
|
||||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) {
|
|
||||||
size = (krp->krp_param[i].crp_nbits + 7) / 8;
|
|
||||||
if (size == 0)
|
|
||||||
continue;
|
|
||||||
error = copyout(krp->krp_param[i].crp_p, kop->crk_param[i].crp_p, size);
|
|
||||||
if (error) {
|
|
||||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fail:
|
|
||||||
if (krp) {
|
|
||||||
kop->crk_status = krp->krp_status;
|
|
||||||
for (i = 0; i < CRK_MAXPARAM; i++) {
|
|
||||||
if (krp->krp_param[i].crp_p)
|
|
||||||
free(krp->krp_param[i].crp_p, M_XDATA);
|
|
||||||
}
|
|
||||||
free(krp, M_XDATA);
|
|
||||||
}
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cryptodev_find(struct crypt_find_op *find)
|
cryptodev_find(struct crypt_find_op *find)
|
||||||
{
|
{
|
||||||
@ -1390,13 +1200,11 @@ static int
|
|||||||
crypto_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
|
crypto_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
|
||||||
struct thread *td)
|
struct thread *td)
|
||||||
{
|
{
|
||||||
static struct timeval keywarn, featwarn;
|
|
||||||
struct fcrypt *fcr;
|
struct fcrypt *fcr;
|
||||||
struct csession *cse;
|
struct csession *cse;
|
||||||
struct session2_op *sop;
|
struct session2_op *sop;
|
||||||
struct crypt_op *cop;
|
struct crypt_op *cop;
|
||||||
struct crypt_aead *caead;
|
struct crypt_aead *caead;
|
||||||
struct crypt_kop *kop;
|
|
||||||
uint32_t ses;
|
uint32_t ses;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
union {
|
union {
|
||||||
@ -1404,7 +1212,6 @@ crypto_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
|
|||||||
#ifdef COMPAT_FREEBSD32
|
#ifdef COMPAT_FREEBSD32
|
||||||
struct crypt_op copc;
|
struct crypt_op copc;
|
||||||
struct crypt_aead aeadc;
|
struct crypt_aead aeadc;
|
||||||
struct crypt_kop kopc;
|
|
||||||
#endif
|
#endif
|
||||||
} thunk;
|
} thunk;
|
||||||
#ifdef COMPAT_FREEBSD32
|
#ifdef COMPAT_FREEBSD32
|
||||||
@ -1443,17 +1250,6 @@ crypto_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
|
|||||||
data = (void *)&thunk.aeadc;
|
data = (void *)&thunk.aeadc;
|
||||||
crypt_aead_from_32((struct crypt_aead32 *)data32, &thunk.aeadc);
|
crypt_aead_from_32((struct crypt_aead32 *)data32, &thunk.aeadc);
|
||||||
break;
|
break;
|
||||||
case CIOCKEY32:
|
|
||||||
case CIOCKEY232:
|
|
||||||
cmd32 = cmd;
|
|
||||||
data32 = data;
|
|
||||||
if (cmd == CIOCKEY32)
|
|
||||||
cmd = CIOCKEY;
|
|
||||||
else
|
|
||||||
cmd = CIOCKEY2;
|
|
||||||
data = (void *)&thunk.kopc;
|
|
||||||
crypt_kop_from_32((struct crypt_kop32 *)data32, &thunk.kopc);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1504,46 +1300,6 @@ crypto_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
|
|||||||
error = cryptodev_op(cse, cop);
|
error = cryptodev_op(cse, cop);
|
||||||
cse_free(cse);
|
cse_free(cse);
|
||||||
break;
|
break;
|
||||||
case CIOCKEY:
|
|
||||||
case CIOCKEY2:
|
|
||||||
if (ratecheck(&keywarn, &warninterval))
|
|
||||||
gone_in(14,
|
|
||||||
"Asymmetric crypto operations via /dev/crypto");
|
|
||||||
|
|
||||||
if (!crypto_userasymcrypto) {
|
|
||||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
|
||||||
return (EPERM); /* XXX compat? */
|
|
||||||
}
|
|
||||||
kop = (struct crypt_kop *)data;
|
|
||||||
if (cmd == CIOCKEY) {
|
|
||||||
/* NB: crypto core enforces s/w driver use */
|
|
||||||
kop->crk_crid =
|
|
||||||
CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
|
|
||||||
}
|
|
||||||
mtx_lock(&Giant);
|
|
||||||
error = cryptodev_key(kop);
|
|
||||||
mtx_unlock(&Giant);
|
|
||||||
break;
|
|
||||||
case CIOCASYMFEAT:
|
|
||||||
if (ratecheck(&featwarn, &warninterval))
|
|
||||||
gone_in(14,
|
|
||||||
"Asymmetric crypto features via /dev/crypto");
|
|
||||||
|
|
||||||
if (!crypto_userasymcrypto) {
|
|
||||||
/*
|
|
||||||
* NB: if user asym crypto operations are
|
|
||||||
* not permitted return "no algorithms"
|
|
||||||
* so well-behaved applications will just
|
|
||||||
* fallback to doing them in software.
|
|
||||||
*/
|
|
||||||
*(int *)data = 0;
|
|
||||||
} else {
|
|
||||||
error = crypto_getfeat((int *)data);
|
|
||||||
if (error)
|
|
||||||
SDT_PROBE1(opencrypto, dev, ioctl, error,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CIOCFINDDEV:
|
case CIOCFINDDEV:
|
||||||
error = cryptodev_find((struct crypt_find_op *)data);
|
error = cryptodev_find((struct crypt_find_op *)data);
|
||||||
break;
|
break;
|
||||||
@ -1581,10 +1337,6 @@ crypto_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
|
|||||||
if (error == 0)
|
if (error == 0)
|
||||||
crypt_aead_to_32((void *)data, data32);
|
crypt_aead_to_32((void *)data, data32);
|
||||||
break;
|
break;
|
||||||
case CIOCKEY32:
|
|
||||||
case CIOCKEY232:
|
|
||||||
crypt_kop_to_32((void *)data, data32);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return (error);
|
return (error);
|
||||||
|
@ -192,11 +192,6 @@
|
|||||||
#define CRYPTO_ALGO_VALID(x) ((x) >= CRYPTO_ALGORITHM_MIN && \
|
#define CRYPTO_ALGO_VALID(x) ((x) >= CRYPTO_ALGORITHM_MIN && \
|
||||||
(x) <= CRYPTO_ALGORITHM_MAX)
|
(x) <= CRYPTO_ALGORITHM_MAX)
|
||||||
|
|
||||||
/* Algorithm flags */
|
|
||||||
#define CRYPTO_ALG_FLAG_SUPPORTED 0x01 /* Algorithm is supported */
|
|
||||||
#define CRYPTO_ALG_FLAG_RNG_ENABLE 0x02 /* Has HW RNG for DH/DSA */
|
|
||||||
#define CRYPTO_ALG_FLAG_DSA_SHA 0x04 /* Can do SHA on msg */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Crypto driver/device flags. They can set in the crid
|
* Crypto driver/device flags. They can set in the crid
|
||||||
* parameter when creating a session or submitting a key
|
* parameter when creating a session or submitting a key
|
||||||
@ -289,43 +284,10 @@ struct crypt_find_op {
|
|||||||
char name[32]; /* device/driver name */
|
char name[32]; /* device/driver name */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* bignum parameter, in packed bytes, ... */
|
|
||||||
struct crparam {
|
|
||||||
void *crp_p;
|
|
||||||
u_int crp_nbits;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define CRK_MAXPARAM 8
|
|
||||||
|
|
||||||
struct crypt_kop {
|
|
||||||
u_int crk_op; /* ie. CRK_MOD_EXP or other */
|
|
||||||
u_int crk_status; /* return status */
|
|
||||||
u_short crk_iparams; /* # of input parameters */
|
|
||||||
u_short crk_oparams; /* # of output parameters */
|
|
||||||
u_int crk_crid; /* NB: only used by CIOCKEY2 (rw) */
|
|
||||||
struct crparam crk_param[CRK_MAXPARAM];
|
|
||||||
};
|
|
||||||
#define CRK_ALGORITM_MIN 0
|
|
||||||
#define CRK_MOD_EXP 0
|
|
||||||
#define CRK_MOD_EXP_CRT 1
|
|
||||||
#define CRK_DSA_SIGN 2
|
|
||||||
#define CRK_DSA_VERIFY 3
|
|
||||||
#define CRK_DH_COMPUTE_KEY 4
|
|
||||||
#define CRK_ALGORITHM_MAX 4 /* Keep updated - see below */
|
|
||||||
|
|
||||||
#define CRF_MOD_EXP (1 << CRK_MOD_EXP)
|
|
||||||
#define CRF_MOD_EXP_CRT (1 << CRK_MOD_EXP_CRT)
|
|
||||||
#define CRF_DSA_SIGN (1 << CRK_DSA_SIGN)
|
|
||||||
#define CRF_DSA_VERIFY (1 << CRK_DSA_VERIFY)
|
|
||||||
#define CRF_DH_COMPUTE_KEY (1 << CRK_DH_COMPUTE_KEY)
|
|
||||||
|
|
||||||
#define CIOCGSESSION _IOWR('c', 101, struct session_op)
|
#define CIOCGSESSION _IOWR('c', 101, struct session_op)
|
||||||
#define CIOCFSESSION _IOW('c', 102, uint32_t)
|
#define CIOCFSESSION _IOW('c', 102, uint32_t)
|
||||||
#define CIOCCRYPT _IOWR('c', 103, struct crypt_op)
|
#define CIOCCRYPT _IOWR('c', 103, struct crypt_op)
|
||||||
#define CIOCKEY _IOWR('c', 104, struct crypt_kop)
|
|
||||||
#define CIOCASYMFEAT _IOR('c', 105, uint32_t)
|
|
||||||
#define CIOCGSESSION2 _IOWR('c', 106, struct session2_op)
|
#define CIOCGSESSION2 _IOWR('c', 106, struct session2_op)
|
||||||
#define CIOCKEY2 _IOWR('c', 107, struct crypt_kop)
|
|
||||||
#define CIOCFINDDEV _IOWR('c', 108, struct crypt_find_op)
|
#define CIOCFINDDEV _IOWR('c', 108, struct crypt_find_op)
|
||||||
#define CIOCCRYPTAEAD _IOWR('c', 109, struct crypt_aead)
|
#define CIOCCRYPTAEAD _IOWR('c', 109, struct crypt_aead)
|
||||||
|
|
||||||
@ -602,20 +564,6 @@ crypto_use_output_uio(struct cryptop *crp, struct uio *uio)
|
|||||||
*/
|
*/
|
||||||
#define CRYPTO_HINT_MORE 0x1 /* more ops coming shortly */
|
#define CRYPTO_HINT_MORE 0x1 /* more ops coming shortly */
|
||||||
|
|
||||||
struct cryptkop {
|
|
||||||
TAILQ_ENTRY(cryptkop) krp_next;
|
|
||||||
|
|
||||||
u_int krp_op; /* ie. CRK_MOD_EXP or other */
|
|
||||||
u_int krp_status; /* return status */
|
|
||||||
u_short krp_iparams; /* # of input parameters */
|
|
||||||
u_short krp_oparams; /* # of output parameters */
|
|
||||||
u_int krp_crid; /* desired device, etc. */
|
|
||||||
uint32_t krp_hid; /* device used */
|
|
||||||
struct crparam krp_param[CRK_MAXPARAM]; /* kvm */
|
|
||||||
void (*krp_callback)(struct cryptkop *);
|
|
||||||
struct cryptocap *krp_cap;
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32_t crypto_ses2hid(crypto_session_t crypto_session);
|
uint32_t crypto_ses2hid(crypto_session_t crypto_session);
|
||||||
uint32_t crypto_ses2caps(crypto_session_t crypto_session);
|
uint32_t crypto_ses2caps(crypto_session_t crypto_session);
|
||||||
void *crypto_get_driver_session(crypto_session_t crypto_session);
|
void *crypto_get_driver_session(crypto_session_t crypto_session);
|
||||||
@ -640,19 +588,14 @@ extern int32_t crypto_get_driverid(device_t dev, size_t session_size,
|
|||||||
extern int crypto_find_driver(const char *);
|
extern int crypto_find_driver(const char *);
|
||||||
extern device_t crypto_find_device_byhid(int hid);
|
extern device_t crypto_find_device_byhid(int hid);
|
||||||
extern int crypto_getcaps(int hid);
|
extern int crypto_getcaps(int hid);
|
||||||
extern int crypto_kregister(uint32_t, int, uint32_t);
|
|
||||||
extern int crypto_unregister_all(uint32_t driverid);
|
extern int crypto_unregister_all(uint32_t driverid);
|
||||||
extern int crypto_dispatch(struct cryptop *crp);
|
extern int crypto_dispatch(struct cryptop *crp);
|
||||||
#define CRYPTO_ASYNC_ORDERED 0x1 /* complete in order dispatched */
|
#define CRYPTO_ASYNC_ORDERED 0x1 /* complete in order dispatched */
|
||||||
extern int crypto_dispatch_async(struct cryptop *crp, int flags);
|
extern int crypto_dispatch_async(struct cryptop *crp, int flags);
|
||||||
extern void crypto_dispatch_batch(struct cryptopq *crpq, int flags);
|
extern void crypto_dispatch_batch(struct cryptopq *crpq, int flags);
|
||||||
extern int crypto_kdispatch(struct cryptkop *);
|
|
||||||
#define CRYPTO_SYMQ 0x1
|
#define CRYPTO_SYMQ 0x1
|
||||||
#define CRYPTO_ASYMQ 0x2
|
|
||||||
extern int crypto_unblock(uint32_t, int);
|
extern int crypto_unblock(uint32_t, int);
|
||||||
extern void crypto_done(struct cryptop *crp);
|
extern void crypto_done(struct cryptop *crp);
|
||||||
extern void crypto_kdone(struct cryptkop *);
|
|
||||||
extern int crypto_getfeat(int *);
|
|
||||||
|
|
||||||
extern void crypto_destroyreq(struct cryptop *crp);
|
extern void crypto_destroyreq(struct cryptop *crp);
|
||||||
extern void crypto_initreq(struct cryptop *crp, crypto_session_t cses);
|
extern void crypto_initreq(struct cryptop *crp, crypto_session_t cses);
|
||||||
@ -660,7 +603,6 @@ extern void crypto_freereq(struct cryptop *crp);
|
|||||||
extern struct cryptop *crypto_getreq(crypto_session_t cses, int how);
|
extern struct cryptop *crypto_getreq(crypto_session_t cses, int how);
|
||||||
|
|
||||||
extern int crypto_usercrypto; /* userland may do crypto requests */
|
extern int crypto_usercrypto; /* userland may do crypto requests */
|
||||||
extern int crypto_userasymcrypto; /* userland may do asym crypto reqs */
|
|
||||||
extern int crypto_devallowsoft; /* only use hardware crypto */
|
extern int crypto_devallowsoft; /* only use hardware crypto */
|
||||||
|
|
||||||
#ifdef SYSCTL_DECL
|
#ifdef SYSCTL_DECL
|
||||||
|
@ -116,9 +116,9 @@ METHOD void freesession {
|
|||||||
} DEFAULT null_freesession;
|
} DEFAULT null_freesession;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Perform a symmetric crypto operation
|
* @brief Perform a crypto operation
|
||||||
*
|
*
|
||||||
* The crypto framework invokes this method for each symmetric crypto
|
* The crypto framework invokes this method for each crypto
|
||||||
* operation performed on a session. A reference to the containing
|
* operation performed on a session. A reference to the containing
|
||||||
* session is stored as a member of 'struct cryptop'. This routine
|
* session is stored as a member of 'struct cryptop'. This routine
|
||||||
* should not block, but queue the operation if necessary.
|
* should not block, but queue the operation if necessary.
|
||||||
@ -145,35 +145,3 @@ METHOD int process {
|
|||||||
struct cryptop *op;
|
struct cryptop *op;
|
||||||
int flags;
|
int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Perform an asymmetric crypto operation
|
|
||||||
*
|
|
||||||
* The crypto framework invokes this method for each asymmetric crypto
|
|
||||||
* operation. Each asymmetric crypto operation should be
|
|
||||||
* self-contained and is not assicated with any persistent session.
|
|
||||||
* This routine should not block, but queue the operation if
|
|
||||||
* necessary.
|
|
||||||
*
|
|
||||||
* This method may return ERESTART to indicate that any internal
|
|
||||||
* queues are full so the operation should be queued in the crypto
|
|
||||||
* framework and retried in the future.
|
|
||||||
*
|
|
||||||
* To report errors with a crypto operation, 'krp_status' should be set
|
|
||||||
* and the operation completed by calling 'crypto_kdone'. This method
|
|
||||||
* should then return zero.
|
|
||||||
*
|
|
||||||
* @param dev the crypto driver device
|
|
||||||
* @param op crypto operation to perform
|
|
||||||
* @param flags set to CRYPTO_HINT_MORE if additional asymmetric
|
|
||||||
* crypto operations are queued for this driver;
|
|
||||||
* otherwise set to zero.
|
|
||||||
*
|
|
||||||
* @retval 0 success
|
|
||||||
* @retval ERESTART internal queue is full
|
|
||||||
*/
|
|
||||||
METHOD int kprocess {
|
|
||||||
device_t dev;
|
|
||||||
struct cryptkop *op;
|
|
||||||
int flags;
|
|
||||||
};
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
# SUCH DAMAGE.
|
# SUCH DAMAGE.
|
||||||
#
|
#
|
||||||
|
|
||||||
PROGS= cryptocheck cryptotest cryptokeytest cryptostats \
|
PROGS= cryptocheck cryptotest cryptostats \
|
||||||
hifnstats ipsecstats safestats
|
hifnstats ipsecstats safestats
|
||||||
MAN=
|
MAN=
|
||||||
BINDIR?= /usr/local/bin
|
BINDIR?= /usr/local/bin
|
||||||
@ -34,9 +34,6 @@ BINDIR?= /usr/local/bin
|
|||||||
# cryptocheck: test symmetric crypto functions
|
# cryptocheck: test symmetric crypto functions
|
||||||
LIBADD.cryptocheck+= crypto util
|
LIBADD.cryptocheck+= crypto util
|
||||||
|
|
||||||
# cryptokeytest: test asymmetric crypto functions
|
|
||||||
LIBADD.cryptokeytest+= crypto
|
|
||||||
|
|
||||||
# cryptostats: dump statistics kept by the core crypto code
|
# cryptostats: dump statistics kept by the core crypto code
|
||||||
# hifnstats: print statistics kept by the HIFN driver
|
# hifnstats: print statistics kept by the HIFN driver
|
||||||
# safestats: statistics kept by the SafeNet driver
|
# safestats: statistics kept by the SafeNet driver
|
||||||
|
@ -1,270 +0,0 @@
|
|||||||
/* $FreeBSD$ */
|
|
||||||
/*
|
|
||||||
* The big num stuff is a bit broken at the moment and I've not yet fixed it.
|
|
||||||
* The symtom is that odd size big nums will fail. Test code below (it only
|
|
||||||
* uses modexp currently).
|
|
||||||
*
|
|
||||||
* --Jason L. Wright
|
|
||||||
*/
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/endian.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <crypto/cryptodev.h>
|
|
||||||
|
|
||||||
#include <err.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <paths.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <openssl/bn.h>
|
|
||||||
#include <openssl/err.h>
|
|
||||||
|
|
||||||
int crid = CRYPTO_FLAG_HARDWARE;
|
|
||||||
int verbose = 0;
|
|
||||||
|
|
||||||
static int
|
|
||||||
devcrypto(void)
|
|
||||||
{
|
|
||||||
static int fd = -1;
|
|
||||||
|
|
||||||
if (fd < 0) {
|
|
||||||
fd = open(_PATH_DEV "crypto", O_RDWR, 0);
|
|
||||||
if (fd < 0)
|
|
||||||
err(1, _PATH_DEV "crypto");
|
|
||||||
if (fcntl(fd, F_SETFD, 1) == -1)
|
|
||||||
err(1, "fcntl(F_SETFD) (devcrypto)");
|
|
||||||
}
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
crlookup(const char *devname)
|
|
||||||
{
|
|
||||||
struct crypt_find_op find;
|
|
||||||
|
|
||||||
find.crid = -1;
|
|
||||||
strlcpy(find.name, devname, sizeof(find.name));
|
|
||||||
if (ioctl(devcrypto(), CIOCFINDDEV, &find) == -1)
|
|
||||||
err(1, "ioctl(CIOCFINDDEV)");
|
|
||||||
return find.crid;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *
|
|
||||||
crfind(int crid)
|
|
||||||
{
|
|
||||||
static struct crypt_find_op find;
|
|
||||||
|
|
||||||
bzero(&find, sizeof(find));
|
|
||||||
find.crid = crid;
|
|
||||||
if (ioctl(devcrypto(), CIOCFINDDEV, &find) == -1)
|
|
||||||
err(1, "ioctl(CIOCFINDDEV)");
|
|
||||||
return find.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convert a little endian byte string in 'p' that is 'plen' bytes long to a
|
|
||||||
* BIGNUM. A new BIGNUM is allocated. Returns NULL on failure.
|
|
||||||
*/
|
|
||||||
static BIGNUM *
|
|
||||||
le_to_bignum(BIGNUM *res, const void *p, int plen)
|
|
||||||
{
|
|
||||||
|
|
||||||
res = BN_lebin2bn(p, plen, res);
|
|
||||||
if (res == NULL)
|
|
||||||
ERR_print_errors_fp(stderr);
|
|
||||||
|
|
||||||
return (res);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convert a BIGNUM to a little endian byte string. Space for BN_num_bytes(n)
|
|
||||||
* is allocated.
|
|
||||||
* Returns NULL on failure.
|
|
||||||
*/
|
|
||||||
static void *
|
|
||||||
bignum_to_le(const BIGNUM *n)
|
|
||||||
{
|
|
||||||
int blen, error;
|
|
||||||
void *rd;
|
|
||||||
|
|
||||||
blen = BN_num_bytes(n);
|
|
||||||
if (blen == 0)
|
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
rd = malloc(blen);
|
|
||||||
if (rd == NULL)
|
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
error = BN_bn2lebinpad(n, rd, blen);
|
|
||||||
if (error < 0) {
|
|
||||||
ERR_print_errors_fp(stderr);
|
|
||||||
free(rd);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (rd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
UB_mod_exp(BIGNUM *res, const BIGNUM *a, const BIGNUM *b, const BIGNUM *c)
|
|
||||||
{
|
|
||||||
struct crypt_kop kop;
|
|
||||||
void *ale, *ble, *cle;
|
|
||||||
int crypto_fd = devcrypto();
|
|
||||||
|
|
||||||
if ((ale = bignum_to_le(a)) == NULL)
|
|
||||||
err(1, "bignum_to_le, a");
|
|
||||||
if ((ble = bignum_to_le(b)) == NULL)
|
|
||||||
err(1, "bignum_to_le, b");
|
|
||||||
if ((cle = bignum_to_le(c)) == NULL)
|
|
||||||
err(1, "bignum_to_le, c");
|
|
||||||
|
|
||||||
bzero(&kop, sizeof(kop));
|
|
||||||
kop.crk_op = CRK_MOD_EXP;
|
|
||||||
kop.crk_iparams = 3;
|
|
||||||
kop.crk_oparams = 1;
|
|
||||||
kop.crk_crid = crid;
|
|
||||||
kop.crk_param[0].crp_p = ale;
|
|
||||||
kop.crk_param[0].crp_nbits = BN_num_bytes(a) * 8;
|
|
||||||
kop.crk_param[1].crp_p = ble;
|
|
||||||
kop.crk_param[1].crp_nbits = BN_num_bytes(b) * 8;
|
|
||||||
kop.crk_param[2].crp_p = cle;
|
|
||||||
kop.crk_param[2].crp_nbits = BN_num_bytes(c) * 8;
|
|
||||||
kop.crk_param[3].crp_p = cle;
|
|
||||||
kop.crk_param[3].crp_nbits = BN_num_bytes(c) * 8;
|
|
||||||
|
|
||||||
if (ioctl(crypto_fd, CIOCKEY2, &kop) == -1)
|
|
||||||
err(1, "CIOCKEY2");
|
|
||||||
if (verbose)
|
|
||||||
printf("device = %s\n", crfind(kop.crk_crid));
|
|
||||||
|
|
||||||
explicit_bzero(ale, BN_num_bytes(a));
|
|
||||||
free(ale);
|
|
||||||
explicit_bzero(ble, BN_num_bytes(b));
|
|
||||||
free(ble);
|
|
||||||
|
|
||||||
if (kop.crk_status != 0) {
|
|
||||||
printf("error %d\n", kop.crk_status);
|
|
||||||
explicit_bzero(cle, BN_num_bytes(c));
|
|
||||||
free(cle);
|
|
||||||
return (-1);
|
|
||||||
} else {
|
|
||||||
res = le_to_bignum(res, cle, BN_num_bytes(c));
|
|
||||||
explicit_bzero(cle, BN_num_bytes(c));
|
|
||||||
free(cle);
|
|
||||||
if (res == NULL)
|
|
||||||
err(1, "le_to_bignum");
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
show_result(const BIGNUM *a, const BIGNUM *b, const BIGNUM *c,
|
|
||||||
const BIGNUM *sw, const BIGNUM *hw)
|
|
||||||
{
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
printf("A = ");
|
|
||||||
BN_print_fp(stdout, a);
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
printf("B = ");
|
|
||||||
BN_print_fp(stdout, b);
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
printf("C = ");
|
|
||||||
BN_print_fp(stdout, c);
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
printf("sw= ");
|
|
||||||
BN_print_fp(stdout, sw);
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
printf("hw= ");
|
|
||||||
BN_print_fp(stdout, hw);
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
testit(void)
|
|
||||||
{
|
|
||||||
BIGNUM *a, *b, *c, *r1, *r2;
|
|
||||||
BN_CTX *ctx;
|
|
||||||
|
|
||||||
ctx = BN_CTX_new();
|
|
||||||
|
|
||||||
a = BN_new();
|
|
||||||
b = BN_new();
|
|
||||||
c = BN_new();
|
|
||||||
r1 = BN_new();
|
|
||||||
r2 = BN_new();
|
|
||||||
|
|
||||||
BN_pseudo_rand(a, 1023, 0, 0);
|
|
||||||
BN_pseudo_rand(b, 1023, 0, 0);
|
|
||||||
BN_pseudo_rand(c, 1024, 0, 0);
|
|
||||||
|
|
||||||
if (BN_cmp(a, c) > 0) {
|
|
||||||
BIGNUM *rem = BN_new();
|
|
||||||
|
|
||||||
BN_mod(rem, a, c, ctx);
|
|
||||||
UB_mod_exp(r2, rem, b, c);
|
|
||||||
BN_free(rem);
|
|
||||||
} else {
|
|
||||||
UB_mod_exp(r2, a, b, c);
|
|
||||||
}
|
|
||||||
BN_mod_exp(r1, a, b, c, ctx);
|
|
||||||
|
|
||||||
if (BN_cmp(r1, r2) != 0) {
|
|
||||||
show_result(a, b, c, r1, r2);
|
|
||||||
}
|
|
||||||
|
|
||||||
BN_free(r2);
|
|
||||||
BN_free(r1);
|
|
||||||
BN_free(c);
|
|
||||||
BN_free(b);
|
|
||||||
BN_free(a);
|
|
||||||
BN_CTX_free(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
usage(const char* cmd)
|
|
||||||
{
|
|
||||||
printf("usage: %s [-d dev] [-v] [count]\n", cmd);
|
|
||||||
printf("count is the number of bignum ops to do\n");
|
|
||||||
printf("\n");
|
|
||||||
printf("-d use specific device\n");
|
|
||||||
printf("-v be verbose\n");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int c, i;
|
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "d:v")) != -1) {
|
|
||||||
switch (c) {
|
|
||||||
case 'd':
|
|
||||||
crid = crlookup(optarg);
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
verbose = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
usage(argv[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
argc -= optind, argv += optind;
|
|
||||||
|
|
||||||
for (i = 0; i < 1000; i++) {
|
|
||||||
fprintf(stderr, "test %d\n", i);
|
|
||||||
testit();
|
|
||||||
}
|
|
||||||
return (0);
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user