Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107562623
D28756.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D28756.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D28756: ossl: Add ChaCha20 cipher support.
Attached
Detach File
Event Timeline
Log In to Comment