Page MenuHomeFreeBSD

D28756.diff
No OneTemporary

D28756.diff

diff --git a/share/man/man4/ossl.4 b/share/man/man4/ossl.4
--- a/share/man/man4/ossl.4
+++ b/share/man/man4/ossl.4
@@ -74,6 +74,8 @@
.Pp
.Bl -bullet -compact
.It
+ChaCha20
+.It
Poly1305
.It
SHA1
diff --git a/sys/conf/files b/sys/conf/files
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -739,6 +739,7 @@
crypto/des/des_ecb.c optional netsmb
crypto/des/des_setkey.c optional netsmb
crypto/openssl/ossl.c optional ossl
+crypto/openssl/ossl_chacha20.c optional ossl
crypto/openssl/ossl_poly1305.c optional ossl
crypto/openssl/ossl_sha1.c optional ossl
crypto/openssl/ossl_sha256.c optional ossl
diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
--- a/sys/conf/files.amd64
+++ b/sys/conf/files.amd64
@@ -137,6 +137,7 @@
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/chacha-x86_64.S optional ossl
crypto/openssl/amd64/poly1305-x86_64.S optional ossl
crypto/openssl/amd64/sha1-x86_64.S optional ossl
crypto/openssl/amd64/sha256-x86_64.S optional ossl
diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64
--- a/sys/conf/files.arm64
+++ b/sys/conf/files.arm64
@@ -125,6 +125,8 @@
crypto/des/des_enc.c optional netsmb
crypto/openssl/ossl_aarch64.c optional ossl
+crypto/openssl/aarch64/chacha-armv8.S optional ossl \
+ compile-with "${CC} -c ${CFLAGS:N-mgeneral-regs-only} ${WERROR} ${PROF} ${.IMPSRC}"
crypto/openssl/aarch64/poly1305-armv8.S optional ossl \
compile-with "${CC} -c ${CFLAGS:N-mgeneral-regs-only} ${WERROR} ${PROF} ${.IMPSRC}"
crypto/openssl/aarch64/sha1-armv8.S optional ossl \
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -77,6 +77,7 @@
compat/linux/linux.c optional compat_linux
crypto/aesni/aeskeys_i386.S optional aesni
crypto/des/arch/i386/des_enc.S optional netsmb
+crypto/openssl/i386/chacha-x86.S optional ossl
crypto/openssl/i386/poly1305-x86.S optional ossl
crypto/openssl/i386/sha1-586.S optional ossl
crypto/openssl/i386/sha256-586.S optional ossl
diff --git a/sys/crypto/openssl/ossl.h b/sys/crypto/openssl/ossl.h
--- a/sys/crypto/openssl/ossl.h
+++ b/sys/crypto/openssl/ossl.h
@@ -34,6 +34,11 @@
/* Compatibility shims. */
#define OPENSSL_cleanse explicit_bzero
+struct cryptop;
+struct crypto_session_params;
+
+int ossl_chacha20(struct cryptop *crp,
+ const struct crypto_session_params *csp);
void ossl_cpuid(void);
/* Needs to be big enough to hold any hash context. */
diff --git a/sys/crypto/openssl/ossl.c b/sys/crypto/openssl/ossl.c
--- a/sys/crypto/openssl/ossl.c
+++ b/sys/crypto/openssl/ossl.c
@@ -48,6 +48,7 @@
#include <opencrypto/xform_auth.h>
#include <crypto/openssl/ossl.h>
+#include <crypto/openssl/ossl_chacha.h>
#include "cryptodev_if.h"
@@ -154,6 +155,16 @@
if (ossl_lookup_hash(csp) == NULL)
return (EINVAL);
break;
+ case CSP_MODE_CIPHER:
+ switch (csp->csp_cipher_alg) {
+ case CRYPTO_CHACHA20:
+ if (csp->csp_cipher_klen != CHACHA_KEY_SIZE)
+ return (EINVAL);
+ break;
+ default:
+ return (EINVAL);
+ }
+ break;
default:
return (EINVAL);
}
@@ -161,15 +172,12 @@
return (CRYPTODEV_PROBE_ACCEL_SOFTWARE);
}
-static int
-ossl_newsession(device_t dev, crypto_session_t cses,
+static void
+ossl_newsession_hash(struct ossl_session *s,
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)
@@ -195,31 +203,35 @@
fpu_kern_leave(curthread, NULL);
}
}
+}
+
+static int
+ossl_newsession(device_t dev, crypto_session_t cses,
+ const struct crypto_session_params *csp)
+{
+ struct ossl_session *s;
+
+ s = crypto_get_driver_session(cses);
+ switch (csp->csp_mode) {
+ case CSP_MODE_DIGEST:
+ ossl_newsession_hash(s, csp);
+ break;
+ }
+
return (0);
}
static int
-ossl_process(device_t dev, struct cryptop *crp, int hint)
+ossl_process_hash(struct ossl_session *s, struct cryptop *crp,
+ const struct crypto_session_params *csp)
{
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) {
ctx = s->hash.ictx;
} else {
@@ -273,13 +285,45 @@
explicit_bzero(digest, sizeof(digest));
out:
+ explicit_bzero(&ctx, sizeof(ctx));
+ return (error);
+}
+
+static int
+ossl_process(device_t dev, struct cryptop *crp, int hint)
+{
+ const struct crypto_session_params *csp;
+ struct ossl_session *s;
+ int error;
+ bool fpu_entered;
+
+ s = crypto_get_driver_session(crp->crp_session);
+ csp = crypto_get_params(crp->crp_session);
+
+ if (is_fpu_kern_thread(0)) {
+ fpu_entered = false;
+ } else {
+ fpu_kern_enter(curthread, NULL, FPU_KERN_NOCTX);
+ fpu_entered = true;
+ }
+
+ switch (csp->csp_mode) {
+ case CSP_MODE_DIGEST:
+ error = ossl_process_hash(s, crp, csp);
+ break;
+ case CSP_MODE_CIPHER:
+ error = ossl_chacha20(crp, csp);
+ break;
+ default:
+ __assert_unreachable();
+ }
+
if (fpu_entered)
fpu_kern_leave(curthread, NULL);
crp->crp_etype = error;
crypto_done(crp);
- explicit_bzero(&ctx, sizeof(ctx));
return (0);
}
diff --git a/sys/crypto/openssl/ossl_chacha.h b/sys/crypto/openssl/ossl_chacha.h
new file mode 100644
--- /dev/null
+++ b/sys/crypto/openssl/ossl_chacha.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * 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
+ */
+
+/* From include/crypto/chacha.h */
+
+#ifndef OSSL_CRYPTO_CHACHA_H
+#define OSSL_CRYPTO_CHACHA_H
+
+/*
+ * ChaCha20_ctr32 encrypts |len| bytes from |inp| with the given key and
+ * nonce and writes the result to |out|, which may be equal to |inp|.
+ * The |key| is not 32 bytes of verbatim key material though, but the
+ * said material collected into 8 32-bit elements array in host byte
+ * order. Same approach applies to nonce: the |counter| argument is
+ * pointer to concatenated nonce and counter values collected into 4
+ * 32-bit elements. This, passing crypto material collected into 32-bit
+ * elements as opposite to passing verbatim byte vectors, is chosen for
+ * efficiency in multi-call scenarios.
+ */
+void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp,
+ size_t len, const unsigned int key[8],
+ const unsigned int counter[4]);
+/*
+ * You can notice that there is no key setup procedure. Because it's
+ * as trivial as collecting bytes into 32-bit elements, it's reckoned
+ * that below macro is sufficient.
+ */
+#define CHACHA_U8TOU32(p) ( \
+ ((unsigned int)(p)[0]) | ((unsigned int)(p)[1]<<8) | \
+ ((unsigned int)(p)[2]<<16) | ((unsigned int)(p)[3]<<24) )
+
+#define CHACHA_KEY_SIZE 32
+#define CHACHA_CTR_SIZE 16
+#define CHACHA_BLK_SIZE 64
+
+#endif
diff --git a/sys/crypto/openssl/ossl_chacha20.c b/sys/crypto/openssl/ossl_chacha20.c
new file mode 100644
--- /dev/null
+++ b/sys/crypto/openssl/ossl_chacha20.c
@@ -0,0 +1,141 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * 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.
+ */
+
+#include <sys/types.h>
+#include <sys/endian.h>
+#include <sys/malloc.h>
+#include <sys/time.h>
+
+#include <opencrypto/cryptodev.h>
+
+#include <crypto/openssl/ossl.h>
+#include <crypto/openssl/ossl_chacha.h>
+
+int
+ossl_chacha20(struct cryptop *crp, const struct crypto_session_params *csp)
+{
+ _Alignas(8) unsigned int key[CHACHA_KEY_SIZE / 4];
+ unsigned int counter[CHACHA_CTR_SIZE / 4];
+ unsigned char block[CHACHA_BLK_SIZE];
+ struct crypto_buffer_cursor cc_in, cc_out;
+ const unsigned char *in, *inseg, *cipher_key;
+ unsigned char *out, *outseg;
+ size_t resid, todo, inlen, outlen;
+ uint32_t next_counter;
+ u_int i;
+
+ if (crp->crp_cipher_key != NULL)
+ cipher_key = crp->crp_cipher_key;
+ else
+ cipher_key = csp->csp_cipher_key;
+ for (i = 0; i < nitems(key); i++)
+ key[i] = CHACHA_U8TOU32(cipher_key + i * 4);
+ crypto_read_iv(crp, counter);
+ for (i = 0; i < nitems(counter); i++)
+ counter[i] = le32toh(counter[i]);
+
+ resid = crp->crp_payload_length;
+ crypto_cursor_init(&cc_in, &crp->crp_buf);
+ crypto_cursor_advance(&cc_in, crp->crp_payload_start);
+ inseg = crypto_cursor_segbase(&cc_in);
+ inlen = crypto_cursor_seglen(&cc_in);
+ if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) {
+ crypto_cursor_init(&cc_out, &crp->crp_obuf);
+ crypto_cursor_advance(&cc_out, crp->crp_payload_output_start);
+ } else
+ cc_out = cc_in;
+ outseg = crypto_cursor_segbase(&cc_out);
+ outlen = crypto_cursor_seglen(&cc_out);
+ while (resid >= CHACHA_BLK_SIZE) {
+ if (inlen < CHACHA_BLK_SIZE) {
+ crypto_cursor_copydata(&cc_in, CHACHA_BLK_SIZE, block);
+ in = block;
+ inlen = CHACHA_BLK_SIZE;
+ } else
+ in = inseg;
+ if (outlen < CHACHA_BLK_SIZE) {
+ out = block;
+ outlen = CHACHA_BLK_SIZE;
+ } else
+ out = outseg;
+
+ /* Figure out how many blocks we can encrypt/decrypt at once. */
+ todo = rounddown(MIN(inlen, outlen), CHACHA_BLK_SIZE);
+
+#ifdef __LP64__
+ /* ChaCha20_ctr32() assumes length is <= 4GB. */
+ todo = (uint32_t)todo;
+#endif
+
+ /* Truncate if the 32-bit counter would roll over. */
+ next_counter = counter[0] + todo / CHACHA_BLK_SIZE;
+ if (next_counter < counter[0]) {
+ todo -= next_counter * CHACHA_BLK_SIZE;
+ next_counter = 0;
+ }
+
+ ChaCha20_ctr32(out, in, todo, key, counter);
+
+ counter[0] = next_counter;
+ if (counter[0] == 0)
+ counter[1]++;
+
+ if (out == block) {
+ crypto_cursor_copyback(&cc_out, CHACHA_BLK_SIZE, block);
+ outseg = crypto_cursor_segbase(&cc_out);
+ outlen = crypto_cursor_seglen(&cc_out);
+ } else {
+ crypto_cursor_advance(&cc_out, todo);
+ outseg += todo;
+ outlen -= todo;
+ }
+ if (in == block) {
+ inseg = crypto_cursor_segbase(&cc_in);
+ inlen = crypto_cursor_seglen(&cc_in);
+ } else {
+ crypto_cursor_advance(&cc_in, todo);
+ inseg += todo;
+ inlen -= todo;
+ }
+ resid -= todo;
+ }
+
+ if (resid > 0) {
+ memset(block, 0, sizeof(block));
+ crypto_cursor_copydata(&cc_in, resid, block);
+ ChaCha20_ctr32(block, block, CHACHA_BLK_SIZE, key, counter);
+ crypto_cursor_copyback(&cc_out, resid, block);
+ }
+
+ explicit_bzero(block, sizeof(block));
+ explicit_bzero(counter, sizeof(counter));
+ explicit_bzero(key, sizeof(key));
+ return (0);
+}
diff --git a/sys/modules/ossl/Makefile b/sys/modules/ossl/Makefile
--- a/sys/modules/ossl/Makefile
+++ b/sys/modules/ossl/Makefile
@@ -8,6 +8,7 @@
cryptodev_if.h \
device_if.h \
ossl.c \
+ ossl_chacha20.c \
ossl_poly1305.c \
ossl_sha1.c \
ossl_sha256.c \
@@ -15,6 +16,7 @@
${SRCS.${MACHINE_CPUARCH}}
SRCS.aarch64= \
+ chacha-armv8.S \
poly1305-armv8.S \
sha1-armv8.S \
sha256-armv8.S \
@@ -22,6 +24,7 @@
ossl_aarch64.c
SRCS.amd64= \
+ chacha-x86_64.S \
poly1305-x86_64.S \
sha1-x86_64.S \
sha256-x86_64.S \
@@ -29,6 +32,7 @@
ossl_x86.c
SRCS.i386= \
+ chacha-x86.S \
poly1305-x86.S \
sha1-586.S \
sha256-586.S \

File Metadata

Mime Type
text/plain
Expires
Thu, Jan 16, 10:38 PM (20 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15829999
Default Alt Text
D28756.diff (12 KB)

Event Timeline