svn commit: r366901 - in head: share/man/man4 sys/amd64/conf sys/conf sys/crypto/openssl sys/i386/conf sys/modules sys/modules/ossl
John Baldwin
jhb at FreeBSD.org
Tue Oct 20 17:50:21 UTC 2020
Author: jhb
Date: Tue Oct 20 17:50:18 2020
New Revision: 366901
URL: https://svnweb.freebsd.org/changeset/base/366901
Log:
Add a kernel crypto driver using assembly routines from OpenSSL.
Currently, this supports SHA1 and SHA2-{224,256,384,512} both as plain
hashes and in HMAC mode on both amd64 and i386. It uses the SHA
intrinsics when present similar to aesni(4), but uses SSE/AVX
instructions when they are not.
Note that some files from OpenSSL that normally wrap the assembly
routines have been adapted to export methods usable by 'struct
auth_xform' as is used by existing software crypto routines.
Reviewed by: gallatin, jkim, delphij, gnn
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D26821
Added:
head/share/man/man4/ossl.4 (contents, props changed)
head/sys/crypto/openssl/ossl.c (contents, props changed)
head/sys/crypto/openssl/ossl.h (contents, props changed)
head/sys/crypto/openssl/ossl_hash.h (contents, props changed)
- copied, changed from r366898, head/crypto/openssl/include/crypto/md32_common.h
head/sys/crypto/openssl/ossl_sha.h
- copied, changed from r366898, head/crypto/openssl/include/openssl/sha.h
head/sys/crypto/openssl/ossl_sha1.c (contents, props changed)
- copied, changed from r366898, head/crypto/openssl/crypto/sha/sha_local.h
head/sys/crypto/openssl/ossl_sha256.c (contents, props changed)
- copied, changed from r366898, head/crypto/openssl/crypto/sha/sha256.c
head/sys/crypto/openssl/ossl_sha512.c (contents, props changed)
- copied, changed from r366898, head/crypto/openssl/crypto/sha/sha512.c
head/sys/modules/ossl/
head/sys/modules/ossl/Makefile (contents, props changed)
Modified:
head/share/man/man4/Makefile
head/sys/amd64/conf/NOTES
head/sys/conf/files.amd64
head/sys/conf/files.i386
head/sys/conf/files.x86
head/sys/i386/conf/NOTES
head/sys/modules/Makefile
Modified: head/share/man/man4/Makefile
==============================================================================
--- head/share/man/man4/Makefile Tue Oct 20 17:24:29 2020 (r366900)
+++ head/share/man/man4/Makefile Tue Oct 20 17:50:18 2020 (r366901)
@@ -398,6 +398,7 @@ MAN= aac.4 \
ocs_fc.4\
ohci.4 \
orm.4 \
+ ${_ossl.4} \
ow.4 \
ow_temp.4 \
owc.4 \
@@ -819,6 +820,7 @@ _ntb_transport.4=ntb_transport.4
_nvd.4= nvd.4
_nvme.4= nvme.4
_nvram.4= nvram.4
+_ossl.4= ossl.4
_padlock.4= padlock.4
_pchtherm.4= pchtherm.4
_rr232x.4= rr232x.4
Added: head/share/man/man4/ossl.4
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/share/man/man4/ossl.4 Tue Oct 20 17:50:18 2020 (r366901)
@@ -0,0 +1,105 @@
+.\" Copyright (c) 2020 Netflix, 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,
+.\" without modification.
+.\" 2. Redistributions in binary form must reproduce at minimum a disclaimer
+.\" similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+.\" redistribution must be conditioned upon including a substantially
+.\" similar Disclaimer requirement for further binary redistribution.
+.\"
+.\" NO WARRANTY
+.\" 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 NONINFRINGEMENT, MERCHANTIBILITY
+.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+.\" THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd October 19, 2020
+.Dt OSSL 4
+.Os
+.Sh NAME
+.Nm ossl
+.Nd "driver using OpenSSL assembly routines on x86 CPUs"
+.Sh SYNOPSIS
+To compile this driver into the kernel,
+place the following lines in your
+kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device crypto"
+.Cd "device cryptodev"
+.Cd "device ossl"
+.Ed
+.Pp
+Alternatively, to load the driver as a
+module at boot time, place the following line in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+ossl_load="YES"
+.Ed
+.Sh DESCRIPTION
+The OpenSSL distribution includes architecture-specific
+implementations for some commonly used cryptographic algorithms.
+This driver adds a wrapper around these routines permitting them to be
+used by in-kernel cryptography consumers such as kernel TLS and IPsec.
+.Pp
+The
+.Nm
+driver includes architecture-specific implementations for the following
+architectures:
+.Pp
+.Bl -bullet -compact
+.It
+amd64
+.It
+i386
+.El
+.Pp
+The
+.Nm
+driver includes support for the following algorithms:
+.Pp
+.Bl -bullet -compact
+.It
+SHA1
+.It
+SHA1-HMAC
+.It
+SHA2-224
+.It
+SHA2-224-HMAC
+.It
+SHA2-256
+.It
+SHA2-256-HMAC
+.It
+SHA2-384
+.It
+SHA2-384-HMAC
+.It
+SHA2-512
+.It
+SHA2-512-HMAC
+.El
+.Sh SEE ALSO
+.Xr crypto 4 ,
+.Xr intro 4 ,
+.Xr ipsec 4 ,
+.Xr crypto 7 ,
+.Xr crypto 9
+.Sh HISTORY
+The
+.Nm
+driver first appeared in
+.Fx 13.0 .
Modified: head/sys/amd64/conf/NOTES
==============================================================================
--- head/sys/amd64/conf/NOTES Tue Oct 20 17:24:29 2020 (r366900)
+++ head/sys/amd64/conf/NOTES Tue Oct 20 17:50:18 2020 (r366901)
@@ -533,6 +533,7 @@ device tpm
device padlock_rng # VIA Padlock RNG
device rdrand_rng # Intel Bull Mountain RNG
device aesni # AES-NI OpenCrypto module
+device ossl # OpenSSL OpenCrypto module
device ioat # Intel I/OAT DMA engine
#
Modified: head/sys/conf/files.amd64
==============================================================================
--- head/sys/conf/files.amd64 Tue Oct 20 17:24:29 2020 (r366900)
+++ head/sys/conf/files.amd64 Tue Oct 20 17:50:18 2020 (r366901)
@@ -137,6 +137,9 @@ cddl/dev/dtrace/amd64/dtrace_asm.S optional dtrace c
cddl/dev/dtrace/amd64/dtrace_subr.c optional dtrace compile-with "${DTRACE_C}"
crypto/aesni/aeskeys_amd64.S optional aesni
crypto/des/des_enc.c optional netsmb
+crypto/openssl/amd64/sha1-x86_64.S optional ossl
+crypto/openssl/amd64/sha256-x86_64.S optional ossl
+crypto/openssl/amd64/sha512-x86_64.S optional ossl
dev/acpi_support/acpi_wmi_if.m standard
dev/agp/agp_amd64.c optional agp
dev/agp/agp_i810.c optional agp
Modified: head/sys/conf/files.i386
==============================================================================
--- head/sys/conf/files.i386 Tue Oct 20 17:24:29 2020 (r366900)
+++ head/sys/conf/files.i386 Tue Oct 20 17:50:18 2020 (r366901)
@@ -77,6 +77,9 @@ compat/linux/linux.c optional compat_linux
compat/ndis/winx32_wrap.S optional ndisapi pci
crypto/aesni/aeskeys_i386.S optional aesni
crypto/des/arch/i386/des_enc.S optional netsmb
+crypto/openssl/i386/sha1-586.S optional ossl
+crypto/openssl/i386/sha256-586.S optional ossl
+crypto/openssl/i386/sha512-586.S optional ossl
dev/agp/agp_ali.c optional agp
dev/agp/agp_amd.c optional agp
dev/agp/agp_amd64.c optional agp
Modified: head/sys/conf/files.x86
==============================================================================
--- head/sys/conf/files.x86 Tue Oct 20 17:24:29 2020 (r366900)
+++ head/sys/conf/files.x86 Tue Oct 20 17:50:18 2020 (r366901)
@@ -53,6 +53,10 @@ intel_sha256.o optional aesni \
compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc} ${WERROR} ${PROF} -mmmx -msse -msse4 -msha ${.IMPSRC}" \
no-implicit-rule \
clean "intel_sha256.o"
+crypto/openssl/ossl.c optional ossl
+crypto/openssl/ossl_sha1.c optional ossl
+crypto/openssl/ossl_sha256.c optional ossl
+crypto/openssl/ossl_sha512.c optional ossl
crypto/via/padlock.c optional padlock
crypto/via/padlock_cipher.c optional padlock
crypto/via/padlock_hash.c optional padlock
Added: head/sys/crypto/openssl/ossl.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/sys/crypto/openssl/ossl.c Tue Oct 20 17:50:18 2020 (r366901)
@@ -0,0 +1,369 @@
+/*
+ * Copyright (c) 2020 Netflix, 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,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * 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 NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ */
+
+/*
+ * A driver for the OpenCrypto framework which uses assembly routines
+ * from OpenSSL.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <machine/fpu.h>
+#include <machine/md_var.h>
+#include <x86/cputypes.h>
+#include <x86/specialreg.h>
+
+#include <opencrypto/cryptodev.h>
+#include <opencrypto/xform_auth.h>
+
+#include <crypto/openssl/ossl.h>
+
+#include "cryptodev_if.h"
+
+struct ossl_softc {
+ int32_t sc_cid;
+};
+
+struct ossl_session_hash {
+ struct ossl_hash_context ictx;
+ struct ossl_hash_context octx;
+ struct auth_hash *axf;
+ u_int mlen;
+};
+
+struct ossl_session {
+ struct ossl_session_hash hash;
+};
+
+/*
+ * See OPENSSL_ia32cap(3).
+ *
+ * [0] = cpu_feature but with a few custom bits
+ * [1] = cpu_feature2 but with AMD XOP in bit 11
+ * [2] = cpu_stdext_feature
+ * [3] = 0
+ */
+unsigned int OPENSSL_ia32cap_P[4];
+
+static MALLOC_DEFINE(M_OSSL, "ossl", "OpenSSL crypto");
+
+static void
+ossl_cpuid(void)
+{
+ uint64_t xcr0;
+ u_int regs[4];
+ u_int max_cores;
+
+ /* Derived from OpenSSL_ia32_cpuid. */
+
+ OPENSSL_ia32cap_P[0] = cpu_feature & ~(CPUID_B20 | CPUID_IA64);
+ if (cpu_vendor_id == CPU_VENDOR_INTEL) {
+ OPENSSL_ia32cap_P[0] |= CPUID_IA64;
+ if ((cpu_id & 0xf00) != 0xf00)
+ OPENSSL_ia32cap_P[0] |= CPUID_B20;
+ }
+
+ /* Only leave CPUID_HTT on if HTT is present. */
+ if (cpu_vendor_id == CPU_VENDOR_AMD && cpu_exthigh >= 0x80000008) {
+ max_cores = (cpu_procinfo2 & AMDID_CMP_CORES) + 1;
+ if (cpu_feature & CPUID_HTT) {
+ if ((cpu_procinfo & CPUID_HTT_CORES) >> 16 <= max_cores)
+ OPENSSL_ia32cap_P[0] &= ~CPUID_HTT;
+ }
+ } else {
+ if (cpu_high >= 4) {
+ cpuid_count(4, 0, regs);
+ max_cores = (regs[0] >> 26) & 0xfff;
+ } else
+ max_cores = -1;
+ }
+ if (max_cores == 0)
+ OPENSSL_ia32cap_P[0] &= ~CPUID_HTT;
+ else if ((cpu_procinfo & CPUID_HTT_CORES) >> 16 == 0)
+ OPENSSL_ia32cap_P[0] &= ~CPUID_HTT;
+
+ OPENSSL_ia32cap_P[1] = cpu_feature2 & ~AMDID2_XOP;
+ if (cpu_vendor_id == CPU_VENDOR_AMD)
+ OPENSSL_ia32cap_P[1] |= amd_feature2 & AMDID2_XOP;
+
+ OPENSSL_ia32cap_P[2] = cpu_stdext_feature;
+ if ((OPENSSL_ia32cap_P[1] & CPUID2_XSAVE) == 0)
+ OPENSSL_ia32cap_P[2] &= ~(CPUID_STDEXT_AVX512F |
+ CPUID_STDEXT_AVX512DQ);
+
+ /* Disable AVX512F on Skylake-X. */
+ if ((cpu_id & 0x0fff0ff0) == 0x00050650)
+ OPENSSL_ia32cap_P[2] &= ~(CPUID_STDEXT_AVX512F);
+
+ if (cpu_feature2 & CPUID2_OSXSAVE)
+ xcr0 = rxcr(0);
+ else
+ xcr0 = 0;
+
+ if ((xcr0 & (XFEATURE_AVX512 | XFEATURE_AVX)) !=
+ (XFEATURE_AVX512 | XFEATURE_AVX))
+ OPENSSL_ia32cap_P[2] &= ~(CPUID_STDEXT_AVX512VL |
+ CPUID_STDEXT_AVX512BW | CPUID_STDEXT_AVX512IFMA |
+ CPUID_STDEXT_AVX512F);
+ if ((xcr0 & XFEATURE_AVX) != XFEATURE_AVX) {
+ OPENSSL_ia32cap_P[1] &= ~(CPUID2_AVX | AMDID2_XOP | CPUID2_FMA);
+ OPENSSL_ia32cap_P[2] &= ~CPUID_STDEXT_AVX2;
+ }
+}
+
+static void
+ossl_identify(driver_t *driver, device_t parent)
+{
+
+ if (device_find_child(parent, "ossl", -1) == NULL)
+ BUS_ADD_CHILD(parent, 10, "ossl", -1);
+}
+
+static int
+ossl_probe(device_t dev)
+{
+
+ device_set_desc(dev, "OpenSSL crypto");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+ossl_attach(device_t dev)
+{
+ struct ossl_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ ossl_cpuid();
+ sc->sc_cid = crypto_get_driverid(dev, sizeof(struct ossl_session),
+ CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC |
+ CRYPTOCAP_F_ACCEL_SOFTWARE);
+ if (sc->sc_cid < 0) {
+ device_printf(dev, "failed to allocate crypto driver id\n");
+ return (ENXIO);
+ }
+
+ return (0);
+}
+
+static int
+ossl_detach(device_t dev)
+{
+ struct ossl_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ crypto_unregister_all(sc->sc_cid);
+
+ return (0);
+}
+
+static struct auth_hash *
+ossl_lookup_hash(const struct crypto_session_params *csp)
+{
+
+ switch (csp->csp_auth_alg) {
+ case CRYPTO_SHA1:
+ case CRYPTO_SHA1_HMAC:
+ return (&ossl_hash_sha1);
+ case CRYPTO_SHA2_224:
+ case CRYPTO_SHA2_224_HMAC:
+ return (&ossl_hash_sha224);
+ case CRYPTO_SHA2_256:
+ case CRYPTO_SHA2_256_HMAC:
+ return (&ossl_hash_sha256);
+ case CRYPTO_SHA2_384:
+ case CRYPTO_SHA2_384_HMAC:
+ return (&ossl_hash_sha384);
+ case CRYPTO_SHA2_512:
+ case CRYPTO_SHA2_512_HMAC:
+ return (&ossl_hash_sha512);
+ default:
+ return (NULL);
+ }
+}
+
+static int
+ossl_probesession(device_t dev, const struct crypto_session_params *csp)
+{
+
+ if ((csp->csp_flags & ~(CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD)) !=
+ 0)
+ return (EINVAL);
+ switch (csp->csp_mode) {
+ case CSP_MODE_DIGEST:
+ if (ossl_lookup_hash(csp) == NULL)
+ return (EINVAL);
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ return (CRYPTODEV_PROBE_ACCEL_SOFTWARE);
+}
+
+static void
+ossl_setkey_hmac(struct ossl_session *s, const void *key, int klen)
+{
+
+ hmac_init_ipad(s->hash.axf, key, klen, &s->hash.ictx);
+ hmac_init_opad(s->hash.axf, key, klen, &s->hash.octx);
+}
+
+static int
+ossl_newsession(device_t dev, crypto_session_t cses,
+ const struct crypto_session_params *csp)
+{
+ struct ossl_session *s;
+ struct auth_hash *axf;
+
+ s = crypto_get_driver_session(cses);
+
+ axf = ossl_lookup_hash(csp);
+ s->hash.axf = axf;
+ if (csp->csp_auth_mlen == 0)
+ s->hash.mlen = axf->hashsize;
+ else
+ s->hash.mlen = csp->csp_auth_mlen;
+
+ if (csp->csp_auth_klen == 0) {
+ axf->Init(&s->hash.ictx);
+ } else {
+ if (csp->csp_auth_key != NULL) {
+ fpu_kern_enter(curthread, NULL, FPU_KERN_NOCTX);
+ ossl_setkey_hmac(s, csp->csp_auth_key,
+ csp->csp_auth_klen);
+ fpu_kern_leave(curthread, NULL);
+ }
+ }
+ return (0);
+}
+
+static int
+ossl_process(device_t dev, struct cryptop *crp, int hint)
+{
+ struct ossl_hash_context ctx;
+ char digest[HASH_MAX_LEN];
+ const struct crypto_session_params *csp;
+ struct ossl_session *s;
+ struct auth_hash *axf;
+ int error;
+ bool fpu_entered;
+
+ s = crypto_get_driver_session(crp->crp_session);
+ csp = crypto_get_params(crp->crp_session);
+ axf = s->hash.axf;
+
+ if (is_fpu_kern_thread(0)) {
+ fpu_entered = false;
+ } else {
+ fpu_kern_enter(curthread, NULL, FPU_KERN_NOCTX);
+ fpu_entered = true;
+ }
+
+ if (crp->crp_auth_key != NULL)
+ ossl_setkey_hmac(s, crp->crp_auth_key, csp->csp_auth_klen);
+
+ ctx = s->hash.ictx;
+
+ if (crp->crp_aad != NULL)
+ error = axf->Update(&ctx, crp->crp_aad, crp->crp_aad_length);
+ else
+ error = crypto_apply(crp, crp->crp_aad_start,
+ crp->crp_aad_length, axf->Update, &ctx);
+ if (error)
+ goto out;
+
+ error = crypto_apply(crp, crp->crp_payload_start,
+ crp->crp_payload_length, axf->Update, &ctx);
+ if (error)
+ goto out;
+
+ axf->Final(digest, &ctx);
+
+ if (csp->csp_auth_klen != 0) {
+ ctx = s->hash.octx;
+ axf->Update(&ctx, digest, axf->hashsize);
+ axf->Final(digest, &ctx);
+ }
+
+ if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) {
+ char digest2[HASH_MAX_LEN];
+
+ crypto_copydata(crp, crp->crp_digest_start, s->hash.mlen,
+ digest2);
+ if (timingsafe_bcmp(digest, digest2, s->hash.mlen) != 0)
+ error = EBADMSG;
+ explicit_bzero(digest2, sizeof(digest2));
+ } else {
+ crypto_copyback(crp, crp->crp_digest_start, s->hash.mlen,
+ digest);
+ }
+ explicit_bzero(digest, sizeof(digest));
+
+out:
+ if (fpu_entered)
+ fpu_kern_leave(curthread, NULL);
+
+ crp->crp_etype = error;
+ crypto_done(crp);
+
+ explicit_bzero(&ctx, sizeof(ctx));
+ return (0);
+}
+
+static device_method_t ossl_methods[] = {
+ DEVMETHOD(device_identify, ossl_identify),
+ DEVMETHOD(device_probe, ossl_probe),
+ DEVMETHOD(device_attach, ossl_attach),
+ DEVMETHOD(device_detach, ossl_detach),
+
+ DEVMETHOD(cryptodev_probesession, ossl_probesession),
+ DEVMETHOD(cryptodev_newsession, ossl_newsession),
+ DEVMETHOD(cryptodev_process, ossl_process),
+
+ DEVMETHOD_END
+};
+
+static driver_t ossl_driver = {
+ "ossl",
+ ossl_methods,
+ sizeof(struct ossl_softc)
+};
+
+static devclass_t ossl_devclass;
+
+DRIVER_MODULE(ossl, nexus, ossl_driver, ossl_devclass, NULL, NULL);
+MODULE_VERSION(ossl, 1);
+MODULE_DEPEND(ossl, crypto, 1, 1, 1);
Added: head/sys/crypto/openssl/ossl.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/sys/crypto/openssl/ossl.h Tue Oct 20 17:50:18 2020 (r366901)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2020 Netflix, 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,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * 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 NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __OSSL_H__
+#define __OSSL_H__
+
+/* Compatibility shims. */
+#define OPENSSL_cleanse explicit_bzero
+
+/* Used by assembly routines to select CPU-specific variants. */
+extern unsigned int OPENSSL_ia32cap_P[4];
+
+/* Needs to be big enough to hold any hash context. */
+struct ossl_hash_context {
+ uint32_t dummy[54];
+} __aligned(32);
+
+extern struct auth_hash ossl_hash_sha1;
+extern struct auth_hash ossl_hash_sha224;
+extern struct auth_hash ossl_hash_sha256;
+extern struct auth_hash ossl_hash_sha384;
+extern struct auth_hash ossl_hash_sha512;
+
+#endif /* !__OSSL_H__ */
Copied and modified: head/sys/crypto/openssl/ossl_hash.h (from r366898, head/crypto/openssl/include/crypto/md32_common.h)
==============================================================================
--- head/crypto/openssl/include/crypto/md32_common.h Tue Oct 20 17:00:43 2020 (r366898, copy source)
+++ head/sys/crypto/openssl/ossl_hash.h Tue Oct 20 17:50:18 2020 (r366901)
@@ -5,96 +5,17 @@
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
+ *
+ * $FreeBSD$
*/
-/*-
- * This is a generic 32 bit "collector" for message digest algorithms.
- * Whenever needed it collects input character stream into chunks of
- * 32 bit values and invokes a block function that performs actual hash
- * calculations.
+/*
+ * Derived from include/crypto/md32_common.h
*
- * Porting guide.
- *
- * Obligatory macros:
- *
- * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
- * this macro defines byte order of input stream.
- * HASH_CBLOCK
- * size of a unit chunk HASH_BLOCK operates on.
- * HASH_LONG
- * has to be at least 32 bit wide.
- * HASH_CTX
- * context structure that at least contains following
- * members:
- * typedef struct {
- * ...
- * HASH_LONG Nl,Nh;
- * either {
- * HASH_LONG data[HASH_LBLOCK];
- * unsigned char data[HASH_CBLOCK];
- * };
- * unsigned int num;
- * ...
- * } HASH_CTX;
- * data[] vector is expected to be zeroed upon first call to
- * HASH_UPDATE.
- * HASH_UPDATE
- * name of "Update" function, implemented here.
- * HASH_TRANSFORM
- * name of "Transform" function, implemented here.
- * HASH_FINAL
- * name of "Final" function, implemented here.
- * HASH_BLOCK_DATA_ORDER
- * name of "block" function capable of treating *unaligned* input
- * message in original (data) byte order, implemented externally.
- * HASH_MAKE_STRING
- * macro converting context variables to an ASCII hash string.
- *
- * MD5 example:
- *
- * #define DATA_ORDER_IS_LITTLE_ENDIAN
- *
- * #define HASH_LONG MD5_LONG
- * #define HASH_CTX MD5_CTX
- * #define HASH_CBLOCK MD5_CBLOCK
- * #define HASH_UPDATE MD5_Update
- * #define HASH_TRANSFORM MD5_Transform
- * #define HASH_FINAL MD5_Final
- * #define HASH_BLOCK_DATA_ORDER md5_block_data_order
+ * HASH_UPDATE and HASH_FINAL have been updated to work with the
+ * auth_hash interface.
*/
-#include <openssl/crypto.h>
-
-#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
-# error "DATA_ORDER must be defined!"
-#endif
-
-#ifndef HASH_CBLOCK
-# error "HASH_CBLOCK must be defined!"
-#endif
-#ifndef HASH_LONG
-# error "HASH_LONG must be defined!"
-#endif
-#ifndef HASH_CTX
-# error "HASH_CTX must be defined!"
-#endif
-
-#ifndef HASH_UPDATE
-# error "HASH_UPDATE must be defined!"
-#endif
-#ifndef HASH_TRANSFORM
-# error "HASH_TRANSFORM must be defined!"
-#endif
-#ifndef HASH_FINAL
-# error "HASH_FINAL must be defined!"
-#endif
-
-#ifndef HASH_BLOCK_DATA_ORDER
-# error "HASH_BLOCK_DATA_ORDER must be defined!"
-#endif
-
-#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
-
#if defined(DATA_ORDER_IS_BIG_ENDIAN)
# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \
@@ -125,15 +46,17 @@
* Time for some action :-)
*/
-int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len)
+static int
+HASH_UPDATE(void *c_, const void *data_, unsigned int len)
{
+ HASH_CTX *c = c_;
const unsigned char *data = data_;
unsigned char *p;
HASH_LONG l;
size_t n;
if (len == 0)
- return 1;
+ return 0;
l = (c->Nl + (((HASH_LONG) len) << 3)) & 0xffffffffUL;
if (l < c->Nl) /* overflow */
@@ -163,7 +86,7 @@ int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t
} else {
memcpy(p + n, data, len);
c->num += (unsigned int)len;
- return 1;
+ return 0;
}
}
@@ -180,16 +103,13 @@ int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t
c->num = (unsigned int)len;
memcpy(p, data, len);
}
- return 1;
+ return 0;
}
-void HASH_TRANSFORM(HASH_CTX *c, const unsigned char *data)
+static void
+HASH_FINAL(uint8_t *md, void *c_)
{
- HASH_BLOCK_DATA_ORDER(c, data, 1);
-}
-
-int HASH_FINAL(unsigned char *md, HASH_CTX *c)
-{
+ HASH_CTX *c = c_;
unsigned char *p = (unsigned char *)c->data;
size_t n = c->num;
@@ -222,35 +142,5 @@ int HASH_FINAL(unsigned char *md, HASH_CTX *c)
HASH_MAKE_STRING(c, md);
#endif
- return 1;
+ return;
}
-
-#ifndef MD32_REG_T
-# if defined(__alpha) || defined(__sparcv9) || defined(__mips)
-# define MD32_REG_T long
-/*
- * This comment was originally written for MD5, which is why it
- * discusses A-D. But it basically applies to all 32-bit digests,
- * which is why it was moved to common header file.
- *
- * In case you wonder why A-D are declared as long and not
- * as MD5_LONG. Doing so results in slight performance
- * boost on LP64 architectures. The catch is we don't
- * really care if 32 MSBs of a 64-bit register get polluted
- * with eventual overflows as we *save* only 32 LSBs in
- * *either* case. Now declaring 'em long excuses the compiler
- * from keeping 32 MSBs zeroed resulting in 13% performance
- * improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
- * Well, to be honest it should say that this *prevents*
- * performance degradation.
- */
-# else
-/*
- * Above is not absolute and there are LP64 compilers that
- * generate better code if MD32_REG_T is defined int. The above
- * pre-processor condition reflects the circumstances under which
- * the conclusion was made and is subject to further extension.
- */
-# define MD32_REG_T int
-# endif
-#endif
Copied and modified: head/sys/crypto/openssl/ossl_sha.h (from r366898, head/crypto/openssl/include/openssl/sha.h)
==============================================================================
--- head/crypto/openssl/include/openssl/sha.h Tue Oct 20 17:00:43 2020 (r366898, copy source)
+++ head/sys/crypto/openssl/ossl_sha.h Tue Oct 20 17:50:18 2020 (r366901)
@@ -5,31 +5,27 @@
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
+ *
+ * $FreeBSD$
*/
-#ifndef HEADER_SHA_H
-# define HEADER_SHA_H
+#ifndef __OSSL_SHA_H__
+#define __OSSL_SHA_H__
-# include <openssl/e_os2.h>
-# include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*-
- * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- * ! SHA_LONG has to be at least 32 bits wide. !
- * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+/*
+ * This is always included last which permits the namespace hacks below
+ * to work.
*/
+#define SHA256_CTX OSSL_SHA256_CTX
+#define SHA512_CTX OSSL_SHA512_CTX
+
+/* From include/openssl/sha.h */
# define SHA_LONG unsigned int
# define SHA_LBLOCK 16
# define SHA_CBLOCK (SHA_LBLOCK*4)/* SHA treats input data as a
* contiguous array of 32 bit wide
* big-endian values. */
-# define SHA_LAST_BLOCK (SHA_CBLOCK-8)
-# define SHA_DIGEST_LENGTH 20
typedef struct SHAstate_st {
SHA_LONG h0, h1, h2, h3, h4;
@@ -38,12 +34,6 @@ typedef struct SHAstate_st {
unsigned int num;
} SHA_CTX;
-int SHA1_Init(SHA_CTX *c);
-int SHA1_Update(SHA_CTX *c, const void *data, size_t len);
-int SHA1_Final(unsigned char *md, SHA_CTX *c);
-unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md);
-void SHA1_Transform(SHA_CTX *c, const unsigned char *data);
-
# define SHA256_CBLOCK (SHA_LBLOCK*4)/* SHA-256 treats input data as a
* contiguous array of 32 bit wide
* big-endian values. */
@@ -55,42 +45,15 @@ typedef struct SHA256state_st {
unsigned int num, md_len;
} SHA256_CTX;
-int SHA224_Init(SHA256_CTX *c);
-int SHA224_Update(SHA256_CTX *c, const void *data, size_t len);
-int SHA224_Final(unsigned char *md, SHA256_CTX *c);
-unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md);
-int SHA256_Init(SHA256_CTX *c);
-int SHA256_Update(SHA256_CTX *c, const void *data, size_t len);
-int SHA256_Final(unsigned char *md, SHA256_CTX *c);
-unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md);
-void SHA256_Transform(SHA256_CTX *c, const unsigned char *data);
-
-# define SHA224_DIGEST_LENGTH 28
-# define SHA256_DIGEST_LENGTH 32
-# define SHA384_DIGEST_LENGTH 48
-# define SHA512_DIGEST_LENGTH 64
-
/*
- * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64
- * being exactly 64-bit wide. See Implementation Notes in sha512.c
- * for further details.
- */
-/*
* SHA-512 treats input data as a
* contiguous array of 64 bit
* wide big-endian values.
*/
# define SHA512_CBLOCK (SHA_LBLOCK*8)
-# if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
-# define SHA_LONG64 unsigned __int64
-# define U64(C) C##UI64
-# elif defined(__arch64__)
-# define SHA_LONG64 unsigned long
-# define U64(C) C##UL
-# else
+
# define SHA_LONG64 unsigned long long
# define U64(C) C##ULL
-# endif
typedef struct SHA512state_st {
SHA_LONG64 h[8];
@@ -102,18 +65,4 @@ typedef struct SHA512state_st {
unsigned int num, md_len;
} SHA512_CTX;
-int SHA384_Init(SHA512_CTX *c);
-int SHA384_Update(SHA512_CTX *c, const void *data, size_t len);
-int SHA384_Final(unsigned char *md, SHA512_CTX *c);
-unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md);
-int SHA512_Init(SHA512_CTX *c);
-int SHA512_Update(SHA512_CTX *c, const void *data, size_t len);
-int SHA512_Final(unsigned char *md, SHA512_CTX *c);
-unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md);
-void SHA512_Transform(SHA512_CTX *c, const unsigned char *data);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+#endif /* !__OSSL_SHA_H__ */
Copied and modified: head/sys/crypto/openssl/ossl_sha1.c (from r366898, head/crypto/openssl/crypto/sha/sha_local.h)
==============================================================================
--- head/crypto/openssl/crypto/sha/sha_local.h Tue Oct 20 17:00:43 2020 (r366898, copy source)
+++ head/sys/crypto/openssl/ossl_sha1.c Tue Oct 20 17:50:18 2020 (r366901)
@@ -7,12 +7,22 @@
* https://www.openssl.org/source/license.html
*/
-#include <stdlib.h>
-#include <string.h>
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
-#include <openssl/opensslconf.h>
-#include <openssl/sha.h>
+#include <sys/libkern.h>
+#include <sys/malloc.h>
+#include <opencrypto/cryptodev.h>
+#include <opencrypto/xform_auth.h>
+
+#include <crypto/openssl/ossl.h>
+#include <crypto/openssl/ossl_sha.h>
+
+/* sha1-x86_64.S */
+void sha1_block_data_order(SHA_CTX *c, const void *p, size_t len);
+
+/* From crypto/sha/sha_local.h */
#define DATA_ORDER_IS_BIG_ENDIAN
#define HASH_LONG SHA_LONG
@@ -27,398 +37,41 @@
ll=(c)->h4; (void)HOST_l2c(ll,(s)); \
} while (0)
-#define HASH_UPDATE SHA1_Update
-#define HASH_TRANSFORM SHA1_Transform
-#define HASH_FINAL SHA1_Final
-#define HASH_INIT SHA1_Init
+#define HASH_UPDATE ossl_sha1_update
+#define HASH_FINAL ossl_sha1_final
+#define HASH_INIT ossl_sha1_init
#define HASH_BLOCK_DATA_ORDER sha1_block_data_order
-#define Xupdate(a,ix,ia,ib,ic,id) ( (a)=(ia^ib^ic^id), \
- ix=(a)=ROTATE((a),1) \
- )
-#ifndef SHA1_ASM
-static void sha1_block_data_order(SHA_CTX *c, const void *p, size_t num);
-#else
-void sha1_block_data_order(SHA_CTX *c, const void *p, size_t num);
-#endif
-
-#include "crypto/md32_common.h"
-
#define INIT_DATA_h0 0x67452301UL
#define INIT_DATA_h1 0xefcdab89UL
#define INIT_DATA_h2 0x98badcfeUL
#define INIT_DATA_h3 0x10325476UL
#define INIT_DATA_h4 0xc3d2e1f0UL
-int HASH_INIT(SHA_CTX *c)
+static void
+HASH_INIT(void *c_)
{
+ SHA_CTX *c = c_;
memset(c, 0, sizeof(*c));
c->h0 = INIT_DATA_h0;
c->h1 = INIT_DATA_h1;
c->h2 = INIT_DATA_h2;
c->h3 = INIT_DATA_h3;
c->h4 = INIT_DATA_h4;
- return 1;
}
-#define K_00_19 0x5a827999UL
-#define K_20_39 0x6ed9eba1UL
-#define K_40_59 0x8f1bbcdcUL
-#define K_60_79 0xca62c1d6UL
+#include "ossl_hash.h"
-/*
- * As pointed out by Wei Dai, F() below can be simplified to the code in
- * F_00_19. Wei attributes these optimizations to Peter Gutmann's SHS code,
- * and he attributes it to Rich Schroeppel.
- * #define F(x,y,z) (((x) & (y)) | ((~(x)) & (z)))
- * I've just become aware of another tweak to be made, again from Wei Dai,
- * in F_40_59, (x&a)|(y&a) -> (x|y)&a
- */
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list