* Crypto Fixes for 4.9
From: Herbert Xu @ 2016-12-10 6:01 UTC (permalink / raw)
To: Linus Torvalds, David S. Miller, Linux Kernel Mailing List,
Linux Crypto Mailing List
In-Reply-To: <20161205063754.GA9408@gondor.apana.org.au>
Hi Linus:
This push fixes the following issues:
- Fix pointer size when caam is used with AArch64 boot loader on
AArch32 kernel.
- Fix ahash state corruption in marvell driver.
- Fix buggy algif_aed tag handling.
- Prevent mcryptd from being used with incompatible algorithms
which can cause crashes.
Please pull from
git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6.git linus
Horia Geantă (1):
crypto: caam - fix pointer size for AArch64 boot loader, AArch32 kernel
Romain Perier (2):
crypto: marvell - Don't copy hash operation twice into the SRAM
crypto: marvell - Don't corrupt state of an STD req for re-stepped ahash
Stephan Mueller (2):
crypto: algif_aead - fix AEAD tag memory handling
crypto: algif_aead - fix uninitialized variable warning
tim (1):
crypto: mcryptd - Check mcryptd algorithm compatibility
crypto/algif_aead.c | 59 ++++++++++++++++++++++++++---------------
crypto/mcryptd.c | 19 ++++++++-----
drivers/crypto/caam/ctrl.c | 5 ++--
drivers/crypto/marvell/hash.c | 11 ++++----
4 files changed, 57 insertions(+), 37 deletions(-)
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [kernel-hardening] Re: Remaining crypto API regressions with CONFIG_VMAP_STACK
From: Eric Biggers @ 2016-12-10 6:03 UTC (permalink / raw)
To: kernel-hardening
Cc: Andy Lutomirski, linux-crypto, linux-kernel@vger.kernel.org,
linux-mm@kvack.org, Andrew Lutomirski, Stephan Mueller
In-Reply-To: <20161210053208.GA27951@gondor.apana.org.au>
On Sat, Dec 10, 2016 at 01:32:08PM +0800, Herbert Xu wrote:
> On Fri, Dec 09, 2016 at 09:25:38PM -0800, Andy Lutomirski wrote:
> >
> > > The following crypto drivers initialize a scatterlist to point into an
> > > ablkcipher_request, which may have been allocated on the stack with
> > > SKCIPHER_REQUEST_ON_STACK():
> > >
> > > drivers/crypto/ccp/ccp-crypto-aes-xts.c:162
> > > drivers/crypto/ccp/ccp-crypto-aes.c:94
> >
> > These are real, and I wish I'd known about them sooner.
>
> Are you sure? Any instance of *_ON_STACK must only be used with
> sync algorithms and most drivers under drivers/crypto declare
> themselves as async.
>
Why exactly is that? Obviously, it wouldn't work if you returned from the stack
frame before the request completed, but does anything stop someone from using an
*_ON_STACK() request and then waiting for the request to complete before
returning from the stack frame?
Eric
^ permalink raw reply
* Re: [kernel-hardening] Re: Remaining crypto API regressions with CONFIG_VMAP_STACK
From: Eric Biggers @ 2016-12-10 6:30 UTC (permalink / raw)
To: kernel-hardening
Cc: Andy Lutomirski, linux-crypto, linux-kernel@vger.kernel.org,
linux-mm@kvack.org, Andrew Lutomirski, Stephan Mueller
In-Reply-To: <20161210053711.GB27951@gondor.apana.org.au>
On Sat, Dec 10, 2016 at 01:37:12PM +0800, Herbert Xu wrote:
> On Fri, Dec 09, 2016 at 09:25:38PM -0800, Andy Lutomirski wrote:
> >
> > Herbert, how hard would it be to teach the crypto code to use a more
> > sensible data structure than scatterlist and to use coccinelle fix
> > this stuff for real?
>
> First of all we already have a sync non-SG hash interface, it's
> called shash.
>
> If we had enough sync-only users of skcipher then I'll consider
> adding an interface for it. However, at this point in time it
> appears to more sense to convert such users over to the async
> interface rather than the other way around.
>
> As for AEAD we never had a sync interface to begin with and I
> don't think I'm going to add one.
>
Isn't the question of "should the API use physical or virtual addresses"
independent of the question of "should the API support asynchronous requests"?
You can already choose, via the flags and mask arguments when allocating a
crypto transform, whether you want it to be synchronous or asynchronous or
whether you don't care. I don't see what that says about whether the API should
take in physical memory (e.g. scatterlists or struct pages) or virtual memory
(e.g. iov_iters or just regular pointers).
And while it's true that asynchronous algorithms are often provided by hardware
drivers that operate on physical memory, it's not always the case. For example
some of the AES-NI algorithms are asynchronous only because they use the SSE
registers which can't always available to kernel code, so the request may need
to be processed by another thread.
Eric
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: scatterwalk_map_and_copy incorrect optimization
From: Herbert Xu @ 2016-12-10 8:08 UTC (permalink / raw)
To: Jason A. Donenfeld; +Cc: linux-crypto, LKML
In-Reply-To: <CAHmME9p24bkNPD2CfGMUOHxgOX+OuFO_rVqfhOQdDexwW53ExA@mail.gmail.com>
On Fri, Dec 09, 2016 at 02:18:01PM +0100, Jason A. Donenfeld wrote:
> Hi Herbert,
>
> The scatterwalk_map_and_copy function copies ordinary buffers to and
> from scatterlists. These buffers can, of course, be on the stack, and
> this remains the most popular use of this function -- getting info
> between stack buffers and DMA regions. It's mostly used for adding or
> checking MACs, in the majority of call sites. Its implementation is
> relatively straightforward. It maps the DMA region(s) to a vaddr, and
> then just calls vanilla memcpy. Pretty uncontroversial.
>
> However, around ~4.1 an optimization was added to prevent copying when
> unnecessary (when the src and dst are the same). The optimization
> looks like this:
>
> if (sg_page(sg) == virt_to_page(buf) &&
> sg->offset == offset_in_page(buf))
> return;
>
> There are two problems with this:
This code no longer exists in the current tree.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: algif for compression?
From: Herbert Xu @ 2016-12-10 8:10 UTC (permalink / raw)
To: abed mohammad kamaluddin; +Cc: linux-crypto
In-Reply-To: <CACVarETuTx40WFD5TRUCwiYv5r3SEvhuJHpGjqPsz90qVZsYKA@mail.gmail.com>
abed mohammad kamaluddin <abedamu@gmail.com> wrote:
>
> We are also looking for user-space access to the kernel crypto layer
> compression algorithms. I have gone through AF_ALG but couldn’t find
> support for compression ops through it. This is required for our
> hardware zip engines whose driver hooks up to the crypto layer.
>
> I was going through the lists and stumbled across this thread. Has
> there been any updates or efforts put up in this direction since this
> thread is a few years old. If not, are there any alternate
> implementations that allow user-space access to compression? I have
> gone through cryptodev and see the same limitation there.
>
> Would appreciate any pointers in this regard.
The compression interface is currently in a state of flux. We
should make it settle down first before exporting it to user-space.
For a start it would be good to actually switch IPsec/IPcomp over
to the new compression interface.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: scatterwalk_map_and_copy incorrect optimization
From: Herbert Xu @ 2016-12-10 8:11 UTC (permalink / raw)
To: Jason A. Donenfeld; +Cc: linux-crypto, ebiggers, linux-kernel
In-Reply-To: <CAHmME9rq9NjawkZw6wQpWsrY58ZgyRutBKT5UL7RA+8Pv2GOew@mail.gmail.com>
Jason A. Donenfeld <Jason@zx2c4.com> wrote:
> Hah, looks like I missed [1] by a couple weeks. Looks like it's been
> settled then.
>
> Is this a stable@ candidate?
Not really since it shouldn't cause any problems unless the stack
is vmalloced.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [kernel-hardening] Re: Remaining crypto API regressions with CONFIG_VMAP_STACK
From: Herbert Xu @ 2016-12-10 8:16 UTC (permalink / raw)
To: Eric Biggers
Cc: kernel-hardening, luto, linux-crypto, linux-kernel, linux-mm,
luto, smueller
In-Reply-To: <20161210060316.GC6846@zzz>
Why did you drop me from the CC list when you were replying to
my email?
Eric Biggers <ebiggers3@gmail.com> wrote:
> On Sat, Dec 10, 2016 at 01:32:08PM +0800, Herbert Xu wrote:
>
>> Are you sure? Any instance of *_ON_STACK must only be used with
>> sync algorithms and most drivers under drivers/crypto declare
>> themselves as async.
>
> Why exactly is that? Obviously, it wouldn't work if you returned from the stack
> frame before the request completed, but does anything stop someone from using an
> *_ON_STACK() request and then waiting for the request to complete before
> returning from the stack frame?
The *_ON_STACK variants (except SHASH of course) were simply hacks
to help legacy crypto API users to cope with the new async interface.
In general we should avoid using the sync interface when possible.
It's a bad idea for the obvious reason that most of our async
algorithms want to DMA and that doesn't work very well when you're
using memory from the stack.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: Remaining crypto API regressions with CONFIG_VMAP_STACK
From: Eric Biggers @ 2016-12-10 8:39 UTC (permalink / raw)
To: Herbert Xu
Cc: kernel-hardening, luto, linux-crypto, linux-kernel, linux-mm,
luto, smueller
In-Reply-To: <20161210081643.GA384@gondor.apana.org.au>
On Sat, Dec 10, 2016 at 04:16:43PM +0800, Herbert Xu wrote:
> Why did you drop me from the CC list when you were replying to
> my email?
>
Sorry --- this thread is Cc'ed to the kernel-hardening mailing list (which was
somewhat recently revived), and I replied to the email that reached me from
there. It looks like it currently behaves a little differently from the vger
mailing lists, in that it replaces "Reply-To" with the address of the mailing
list itself rather than the sender. So that's how you got dropped. It also
seems to add a prefix to the subject...
I
> >> Are you sure? Any instance of *_ON_STACK must only be used with
> >> sync algorithms and most drivers under drivers/crypto declare
> >> themselves as async.
> >
> > Why exactly is that? Obviously, it wouldn't work if you returned from the stack
> > frame before the request completed, but does anything stop someone from using an
> > *_ON_STACK() request and then waiting for the request to complete before
> > returning from the stack frame?
>
> The *_ON_STACK variants (except SHASH of course) were simply hacks
> to help legacy crypto API users to cope with the new async interface.
> In general we should avoid using the sync interface when possible.
>
> It's a bad idea for the obvious reason that most of our async
> algorithms want to DMA and that doesn't work very well when you're
> using memory from the stack.
Sure, I just feel that the idea of "is this algorithm asynchronous?" is being
conflated with the idea of "does this algorithm operate on physical memory?".
Also, if *_ON_STACK are really not allowed with asynchronous algorithms can
there at least be a comment or a WARN_ON() to express this?
Thanks,
Eric
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* RE: [PATCH v6 1/2] sparc: fix a building error reported by kbuild
From: Gonglei (Arei) @ 2016-12-10 8:40 UTC (permalink / raw)
To: Sam Ravnborg
Cc: linux-kernel@vger.kernel.org, qemu-devel@nongnu.org,
virtio-dev@lists.oasis-open.org,
virtualization@lists.linux-foundation.org,
linux-crypto@vger.kernel.org, Luonengjun, mst@redhat.com,
stefanha@redhat.com, Huangweidong (C), Wubin (H),
xin.zeng@intel.com, Claudio Fontana, herbert@gondor.apana.org.au,
pasic@linux.vnet.ibm.com, davem@davemloft.net
In-Reply-To: <20161209215851.GA7717@ravnborg.org>
Regards,
-Gonglei
> -----Original Message-----
> From: linux-crypto-owner@vger.kernel.org
> [mailto:linux-crypto-owner@vger.kernel.org] On Behalf Of Sam Ravnborg
> Sent: Saturday, December 10, 2016 5:59 AM
> To: Gonglei (Arei)
> Cc: linux-kernel@vger.kernel.org; qemu-devel@nongnu.org;
> virtio-dev@lists.oasis-open.org; virtualization@lists.linux-foundation.org;
> linux-crypto@vger.kernel.org; Luonengjun; mst@redhat.com;
> stefanha@redhat.com; Huangweidong (C); Wubin (H); xin.zeng@intel.com;
> Claudio Fontana; herbert@gondor.apana.org.au; pasic@linux.vnet.ibm.com;
> davem@davemloft.net; Zhoujian (jay, Euler); Hanweidong (Randy);
> arei.gonglei@hotmail.com; cornelia.huck@de.ibm.com; Xuquan (Quan Xu);
> longpeng; Wanzongshun (Vincent); sparclinux@vger.kernel.org
> Subject: Re: [PATCH v6 1/2] sparc: fix a building error reported by kbuild
>
> Hi Gonglei.
>
> On Thu, Dec 08, 2016 at 12:37:08PM +0800, Gonglei wrote:
> > >> arch/sparc/include/asm/topology_64.h:44:44:
> > error: implicit declaration of function 'cpu_data'
> > [-Werror=implicit-function-declaration]
> >
> > #define topology_physical_package_id(cpu) (cpu_data(cpu).proc_id)
> > ^
> > Let's include cpudata.h in topology_64.h.
> >
> > Cc: Sam Ravnborg <sam@ravnborg.org>
> > Cc: David S. Miller <davem@davemloft.net>
> > Cc: sparclinux@vger.kernel.org
> > Suggested-by: Sam Ravnborg <sam@ravnborg.org>
> > Signed-off-by: Gonglei <arei.gonglei@huawei.com>
> Acked-by: Sam Ravnborg <sam@ravnborg.org>
>
Thanks.
> > ---
> > arch/sparc/include/asm/topology_64.h | 1 +
> > 1 file changed, 1 insertion(+)
> >
> > diff --git a/arch/sparc/include/asm/topology_64.h
> b/arch/sparc/include/asm/topology_64.h
> > index 7b4898a..2255430 100644
> > --- a/arch/sparc/include/asm/topology_64.h
> > +++ b/arch/sparc/include/asm/topology_64.h
> > @@ -4,6 +4,7 @@
> > #ifdef CONFIG_NUMA
> >
> > #include <asm/mmzone.h>
> > +#include <asm/cpudata.h>
>
> Nitpick - if you are going to resend this patch,
It depends on the maintainer's thought. :)
> then please order the two includes in alphabetic order.
>
> For two includes this looks like bikeshedding, but when we add
> more having them in a defined arder prevents merge conflicts.
> And makes it readable too.
>
> We also sometimes order the includes with the longest lines topmost,
> and lines with the ame length are ordered alphabetically.
> But this is not seen so often.
>
Regards,
-Gonglei
^ permalink raw reply
* Re: [kernel-hardening] [PATCH] siphash: add cryptographically secure hashtable function
From: Greg KH @ 2016-12-10 12:37 UTC (permalink / raw)
To: kernel-hardening
Cc: linux-kernel, linux-crypto, rusty, torvalds, Jason A. Donenfeld,
Jean-Philippe Aumasson, Daniel J . Bernstein
In-Reply-To: <20161209183659.25727-1-Jason@zx2c4.com>
On Fri, Dec 09, 2016 at 07:36:59PM +0100, Jason A. Donenfeld wrote:
> SipHash is a 64-bit keyed hash function that is actually a
> cryptographically secure PRF, like HMAC. Except SipHash is super fast,
> and is meant to be used as a hashtable keyed lookup function.
>
> SipHash isn't just some new trendy hash function. It's been around for a
> while, and there really isn't anything that comes remotely close to
> being useful in the way SipHash is. With that said, why do we need this?
>
> There are a variety of attacks known as "hashtable poisoning" in which an
> attacker forms some data such that the hash of that data will be the
> same, and then preceeds to fill up all entries of a hashbucket. This is
> a realistic and well-known denial-of-service vector.
>
> Linux developers already seem to be aware that this is an issue, and
> various places that use hash tables in, say, a network context, use a
> non-cryptographically secure function (usually jhash) and then try to
> twiddle with the key on a time basis (or in many cases just do nothing
> and hope that nobody notices). While this is an admirable attempt at
> solving the problem, it doesn't actually fix it. SipHash fixes it.
>
> (It fixes it in such a sound way that you could even build a stream
> cipher out of SipHash that would resist the modern cryptanalysis.)
>
> There are a modicum of places in the kernel that are vulnerable to
> hashtable poisoning attacks, either via userspace vectors or network
> vectors, and there's not a reliable mechanism inside the kernel at the
> moment to fix it. The first step toward fixing these issues is actually
> getting a secure primitive into the kernel for developers to use. Then
> we can, bit by bit, port things over to it as deemed appropriate.
>
> Dozens of languages are already using this internally for their hash
> tables. Some of the BSDs already use this in their kernels. SipHash is
> a widely known high-speed solution to a widely known problem, and it's
> time we catch-up.
>
> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
> Cc: Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com>
> Cc: Daniel J. Bernstein <djb@cr.yp.to>
> ---
> include/linux/siphash.h | 18 ++++++
> lib/Makefile | 3 +-
> lib/siphash.c | 163 ++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 183 insertions(+), 1 deletion(-)
> create mode 100644 include/linux/siphash.h
> create mode 100644 lib/siphash.c
This looks really nice, but we don't usually add stuff into lib/ unless
there is an actual user of the code :)
Have you tried converting any of the existing hash users to use this
instead? If you did that, and it shows a solution for the known
problems with our existing hashes (as you point out above), I doubt
there would be any objection for this patch at all.
Minor coding style nits below:
> @@ -0,0 +1,18 @@
> +/* Copyright (C) 2016 Jason A. Donenfeld <Jason@zx2c4.com>
> + *
> + * SipHash: a fast short-input PRF
> + * https://131002.net/siphash/
> + */
> +
> +#ifndef _LINUX_SIPHASH_H
> +#define _LINUX_SIPHASH_H
> +
> +#include <linux/types.h>
> +
> +enum siphash24_lengths {
> + SIPHASH24_KEY_LEN = 16
> +};
> +
> +uint64_t siphash24(const uint8_t *data, size_t len, const uint8_t key[SIPHASH24_KEY_LEN]);
Please use u64 and u8 instead of the userspace uint64_t and uint8_t
types for kernel code. Yes, the ship has probably sailed for trying to
strictly enforce it, but it's a good idea to do where ever possible.
> +
> +#endif /* _LINUX_SIPHASH_H */
> diff --git a/lib/Makefile b/lib/Makefile
> index 50144a3aeebd..d224337b0d01 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -22,7 +22,8 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
> sha1.o chacha20.o md5.o irq_regs.o argv_split.o \
> flex_proportions.o ratelimit.o show_mem.o \
> is_single_threaded.o plist.o decompress.o kobject_uevent.o \
> - earlycpio.o seq_buf.o nmi_backtrace.o nodemask.o win_minmax.o
> + earlycpio.o seq_buf.o siphash.o \
> + nmi_backtrace.o nodemask.o win_minmax.o
>
> lib-$(CONFIG_MMU) += ioremap.o
> lib-$(CONFIG_SMP) += cpumask.o
> diff --git a/lib/siphash.c b/lib/siphash.c
> new file mode 100644
> index 000000000000..022d86f04b9b
> --- /dev/null
> +++ b/lib/siphash.c
> @@ -0,0 +1,163 @@
> +/* Copyright (C) 2015-2016 Jason A. Donenfeld <Jason@zx2c4.com>
> + * Copyright (C) 2012-2014 Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com>
> + * Copyright (C) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
> + *
> + * SipHash: a fast short-input PRF
> + * https://131002.net/siphash/
> + */
Any specific license for this code? It's good to at the least say what
it is. Yes, we know it will default to GPLv2 only as part of the whole
kernel tree, but it's good to be explicit for when someone wants to copy
this code for their own projects...
> +
> +#include <linux/siphash.h>
> +#include <linux/kernel.h>
> +#include <linux/string.h>
> +
> +#define ROTL(x,b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
Don't we have this in kernel.h somewhere? Ah, yeah, it's rol64() in
bitops.h, no need to define it again please.
> +#define U8TO64(p) le64_to_cpu(*(__le64 *)(p))
Why the crazy casting behind a macro?
> +
> +#define SIPROUND \
> + do { \
> + v0 += v1; v1 = ROTL(v1, 13); v1 ^= v0; v0 = ROTL(v0, 32); \
> + v2 += v3; v3 = ROTL(v3, 16); v3 ^= v2; \
> + v0 += v3; v3 = ROTL(v3, 21); v3 ^= v0; \
> + v2 += v1; v1 = ROTL(v1, 17); v1 ^= v2; v2 = ROTL(v2, 32); \
> + } while(0)
> +
> +__attribute__((optimize("unroll-loops")))
Care to document why this attribute is needed? Older versions of gcc
doesn't know how to handle it properly? Faster with newer versions?
Black magic? :)
> +uint64_t siphash24(const uint8_t *data, size_t len, const uint8_t key[SIPHASH24_KEY_LEN])
> +{
> + uint64_t v0 = 0x736f6d6570736575ULL;
s/uint64_t/u64/g please.
> + uint64_t v1 = 0x646f72616e646f6dULL;
> + uint64_t v2 = 0x6c7967656e657261ULL;
> + uint64_t v3 = 0x7465646279746573ULL;
> + uint64_t b;
> + uint64_t k0 = U8TO64(key);
> + uint64_t k1 = U8TO64(key + sizeof(uint64_t));
> + uint64_t m;
> + const uint8_t *end = data + len - (len % sizeof(uint64_t));
> + const uint8_t left = len & (sizeof(uint64_t) - 1);
> + b = ((uint64_t)len) << 56;
> + v3 ^= k1;
> + v2 ^= k0;
> + v1 ^= k1;
> + v0 ^= k0;
> + for (; data != end; data += sizeof(uint64_t)) {
> + m = U8TO64(data);
> + v3 ^= m;
> + SIPROUND;
> + SIPROUND;
> + v0 ^= m;
> + }
> + switch (left) {
> + case 7: b |= ((uint64_t)data[6]) << 48;
> + case 6: b |= ((uint64_t)data[5]) << 40;
> + case 5: b |= ((uint64_t)data[4]) << 32;
> + case 4: b |= ((uint64_t)data[3]) << 24;
> + case 3: b |= ((uint64_t)data[2]) << 16;
> + case 2: b |= ((uint64_t)data[1]) << 8;
> + case 1: b |= ((uint64_t)data[0]); break;
> + case 0: break;
> + }
> + v3 ^= b;
> + SIPROUND;
> + SIPROUND;
> + v0 ^= b;
> + v2 ^= 0xff;
> + SIPROUND;
> + SIPROUND;
> + SIPROUND;
> + SIPROUND;
> + b = (v0 ^ v1) ^ (v2 ^ v3);
> + return (__force uint64_t)cpu_to_le64(b);
> +}
> +EXPORT_SYMBOL(siphash24);
EXPORT_SYMBOL_GPL()? I have to ask, sorry :)
> +
> +#ifdef DEBUG
> +static const uint8_t test_vectors[64][8] = {
> + { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72 },
> + { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74 },
> + { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d },
> + { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85 },
> + { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf },
> + { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18 },
> + { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb },
> + { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab },
> + { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93 },
> + { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e },
> + { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a },
> + { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4 },
> + { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75 },
> + { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14 },
> + { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7 },
> + { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1 },
> + { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f },
> + { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69 },
> + { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b },
> + { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb },
> + { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe },
> + { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0 },
> + { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93 },
> + { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8 },
> + { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8 },
> + { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc },
> + { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17 },
> + { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f },
> + { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde },
> + { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6 },
> + { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad },
> + { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32 },
> + { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71 },
> + { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7 },
> + { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12 },
> + { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15 },
> + { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31 },
> + { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02 },
> + { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca },
> + { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a },
> + { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e },
> + { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad },
> + { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18 },
> + { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4 },
> + { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9 },
> + { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9 },
> + { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb },
> + { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0 },
> + { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6 },
> + { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7 },
> + { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee },
> + { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1 },
> + { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a },
> + { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81 },
> + { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f },
> + { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24 },
> + { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7 },
> + { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea },
> + { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60 },
> + { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66 },
> + { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c },
> + { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f },
> + { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5 },
> + { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95 }
> +};
> +
> +static int siphash24_selftest(void)
> +{
> + uint8_t in[64], k[16], i;
> + uint64_t out;
> + int ret = 0;
> +
> + for (i = 0; i < 16; ++i)
> + k[i] = i;
> +
> + for (i = 0; i < 64; ++i) {
> + in[i] = i;
> + out = siphash24(in, i, k);
> + if (memcmp(&out, test_vectors[i], 8)) {
> + printk(KERN_INFO "siphash24: self-test %u: FAIL\n", i + 1);
pr_info()?
> + ret = -1;
Pick a real error number?
> + }
> + }
> + if (!ret)
> + printk(KERN_INFO "siphash24: self-tests: pass\n");
pr_info()?
> + return ret;
> +}
> +__initcall(siphash24_selftest);
Don't we have a "do crypto/library/whatever selftests at boot" config
option that this little test could be put under? It would be great to
not have to manually add DEBUG to the build to verify this works on a
specific arch.
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH] siphash: add cryptographically secure hashtable function
From: Vegard Nossum @ 2016-12-10 14:17 UTC (permalink / raw)
To: Jason A. Donenfeld
Cc: LKML, kernel-hardening, linux-crypto, Rusty Russell,
Linus Torvalds, Jean-Philippe Aumasson, Daniel J . Bernstein,
linux
In-Reply-To: <20161209183659.25727-1-Jason@zx2c4.com>
On 9 December 2016 at 19:36, Jason A. Donenfeld <Jason@zx2c4.com> wrote:
> SipHash is a 64-bit keyed hash function that is actually a
> cryptographically secure PRF, like HMAC. Except SipHash is super fast,
> and is meant to be used as a hashtable keyed lookup function.
>
> SipHash isn't just some new trendy hash function. It's been around for a
> while, and there really isn't anything that comes remotely close to
> being useful in the way SipHash is. With that said, why do we need this?
>
> There are a variety of attacks known as "hashtable poisoning" in which an
> attacker forms some data such that the hash of that data will be the
> same, and then preceeds to fill up all entries of a hashbucket. This is
> a realistic and well-known denial-of-service vector.
>
> Linux developers already seem to be aware that this is an issue, and
> various places that use hash tables in, say, a network context, use a
> non-cryptographically secure function (usually jhash) and then try to
> twiddle with the key on a time basis (or in many cases just do nothing
> and hope that nobody notices). While this is an admirable attempt at
> solving the problem, it doesn't actually fix it. SipHash fixes it.
Could you give some more concrete details/examples? Here's the IPv4
hash table from include/net/inet_sock.h / net/ipv4/inet_hashtables.c:
static inline unsigned int __inet_ehashfn(const __be32 laddr,
const __u16 lport,
const __be32 faddr,
const __be16 fport,
u32 initval)
{
return jhash_3words((__force __u32) laddr,
(__force __u32) faddr,
((__u32) lport) << 16 | (__force __u32)fport,
initval);
}
static u32 inet_ehashfn(const struct net *net, const __be32 laddr,
const __u16 lport, const __be32 faddr,
const __be16 fport)
{
static u32 inet_ehash_secret __read_mostly;
net_get_random_once(&inet_ehash_secret, sizeof(inet_ehash_secret));
return __inet_ehashfn(laddr, lport, faddr, fport,
inet_ehash_secret + net_hash_mix(net));
}
There's a 32-bit secret random salt (inet_ehash_secret) which means
that in practice, inet_ehashfn() will select 1 out of 2^32 different
hash functions at random each time you boot the kernel; without
knowing which one it selected, how can a local or remote attacker can
force IPv4 connections/whatever to go into a single hash bucket?
It is not possible to obtain the secret salt directly (except by
reading from kernel memory, in which case you've lost already), nor is
it possible to obtain the result of inet_ehashfn() other than (maybe)
by a timing attack where you somehow need to detect that two
connections went into the same hash bucket and work backwards from
that to figure out how to land more connections into into the same
bucket -- but if they can do that, you've also already lost.
The same pattern is used for IPv6 hashtables and the dentry cache.
I suppose that using a hash function proven to be cryptographically
secure gives a hard guarantee (under some assumptions) that the
salt/key will give enough diversity between the (in the example above)
2^32 different hash functions that you cannot improve your chances of
guessing that two values will map to the same bucket regardless of the
salt/key. However, I am a bit doubtful that using a cryptographically
secure hash function will make much of a difference as long as the
attacker doesn't actually have any way to get the output/result of the
hash function (and given that the hash function isn't completely
trivial, of course).
I am happy to be proven wrong, but you make it sound very easy to
exploit the current situation, so I would just like to ask whether you
have a concrete way to do that?
Vegard
> There are a modicum of places in the kernel that are vulnerable to
> hashtable poisoning attacks, either via userspace vectors or network
> vectors, and there's not a reliable mechanism inside the kernel at the
> moment to fix it. The first step toward fixing these issues is actually
> getting a secure primitive into the kernel for developers to use. Then
> we can, bit by bit, port things over to it as deemed appropriate.
>
> Dozens of languages are already using this internally for their hash
> tables. Some of the BSDs already use this in their kernels. SipHash is
> a widely known high-speed solution to a widely known problem, and it's
> time we catch-up.
^ permalink raw reply
* Re: [kernel-hardening] Re: Remaining crypto API regressions with CONFIG_VMAP_STACK
From: Jason A. Donenfeld @ 2016-12-10 14:45 UTC (permalink / raw)
To: kernel-hardening
Cc: Andy Lutomirski, Eric Biggers, linux-crypto,
linux-kernel@vger.kernel.org, linux-mm@kvack.org,
Andrew Lutomirski, Stephan Mueller
In-Reply-To: <20161210053711.GB27951@gondor.apana.org.au>
Hi Herbert,
On Sat, Dec 10, 2016 at 6:37 AM, Herbert Xu <herbert@gondor.apana.org.au> wrote:
> As for AEAD we never had a sync interface to begin with and I
> don't think I'm going to add one.
That's too bad to hear. I hope you'll reconsider. Modern cryptographic
design is heading more and more in the direction of using AEADs for
interesting things, and having a sync interface would be a lot easier
for implementing these protocols. In the same way many protocols need
a hash of some data, now protocols often want some particular data
encrypted with an AEAD using a particular key and nonce and AD. One
protocol that comes to mind is Noise [1].
I know that in my own [currently external to the tree] kernel code, I
just forego the use of the crypto API all together, and one of the
primary reasons for that is lack of a sync interface for AEADs. When I
eventually send this upstream, presumably everyone will want me to use
the crypto API, and having a sync AEAD interface would be personally
helpful for that. I guess I could always write the sync interface
myself, but I imagine you'd prefer having the design control etc.
Jason
[1] http://noiseprotocol.org/
^ permalink raw reply
* Re: [PATCH] siphash: add cryptographically secure hashtable function
From: George Spelvin @ 2016-12-10 15:35 UTC (permalink / raw)
To: Jason, vegard.nossum
Cc: djb, jeanphilippe.aumasson, kernel-hardening, linux-crypto,
linux-kernel, linux, rusty, torvalds
In-Reply-To: <CAOMGZ=HMTZhBOh0jTBT4cyMuK5s-D51FFUtWUWyMV7VX0U2L0w@mail.gmail.com>
> There's a 32-bit secret random salt (inet_ehash_secret) which means
> that in practice, inet_ehashfn() will select 1 out of 2^32 different
> hash functions at random each time you boot the kernel; without
> knowing which one it selected, how can a local or remote attacker can
> force IPv4 connections/whatever to go into a single hash bucket?
By figuring out the salt. The thing is, the timing of hash table lookups
*is externally visible*. If I create connections to the target, then
see which ones make responses on previous connections slightly slower,
I gain information about the salt.
I dont't know *where* in the hash table the collissions occur, but I
know *which* inputs collide, and that's enough for me to learn something.
(I need more connections than the size of the hash table, but even
with just one IP source I can use 64K ports on my end times however
many the target has open on its end.)
With enough information (google "unicity distance") I can recover the
entire salt. It's not like I care about the cryptographic strength of
the hash; simply trying all 4 billion possible seeds is pretty fast on
a 4 GHz processor.
Once that happens, I can choose a target connection whose timing I can't
observe directly and pack its hash chain without being obvious about it.
> I am happy to be proven wrong, but you make it sound very easy to
> exploit the current situation, so I would just like to ask whether you
> have a concrete way to do that?
I don't think anyone's implemented an attack on this particular hash
table yet, and the reason it hasn't been urgent is that it's just a mild
DoS attack it makes the computer noticeably slower withough disabling
it completely.
But the general style of attack is well known and has been repeatedly
demonstrated. Its practicality is not in question. The only question is
whether it's *more* practical that simpler techniques that don't depend
on any such algorithmic subtlety like brute-force flooding.
But if the history of Internet security has taught us one thing, it's
that naively hoping something won't be a problem is doomed.
The main issue is performance. IPv6 addresses are big, and although
SipHash is fast by the standard of cryptographic hashes, it's far slower
than jhash or any other non-cryptographic hash.
^ permalink raw reply
* Re: [kernel-hardening] Re: Remaining crypto API regressions with CONFIG_VMAP_STACK
From: Andy Lutomirski @ 2016-12-10 17:48 UTC (permalink / raw)
To: Jason A. Donenfeld, Al Viro
Cc: kernel-hardening@lists.openwall.com, Eric Biggers, linux-crypto,
linux-kernel@vger.kernel.org, linux-mm@kvack.org,
Andrew Lutomirski, Stephan Mueller
In-Reply-To: <CAHmME9pzT=bxuEVVGDOJkm2PaEAVjbo=8na7URy=g-1sKvv0yw@mail.gmail.com>
cc: Viro because I'm talking about iov_iter.
On Sat, Dec 10, 2016 at 6:45 AM, Jason A. Donenfeld <Jason@zx2c4.com> wrote:
> Hi Herbert,
>
> On Sat, Dec 10, 2016 at 6:37 AM, Herbert Xu <herbert@gondor.apana.org.au> wrote:
>> As for AEAD we never had a sync interface to begin with and I
>> don't think I'm going to add one.
>
> That's too bad to hear. I hope you'll reconsider. Modern cryptographic
> design is heading more and more in the direction of using AEADs for
> interesting things, and having a sync interface would be a lot easier
> for implementing these protocols. In the same way many protocols need
> a hash of some data, now protocols often want some particular data
> encrypted with an AEAD using a particular key and nonce and AD. One
> protocol that comes to mind is Noise [1].
>
I think that sync vs async has gotten conflated with
vectored-vs-nonvectored and the results are unfortunate.
There are a lot of users in the tree that are trying to do crypto on
very small pieces of data and want to have that data consist of the
concatenation of two small buffers and/or want to use primitives that
don't have "sync" interfaces. These users are stuck using async
interfaces even though using async implementations makes no sense for
them.
I'd love to see the API restructured a bit to decouple all of these
considerations. One approach might be to teach iov_iter about
scatterlists. Then, for each primitive, there could be two entry
points:
1. A simplified and lower-overhead entry. You pass it an iov_iter
(and, depending on what the operation is, an output iov_iter), it does
the crypto synchronously, and returns. Operating in-place might be
permitted for some primitives.
2. A full-featured async entry. You pass it iov_iters and it requires
that the iov_iters be backed by scatterlists in order to operate
asynchronously.
I see no reason that the decisions to use virtual vs physical
addressing or to do vectored vs non-vectored IO should be tied up with
asynchronicity.
--Andy
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [PATCH] siphash: add cryptographically secure hashtable function
From: Jean-Philippe Aumasson @ 2016-12-10 18:13 UTC (permalink / raw)
To: Vegard Nossum, Jason A. Donenfeld
Cc: LKML, kernel-hardening, linux-crypto, Rusty Russell,
Linus Torvalds, Daniel J . Bernstein, linux
In-Reply-To: <CAOMGZ=HMTZhBOh0jTBT4cyMuK5s-D51FFUtWUWyMV7VX0U2L0w@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 5804 bytes --]
SipHash co-designer here.
SipHash is secure when it takes a secret key/seed as parameter, meaning
that its output values are unpredictable. Concretely, when SipHash produces
64-bit output values then you've a chance 1/2^64 to guess the hash value of
a given message, provided that the key/seed is kept secret. That's the
standard security definition of a pseudorandom function (PRF), which is
typically instantiated with a MAC such as HMAC-somehash.
With djb we demonstrated that this security notion is sufficient to protect
from hash-flooding attacks wherein an attacker creates many different input
values that hash to a same value and therefore may DoS the underlying data
structure.
I admit that the naming is confusing: "SipHash" is not a hash function,
strictly speaking. In crypto we only call hash function algorithms that are
unkeyed. PRFs/MACs are sometimes called keyed hash functions though.
On Sat, Dec 10, 2016 at 3:17 PM Vegard Nossum <vegard.nossum@gmail.com>
wrote:
> On 9 December 2016 at 19:36, Jason A. Donenfeld <Jason@zx2c4.com> wrote:
> > SipHash is a 64-bit keyed hash function that is actually a
> > cryptographically secure PRF, like HMAC. Except SipHash is super fast,
> > and is meant to be used as a hashtable keyed lookup function.
> >
> > SipHash isn't just some new trendy hash function. It's been around for a
> > while, and there really isn't anything that comes remotely close to
> > being useful in the way SipHash is. With that said, why do we need this?
> >
> > There are a variety of attacks known as "hashtable poisoning" in which an
> > attacker forms some data such that the hash of that data will be the
> > same, and then preceeds to fill up all entries of a hashbucket. This is
> > a realistic and well-known denial-of-service vector.
> >
> > Linux developers already seem to be aware that this is an issue, and
> > various places that use hash tables in, say, a network context, use a
> > non-cryptographically secure function (usually jhash) and then try to
> > twiddle with the key on a time basis (or in many cases just do nothing
> > and hope that nobody notices). While this is an admirable attempt at
> > solving the problem, it doesn't actually fix it. SipHash fixes it.
>
> Could you give some more concrete details/examples? Here's the IPv4
> hash table from include/net/inet_sock.h / net/ipv4/inet_hashtables.c:
>
> static inline unsigned int __inet_ehashfn(const __be32 laddr,
> const __u16 lport,
> const __be32 faddr,
> const __be16 fport,
> u32 initval)
> {
> return jhash_3words((__force __u32) laddr,
> (__force __u32) faddr,
> ((__u32) lport) << 16 | (__force __u32)fport,
> initval);
> }
>
> static u32 inet_ehashfn(const struct net *net, const __be32 laddr,
> const __u16 lport, const __be32 faddr,
> const __be16 fport)
> {
> static u32 inet_ehash_secret __read_mostly;
>
> net_get_random_once(&inet_ehash_secret, sizeof(inet_ehash_secret));
>
> return __inet_ehashfn(laddr, lport, faddr, fport,
> inet_ehash_secret + net_hash_mix(net));
> }
>
> There's a 32-bit secret random salt (inet_ehash_secret) which means
> that in practice, inet_ehashfn() will select 1 out of 2^32 different
> hash functions at random each time you boot the kernel; without
> knowing which one it selected, how can a local or remote attacker can
> force IPv4 connections/whatever to go into a single hash bucket?
>
> It is not possible to obtain the secret salt directly (except by
> reading from kernel memory, in which case you've lost already), nor is
> it possible to obtain the result of inet_ehashfn() other than (maybe)
> by a timing attack where you somehow need to detect that two
> connections went into the same hash bucket and work backwards from
> that to figure out how to land more connections into into the same
> bucket -- but if they can do that, you've also already lost.
>
> The same pattern is used for IPv6 hashtables and the dentry cache.
>
> I suppose that using a hash function proven to be cryptographically
> secure gives a hard guarantee (under some assumptions) that the
> salt/key will give enough diversity between the (in the example above)
> 2^32 different hash functions that you cannot improve your chances of
> guessing that two values will map to the same bucket regardless of the
> salt/key. However, I am a bit doubtful that using a cryptographically
> secure hash function will make much of a difference as long as the
> attacker doesn't actually have any way to get the output/result of the
> hash function (and given that the hash function isn't completely
> trivial, of course).
>
> I am happy to be proven wrong, but you make it sound very easy to
> exploit the current situation, so I would just like to ask whether you
> have a concrete way to do that?
>
>
> Vegard
>
> > There are a modicum of places in the kernel that are vulnerable to
> > hashtable poisoning attacks, either via userspace vectors or network
> > vectors, and there's not a reliable mechanism inside the kernel at the
> > moment to fix it. The first step toward fixing these issues is actually
> > getting a secure primitive into the kernel for developers to use. Then
> > we can, bit by bit, port things over to it as deemed appropriate.
> >
> > Dozens of languages are already using this internally for their hash
> > tables. Some of the BSDs already use this in their kernels. SipHash is
> > a widely known high-speed solution to a widely known problem, and it's
> > time we catch-up.
>
[-- Attachment #2: Type: text/html, Size: 8549 bytes --]
^ permalink raw reply
* Re: [PATCH 3/3] crypto: brcm: Add Broadcom SPU driver DT entry.
From: kbuild test robot @ 2016-12-11 0:14 UTC (permalink / raw)
To: Rob Rice
Cc: kbuild-all-JC7UmRfGjtg, Herbert Xu, David S. Miller, Rob Herring,
Mark Rutland, linux-crypto-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Ray Jui, Scott Branden,
Jon Mason, bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
Catalin Marinas, Will Deacon,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Steve Lin,
Rob Rice
In-Reply-To: <1480536453-24781-4-git-send-email-rob.rice-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1065 bytes --]
Hi Rob,
[auto build test ERROR on cryptodev/master]
[also build test ERROR on v4.9-rc8]
[cannot apply to next-20161209]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Rob-Rice/crypto-brcm-DT-documentation-for-Broadcom-SPU-driver/20161202-010038
base: https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master
config: arm64-defconfig (attached as .config)
compiler: aarch64-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=arm64
All errors (new ones prefixed by >>):
>> ERROR: Input tree has errors, aborting (use -f to force output)
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 31957 bytes --]
^ permalink raw reply
* Re: [PATCH] siphash: add cryptographically secure hashtable function
From: Jason A. Donenfeld @ 2016-12-11 15:30 UTC (permalink / raw)
To: Greg KH
Cc: kernel-hardening, LKML, linux-crypto, Linus Torvalds,
Jean-Philippe Aumasson, Daniel J . Bernstein, Herbert Xu,
George Spelvin, Scott Bauer, ak, Andy Lutomirski
In-Reply-To: <20161210123725.GC21421@kroah.com>
Hi Greg,
Thanks for the review. Responses to your suggestions are inline below:
On Sat, Dec 10, 2016 at 1:37 PM, Greg KH <gregkh@linuxfoundation.org> wrote:
> Please use u64 and u8 instead of the userspace uint64_t and uint8_t
> types for kernel code. Yes, the ship has probably sailed for trying to
> strictly enforce it, but it's a good idea to do where ever possible.
I didn't know this was a rule. Since I had seen a hodgepodge
throughout the kernel I just sort of assumed it was a free for all.
I've fixed this up for v2, and I've also gone through all of my other
[not yet submitted] code and made this change.
> Any specific license for this code? It's good to at the least say what
> it is. Yes, we know it will default to GPLv2 only as part of the whole
> kernel tree, but it's good to be explicit for when someone wants to copy
> this code for their own projects...
Public domain, actually. I'll add notice of this to the header.
> Don't we have this in kernel.h somewhere? Ah, yeah, it's rol64() in
> bitops.h, no need to define it again please.
Thanks!
>
>> +#define U8TO64(p) le64_to_cpu(*(__le64 *)(p))
>
> Why the crazy casting behind a macro?
le64_to_cpup doesn't take the right type. But I agree the macro is not
the nicest way to do this. Instead, I'll copy what
crypto/chacha20_generic.c does and define locally le64_to_cpuvp which
takes a void pointer:
static inline u64 le64_to_cpuvp(const void *p)
{
return le64_to_cpup(p);
}
>> +__attribute__((optimize("unroll-loops")))
>
> Care to document why this attribute is needed? Older versions of gcc
> doesn't know how to handle it properly? Faster with newer versions?
> Black magic? :)
It tells gcc to unroll the loops. Comparing the assembly, it looks
like on x86_64, gcc does twice as many rounds per loop iteration when
asked to unroll the loops. This allows the code to remain neat and
straightforward, while instructing gcc to do the gnarly part.
Is this too much rice? Have I been Gentoo-ing for too long? Or are
limited uses of unroll-loops acceptable?
> s/uint64_t/u64/g please.
Done.
> EXPORT_SYMBOL_GPL()? I have to ask, sorry :)
Since it's public domain, EXPORT_SYMBOL() is fine.
If you have some reason for preferring GPL2 over public domain, I'm
happy to make the change. Maybe you want to preclude the new&shiny
from proprietary modules? That's fine with me, if you desire it being
that way.
>
>
> pr_info()?
Ack.
>
>> + ret = -1;
>
> Pick a real error number?
I started to do this, but couldn't make up my mind, and then resigned
to -1. I'll redouble my efforts to pick something decent.
> pr_info()?
Ack.
> Don't we have a "do crypto/library/whatever selftests at boot" config
> option that this little test could be put under? It would be great to
> not have to manually add DEBUG to the build to verify this works on a
> specific arch.
There is crypto/testmgr.c, but it's designed for testing things that
use the actual crypto API. Clearly for a hashtable function, nobody
would accept the overhead of the enormous crypto API, so siphash has
to remain an ordinary fast function call. Also, it lives in lib/, not
in crypto/. For that reason, I thought that Herbert might object if I
clutter up his testmgr with non crypto API functions. I'll CC him on
this email to double check.
> This looks really nice, but we don't usually add stuff into lib/ unless
> there is an actual user of the code :)
>
> Have you tried converting any of the existing hash users to use this
> instead? If you did that, and it shows a solution for the known
> problems with our existing hashes (as you point out above), I doubt
> there would be any objection for this patch at all.
Here's where the controversy begins! As we've seen from this thread,
there are two hurdles:
1. Convincing people that the cryptographic properties of siphash are
important, and jhash does not have these. I think JP Aumasson's email
described things pretty clearly, and this isn't really up for debate
anymore.
2. Convincing people that for a particular use case, siphash _is_
sufficiently fast, and that any potential (tiny) slowdown, compared to
insecure function like jhash, is either a) not worth having a
known-vulnerability or b) not even measurably relavent for the actual
real life workload.
I suspect that the debates about (2.a) and (2.b) will need to be duked
out one-by-one for a bit of time. I thought that since this will be
more of an evolutionary change, it'd be best to at least get the
primitives into lib/ so they can actually be used.
For example, I found some patches from George Spelvin (CC'd) trying to
get this added a few years back, for reasons related to extfs code. I
found a discussion between Scott Bauer (CC'd) and Andy&Andi (CC'd)
about adding siphash for the purpose of SROP mitigation, but not doing
so because there wasn't the primitive in lib/.
Seeing that siphash is both a solution to current existing problems,
future security mechanisms, and current things people clearly seem to
want, I thought it might be worthwhile to add this straight-up.
But if you really really want me to submit this alongside a patch
series of places that could be changed, I guess I could take the time
to pick out the most uncontroversial places -- some network stack /
netfilter places, some userspace API hashtable DoS places, etc -- but
I fear that's going to drag so many different consumers into the fold
that in the end nothing will get merged. So I think this might be a
good case for an exception with /lib, as a means of making forward
progress in general. Feel free to disagree, though; you know best.
Regards,
Jason
^ permalink raw reply
* Re: Remaining crypto API regressions with CONFIG_VMAP_STACK
From: Andy Lutomirski @ 2016-12-11 19:13 UTC (permalink / raw)
To: Eric Biggers
Cc: linux-crypto, linux-kernel@vger.kernel.org, linux-mm@kvack.org,
kernel-hardening@lists.openwall.com, Herbert Xu,
Andrew Lutomirski, Stephan Mueller
In-Reply-To: <20161209230851.GB64048@google.com>
On Fri, Dec 9, 2016 at 3:08 PM, Eric Biggers <ebiggers3@gmail.com> wrote:
> In the 4.9 kernel, virtually-mapped stacks will be supported and enabled by
> default on x86_64. This has been exposing a number of problems in which
> on-stack buffers are being passed into the crypto API, which to support crypto
> accelerators operates on 'struct page' rather than on virtual memory.
>
> fs/cifs/smbencrypt.c:96
This should use crypto_cipher_encrypt_one(), I think.
--Andy
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* [ANNOUNCE] libkcapi v0.13.0 released
From: Stephan Müller @ 2016-12-11 20:31 UTC (permalink / raw)
To: linux-crypto
Hi,
The Linux kernel exports a network interface of type AF_ALG to allow user
space to utilize the kernel crypto API. libkcapi uses this network interface
and exports an easy to use API so that a developer does not need to consider
the low-level network interface handling.
The library does not implement any low level cipher algorithms. All consumer
requests are sent to the kernel for processing. Results from the kernel crypto
API are returned to the consumer via the library API.
The kernel interface and therefore this library can be used by unprivileged
processes.
The library code archive also provides a drop-in replacement for the command
line tools of sha*sum, fipscheck/fipshmac and sha512hmac.
The source code and the documentation is available at [1].
[1] http://www.chronox.de/libkcapi.html
Changes v0.13.0:
* change kcapi_aead_encrypt_aio, kcapi_aead_decrypt_aio,
kcapi_cipher_encrypt_aio and kcapi_cipher_decrypt_aio to require the
user to provide IOVECs for input and output buffers separately
* addition of kcapi_aead_inbuflen_enc, kcapi_aead_inbuflen_dec,
kcapi_aead_outbuflen_enc, kcapi_aead_outbuflen_dec,
kcapi_aead_getdata_input,
kcapi_aead_getdata_output to allow apps to be programmed without specific
code handling for old and new AEAD AF_ALG interface (AAD and tag handling).
See the documentation section "AEAD Memory Structure" for an explanation
on how to use the API in a way to make the calling application agnostic
of the kernel interface differences.
* significant addition to library to handle old / new AEAD AF_ALG interface
without the caller being aware of that
* change AEAD tests such to use the new API calls to make code independent
of AEAD interface changes
* split up of the library implementation into individual files to allow
a more clear code management and to allow even to selectively disable
code to make the library smaller
* various small fixes suggested by Zbigniew Jędrzejewski-Szmek
* fix memleak in kcapi_*_destroy suggested by Zbigniew Jędrzejewski-Szmek
* use hard-links for the kcapi-hasher apps
* add bi-arch tests
* add check that AIO interface is only initialized if the kernel supports
AIO (library requires kernel 4.1.0 or larger for skcipher AIO and
4.7.0 or larger for AEAD AIO support)
* add transparent fallback in case the caller requests AIO operation but
the AIO interface was not or could not be initialized -- the AIO API can be
used on systems without AIO support as the library transparently falls back
to the non-AIO operation (however, the library complains at the beginning
about the use of the AIO API on unsupported systems).
Ciao
Stephan
^ permalink raw reply
* Re: [kernel-hardening] [PATCH] siphash: add cryptographically secure hashtable function
From: Greg KH @ 2016-12-11 20:43 UTC (permalink / raw)
To: Jason A. Donenfeld
Cc: kernel-hardening, LKML, linux-crypto, Linus Torvalds,
Jean-Philippe Aumasson, Daniel J . Bernstein, Herbert Xu,
George Spelvin, Scott Bauer, ak, Andy Lutomirski
In-Reply-To: <CAHmME9qFjeiSFkXfyQQgpRyQCj7dDV9r+UM7S8W=QBsQX+=McQ@mail.gmail.com>
On Sun, Dec 11, 2016 at 04:30:31PM +0100, Jason A. Donenfeld wrote:
> Hi Greg,
>
> Thanks for the review. Responses to your suggestions are inline below:
>
> On Sat, Dec 10, 2016 at 1:37 PM, Greg KH <gregkh@linuxfoundation.org> wrote:
> > Please use u64 and u8 instead of the userspace uint64_t and uint8_t
> > types for kernel code. Yes, the ship has probably sailed for trying to
> > strictly enforce it, but it's a good idea to do where ever possible.
>
> I didn't know this was a rule. Since I had seen a hodgepodge
> throughout the kernel I just sort of assumed it was a free for all.
> I've fixed this up for v2, and I've also gone through all of my other
> [not yet submitted] code and made this change.
>
> > Any specific license for this code? It's good to at the least say what
> > it is. Yes, we know it will default to GPLv2 only as part of the whole
> > kernel tree, but it's good to be explicit for when someone wants to copy
> > this code for their own projects...
>
> Public domain, actually. I'll add notice of this to the header.
Hm, there really is no such license as "Public domain" that works in all
countries, sorry. You will note it's not one of the "valid module
license list" we have in module.h because of that.
So, I don't know where you got the code from, but perhaps "Dual BSD/GPL"
is the correct one for you?
Note, I'm not a lawyer, so this isn't legal advice about the license of
code, but I do spend way too much time with lawyers dealing with license
issues...
> >> +#define U8TO64(p) le64_to_cpu(*(__le64 *)(p))
> >
> > Why the crazy casting behind a macro?
>
> le64_to_cpup doesn't take the right type. But I agree the macro is not
> the nicest way to do this. Instead, I'll copy what
> crypto/chacha20_generic.c does and define locally le64_to_cpuvp which
> takes a void pointer:
>
> static inline u64 le64_to_cpuvp(const void *p)
> {
> return le64_to_cpup(p);
> }
Ah much better.
> >> +__attribute__((optimize("unroll-loops")))
> >
> > Care to document why this attribute is needed? Older versions of gcc
> > doesn't know how to handle it properly? Faster with newer versions?
> > Black magic? :)
>
> It tells gcc to unroll the loops. Comparing the assembly, it looks
> like on x86_64, gcc does twice as many rounds per loop iteration when
> asked to unroll the loops. This allows the code to remain neat and
> straightforward, while instructing gcc to do the gnarly part.
>
> Is this too much rice? Have I been Gentoo-ing for too long? Or are
> limited uses of unroll-loops acceptable?
Given that this would be the first use of it in the kernel, it might be
too much rice :)
Unless you can show real numbers that it actually matters, I wouldn't do
it, it's not worth the hassle. That's the same rule for when you use
likely()/unlikely(), if you can not measure it, don't use it as you
almost always get it wrong, the compiler is smarter, and keeps getting
better over time.
> > s/uint64_t/u64/g please.
>
> Done.
>
> > EXPORT_SYMBOL_GPL()? I have to ask, sorry :)
>
> Since it's public domain, EXPORT_SYMBOL() is fine.
>
> If you have some reason for preferring GPL2 over public domain, I'm
> happy to make the change. Maybe you want to preclude the new&shiny
> from proprietary modules? That's fine with me, if you desire it being
> that way.
Nope, I just have to ask :)
If it's dual licensed, a normal EXPORT_SYMBOL() is just fine, I have no
objection to that at all.
thanks,
greg k-h
^ permalink raw reply
* Re: Remaining crypto API regressions with CONFIG_VMAP_STACK
From: Eric Biggers @ 2016-12-11 23:31 UTC (permalink / raw)
To: Andy Lutomirski
Cc: linux-crypto, linux-kernel@vger.kernel.org, linux-mm@kvack.org,
kernel-hardening@lists.openwall.com, Herbert Xu,
Andrew Lutomirski, Stephan Mueller
In-Reply-To: <CALCETrVBGPijiacbY-trdbgRPYC8grNrGA7TVu0xvxUaqud08w@mail.gmail.com>
On Sun, Dec 11, 2016 at 11:13:55AM -0800, Andy Lutomirski wrote:
> On Fri, Dec 9, 2016 at 3:08 PM, Eric Biggers <ebiggers3@gmail.com> wrote:
> > In the 4.9 kernel, virtually-mapped stacks will be supported and enabled by
> > default on x86_64. This has been exposing a number of problems in which
> > on-stack buffers are being passed into the crypto API, which to support crypto
> > accelerators operates on 'struct page' rather than on virtual memory.
> >
>
> > fs/cifs/smbencrypt.c:96
>
> This should use crypto_cipher_encrypt_one(), I think.
>
> --Andy
Yes, I believe that's correct. It encrypts 8 bytes with ecb(des) which is
equivalent to simply encrypting one block with DES. Maybe try the following
(untested):
static int
smbhash(unsigned char *out, const unsigned char *in, unsigned char *key)
{
unsigned char key2[8];
struct crypto_cipher *cipher;
str_to_key(key, key2);
cipher = crypto_alloc_cipher("des", 0, 0);
if (IS_ERR(cipher)) {
cifs_dbg(VFS, "could not allocate des cipher\n");
return PTR_ERR(cipher);
}
crypto_cipher_setkey(cipher, key2, 8);
crypto_cipher_encrypt_one(cipher, out, in);
crypto_free_cipher(cipher);
return 0;
}
- Eric
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* kernel crash when using sha1 as csums-alg for drbd
From: Zhang Zhuoyu @ 2016-12-12 3:31 UTC (permalink / raw)
To: mouli; +Cc: marex, hpa, herbert, 'lixiubo', linux-crypto
Hello, Chandramouli
Sorry for last email.
These days we experienced 5 times kernel crash issue when using sha1 as
csums-alg for drbd on our CentOS7.2 3.10.0-327.el7.x86_64:
Kernel log as below:
[19839335.792807] BUG: unable to handle kernel paging request at
ffff88007bd4f000
[19839335.793145] IP: [<ffffffff8106a908>] _begin+0x28/0x187
[19839335.793326] PGD 1f32067 PUD 607ffff067 PMD 1f35067 PTE 0
[19839335.793510] Oops: 0000 [#1] SMP
[19839335.793683] Modules linked in: dm_service_time iscsi_tcp libiscsi_tcp
libiscsi scsi_transport_iscsi nf_conntrack_netlink nf_conntrack_ipv6
nf_defrag_ipv6 xt_mac xt_set xt_physdev xt_CT ip_set_hash_net ip_set
nfnetlink vhost_net vhost macvtap macvlan veth iptable_raw iptable_filter
iptable_nat nf_nat_ipv4 iptable_mangle ip_tables dm_multipath ip6table_raw
vport_vxlan vxlan ip6_udp_tunnel udp_tunnel openvswitch xt_multiport
ipmi_devintf xt_comment ext4 mbcache jbd2 xt_CHECKSUM ipt_MASQUERADE
nf_nat_masquerade_ipv4 nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack
nf_conntrack ipt_REJECT tun bridge ebtable_filter ebtables ip6table_filter
ip6_tables drbd(OE) 8021q garp stp mrp llc bonding dm_mirror dm_region_hash
dm_log iTCO_wdt iTCO_vendor_support intel_powerclamp coretemp intel_rapl
kvm_intel kvm
[19839335.795640] crc32_pclmul dm_mod ghash_clmulni_intel aesni_intel lrw
gf128mul glue_helper ablk_helper cryptd pcspkr ses ipmi_ssif enclosure sg
sb_edac edac_core lpc_ich mei_me i2c_i801 mfd_core mei ioatdma shpchp wmi
ipmi_si ipmi_msghandler acpi_power_meter acpi_pad nfsd auth_rpcgss nfs_acl
lockd grace sunrpc xfs libcrc32c sd_mod crc_t10dif crct10dif_generic
syscopyarea sysfillrect sysimgblt crct10dif_pclmul crct10dif_common
crc32c_intel drm_kms_helper ttm ixgbe drm igb mdio ptp mpt3sas pps_core
i2c_algo_bit raid_class dca i2c_core scsi_transport_sas [last unloaded:
ip_tables][19839335.797216] CPU: 1 PID: 2912 Comm: drbd_w_drbd1 Tainted: G
OE ------------ 3.10.0-327.el7.x86_64 #1
[19839335.797550] Hardware name: Inspur NF5280M4/YZMB-00326-101, BIOS 4.0.18
11/09/2015
[19839335.797877] task: ffff885f749b9700 ti: ffff882f62fc4000 task.ti:
ffff882f62fc4000
[19839335.798203] RIP: 0010:[<ffffffff8106a908>] [<ffffffff8106a908>]
_begin+0x28/0x187
[19839335.798532] RSP: 0018:ffff882f62fc75f8 EFLAGS: 00010202
[19839335.798702] RAX: 000000002fced277 RBX: 00000000e9cee1cc RCX:
00000000a73b8733
[19839335.799030] RDX: 00000000b573ac7c RSI: 00000000bb6b5097 RDI:
00000000da4f4b14
[19839335.799356] RBP: 0000000058444804 R08: ffffffff81656100 R09:
ffff882f33147998
[19839335.799680] R10: ffff88007bd4ef80 R11: ffff88007bd4f040 R12:
00000000e770e674
[19839335.800010] R13: ffff88007bd4efc0 R14: ffff882f62fc75f8 R15:
ffff882f62fc7898
[19839335.800336] FS: 0000000000000000(0000) GS:ffff882fbf840000(0000)
knlGS:0000000000000000
[19839335.800664] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[19839335.800835] CR2: ffff88007bd4f000 CR3: 000000000194a000 CR4:
00000000001427e0
[19839335.801160] DR0: 0000000000000000 DR1: 0000000000000000 DR2:
0000000000000000
[19839335.801486] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7:
0000000000000400
[19839335.801812] Stack:
[19839335.801974] 5a8279995a827999 5a8279995a827999 5a8279995a827999
5a8279995a827999
[19839335.802317] 5a8279995a827999 5a8279995a827999 5a8279995a827999
5a8279995a827999
[19839335.802663] 5a8279995a827999 5a8279995a827999 5a8279995a827999
5a8279995a827999
[19839335.803005] Call Trace:
[19839335.803180] [<ffffffff81569a41>] ? ip_local_out_sk+0x31/0x40
[19839335.803355] [<ffffffff8106a31d>] ?
sha1_apply_transform_avx2+0x1d/0x30
[19839335.803530] [<ffffffff8106a063>] ? __sha1_ssse3_update+0x53/0xd0
[19839335.803704] [<ffffffff8106a388>] ? sha1_ssse3_update+0x58/0xf0
[19839335.803881] [<ffffffff812b1878>] ? crypto_shash_update+0x38/0x100
[19839335.804056] [<ffffffff812b1d6e>] ? shash_compat_update+0x4e/0x80
[19839335.804242] [<ffffffffa05245ab>] ? drbd_csum_bio+0x9b/0xe0 [drbd]
[19839335.804427] [<ffffffffa0546701>] ? drbd_send_dblock+0x3b1/0x480
[drbd]
[19839335.804608] [<ffffffffa0522a80>] ? dequeue_work_batch+0x20/0x90
[drbd]
[19839335.804788] [<ffffffffa0522d37>] ? wait_for_work+0x67/0x370 [drbd]
[19839335.804969] [<ffffffffa052726f>] ? w_send_dblock+0xaf/0x1d0 [drbd]
[19839335.805168] [<ffffffffa052867b>] ? drbd_worker+0xfb/0x390 [drbd]
[19839335.805349] [<ffffffffa0542430>] ?
drbd_destroy_connection+0x160/0x160 [drbd]
[19839335.805684] [<ffffffffa054244d>] ? drbd_thread_setup+0x1d/0x110
[drbd]
[19839335.805864] [<ffffffffa0542430>] ?
drbd_destroy_connection+0x160/0x160 [drbd]
[19839335.806195] [<ffffffff810a5aef>] ? kthread+0xcf/0xe0
[19839335.806367] [<ffffffff810a5a20>] ? kthread_create_on_node+0x140/0x140
[19839335.806545] [<ffffffff81645858>] ? ret_from_fork+0x58/0x90
[19839335.806717] [<ffffffff810a5a20>] ? kthread_create_on_node+0x140/0x140
[19839335.806889] Code: 00 00 00 89 f3 c4 e3 7b f0 f6 02 c4 e2 60 f2 e8 21
fb 31 eb 41 03 17 c4 e2 70 f2 ef 8d 14 1a c4 63 7b f0 e1 1b c4 e3 7b f0 d9
02 <c4> c1 7a 6f 82 80 00 00 00 21 f1 31 e9 42 8d 14 22 41 03 47 04
[19839335.807640] RIP [<ffffffff8106a908>] _begin+0x28/0x187
[19839335.807814] RSP <ffff882f62fc75f8>
[19839335.807979] CR2: ffff88007bd4f000
We debug it by using crash:
crash> bt
PID: 2912 TASK: ffff885f749b9700 CPU: 1 COMMAND: "drbd_w_drbd1"
#0 [ffff882f62fc72c0] machine_kexec at ffffffff81051beb
#1 [ffff882f62fc7320] crash_kexec at ffffffff810f2542
#2 [ffff882f62fc73f0] oops_end at ffffffff8163e1a8
#3 [ffff882f62fc7418] no_context at ffffffff8162e2b8
#4 [ffff882f62fc7468] __bad_area_nosemaphore at ffffffff8162e34e
#5 [ffff882f62fc74b0] bad_area_nosemaphore at ffffffff8162e4b8
#6 [ffff882f62fc74c0] __do_page_fault at ffffffff81640fce
#7 [ffff882f62fc7518] do_page_fault at ffffffff81641113
#8 [ffff882f62fc7540] page_fault at ffffffff8163d408
[exception RIP: _begin+40]
RIP: ffffffff8106a908 RSP: ffff882f62fc75f8 RFLAGS: 00010202
RAX: 000000002fced277 RBX: 00000000e9cee1cc RCX: 00000000a73b8733
RDX: 00000000b573ac7c RSI: 00000000bb6b5097 RDI: 00000000da4f4b14
RBP: 0000000058444804 R8: ffffffff81656100 R9: ffff882f33147998
R10: ffff88007bd4ef80 R11: ffff88007bd4f040 R12: 00000000e770e674
R13: ffff88007bd4efc0 R14: ffff882f62fc75f8 R15: ffff882f62fc7898
ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
#9 [ffff882f62fc7878] ip_local_out_sk at ffffffff81569a41
#10 [ffff882f62fc7ba8] sha1_apply_transform_avx2 at ffffffff8106a31d
#11 [ffff882f62fc7bb8] __sha1_ssse3_update at ffffffff8106a063
#12 [ffff882f62fc7bf8] sha1_ssse3_update at ffffffff8106a388
#13 [ffff882f62fc7c28] crypto_shash_update at ffffffff812b1878
#14 [ffff882f62fc7c78] shash_compat_update at ffffffff812b1d6e
#15 [ffff882f62fc7cc8] drbd_csum_bio at ffffffffa05245ab [drbd]
#16 [ffff882f62fc7d28] drbd_send_dblock at ffffffffa0546701 [drbd]
#17 [ffff882f62fc7de0] w_send_dblock at ffffffffa052726f [drbd]
#18 [ffff882f62fc7e28] drbd_worker at ffffffffa052867b [drbd]
#19 [ffff882f62fc7e98] drbd_thread_setup at ffffffffa054244d [drbd]
#20 [ffff882f62fc7ec8] kthread at ffffffff810a5aef
#21 [ffff882f62fc7f50] ret_from_fork at ffffffff81645858
crash> dis -l ffffffff8106a908
/usr/src/debug/kernel-3.10.0-327.el7/linux-3.10.0-327.el7.x86_64/arch/x86/cr
ypto/sha1_avx2_x86_64_asm.S: 677
0xffffffff8106a908 <_begin+40>: vmovdqu 0x80(%r10),%xmm0
crash> dis -l _begin
/usr/src/debug/kernel-3.10.0-327.el7/linux-3.10.0-327.el7.x86_64/arch/x86/cr
ypto/sha1_avx2_x86_64_asm.S: 677
0xffffffff8106a8e0 <_begin>: mov %esi,%ebx
0xffffffff8106a8e2 <_begin+2>: rorx $0x2,%esi,%esi
0xffffffff8106a8e8 <_begin+8>: andn %eax,%ebx,%ebp
0xffffffff8106a8ed <_begin+13>: and %edi,%ebx
0xffffffff8106a8ef <_begin+15>: xor %ebp,%ebx
0xffffffff8106a8f1 <_begin+17>: add (%r15),%edx
0xffffffff8106a8f4 <_begin+20>: andn %edi,%ecx,%ebp
0xffffffff8106a8f9 <_begin+25>: lea (%rdx,%rbx,1),%edx
0xffffffff8106a8fc <_begin+28>: rorx $0x1b,%ecx,%r12d
0xffffffff8106a902 <_begin+34>: rorx $0x2,%ecx,%ebx
0xffffffff8106a908 <_begin+40>: vmovdqu 0x80(%r10),%xmm0
<--------------- crash here
0xffffffff8106a911 <_begin+49>: and %esi,%ecx
0xffffffff8106a913 <_begin+51>: xor %ebp,%ecx
0xffffffff8106a915 <_begin+53>: lea (%rdx,%r12,1),%edx
0xffffffff8106a919 <_begin+57>: add 0x4(%r15),%eax
0xffffffff8106a91d <_begin+61>: andn %esi,%edx,%ebp
0xffffffff8106a922 <_begin+66>: lea (%rax,%rcx,1),%eax
0xffffffff8106a925 <_begin+69>: rorx $0x1b,%edx,%r12d
0xffffffff8106a92b <_begin+75>: rorx $0x2,%edx,%ecx
0xffffffff8106a931 <_begin+81>: vinsertf128 $0x1,0x80(%r13),%ymm0,%ymm0
0xffffffff8106a93b <_begin+91>: and %ebx,%edx
0xffffffff8106a93d <_begin+93>: xor %ebp,%edx
0xffffffff8106a93f <_begin+95>: lea (%rax,%r12,1),%eax
0xffffffff8106a943 <_begin+99>: add 0x8(%r15),%edi
It crashed at arch/x86/crypto/sha1_avx2_x86_64_asm.S, and according to the
stack trace, I deduced some useful information:
crash> struct -x sha1_state 0xffff882f33147990
struct sha1_state {
count = 0x4e000,
state = {0xa73b8733, 0xedad425e, 0xda4f4b14, 0x2fced277, 0x90a160ae},
buffer =
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00
0\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00
0\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00
0\000\000\000\000\000\000"
}
crash> rd ffff882f62fc7c78 24
ffff882f62fc7c78: ffffffff812b1d6e ffff88007bd4e000 n.+........{....
ffff882f62fc7c88: 0000000000000000 ffffea0001ef5380 .........S......
ffff882f62fc7c98: 0000000000000000 ffff882f62fc7ce0 .........|.b/...
ffff882f62fc7ca8: ffffffff00000000 00000000f6275b17 .........['.....
ffff882f62fc7cb8: 000000000000004e ffff882f62fc7d20 N....... }.b/...
ffff882f62fc7cc8: ffffffffa05245ab ffff885f66044120 .ER..... A.f_...
ffff882f62fc7cd8: ffff882f00000000 ffffea0001ef5382 ..../....S......
ffff882f62fc7ce8: 0000100000000000 0000000000000000 ................
ffff882f62fc7cf8: 0000000000000000 00000000f6275b17 .........['.....
ffff882f62fc7d08: ffff882f73c0a000 ffff880111b94540 ...s/...@E......
ffff882f62fc7d18: ffff882f6aff0010 ffff882f62fc7dd8 ...j/....}.b/...
ffff882f62fc7d28: ffffffffa0546701 0000000000000000 .gT.............
crash>
crash> struct hash_desc ffff882f62fc7cd0
struct hash_desc {
tfm = 0xffff885f66044120,
flags = 0
}
crash> struct scatterlist ffff882f62fc7ce0
struct scatterlist {
page_link = 18446719884486202242,
offset = 0,
length = 4096,
dma_address = 0,
dma_length = 0
}
crash> rd ffff882f62fc7c28 22
ffff882f62fc7c28: ffffffff812b1878 ffff882f33147980 x.+......y.3/...
ffff882f62fc7c38: ffff882f6aff0028 ffff882ae84cd500 (..j/.....L.*...
ffff882f62fc7c48: ffff882f33147980 ffff882f6aff0028 .y.3/...(..j/...
ffff882f62fc7c58: ffff882ae84cd500 ffff882f70846800 ..L.*....h.p/...
ffff882f62fc7c68: ffff885f738a12a0 ffff882f62fc7cc0 ...s_....|.b/...
ffff882f62fc7c78: ffffffff812b1d6e ffff88007bd4e000 n.+........{....
ffff882f62fc7c88: 0000000000000000 ffffea0001ef5380 .........S......
ffff882f62fc7c98: 0000000000000000 ffff882f62fc7ce0 .........|.b/...
ffff882f62fc7ca8: ffffffff00000000 00000000f6275b17 .........['.....
ffff882f62fc7cb8: 000000000000004e ffff882f62fc7d20 N....... }.b/...
ffff882f62fc7cc8: ffffffffa05245ab ffff885f66044120 .ER..... A.f_...
crash>
crash>
crash>
crash> struct crypto_hash_walk ffff882f62fc7c80
struct crypto_hash_walk {
data = 0xffff88007bd4e000 struct: page excluded: kernel virtual address:
ffff88007bd4e000 type: "gdb_readmem_callback"
struct: page excluded: kernel virtual address: ffff88007bd4e000 type:
"gdb_readmem_callback"
<Address 0xffff88007bd4e000 out of bounds>,
offset = 0,
alignmask = 0,
pg = 0xffffea0001ef5380,
entrylen = 0,
total = 0,
sg = 0xffff882f62fc7ce0,
flags = 0
}
According to the above information, after call shash_compat_update and, we
got one page sized 4k after kmap, which started at virtual address
0xffff88007bd4e000.
So, the value pass to void sha1_transform_avx2(int *hash, const char* data,
size_t num_blocks ); data = 0xffff88007bd4e000, rounds = 64, which means we
have 64 blocks(4k) to handle.
But the BUFFER_END we calculated out in sha1_avx2_x86_64_asm.S is rounds <<6
+ data + 64 = 64 <<6 + 0xffff88007bd4e000 + 64 = 0xffff88007bd4f040 which
exceed one page.
I think maybe it is the reason why we got the "BUG: unable to handle kernel
paging request at ffff88007bd4f000".
I am not so familiar with the sha1 algorithm, so I email you for your kindly
help, can you give me some suggestion on this issue?
Sincerely
Zhuoyu
^ permalink raw reply
* [PATCH v2] siphash: add cryptographically secure hashtable function
From: Jason A. Donenfeld @ 2016-12-12 3:48 UTC (permalink / raw)
To: kernel-hardening, LKML, linux-crypto, Linus Torvalds,
George Spelvin, Scott Bauer, ak, Andy Lutomirski, Greg KH
Cc: Jason A. Donenfeld, Jean-Philippe Aumasson, Daniel J . Bernstein
In-Reply-To: <20161211204345.GA1558@kroah.com>
SipHash is a 64-bit keyed hash function that is actually a
cryptographically secure PRF, like HMAC. Except SipHash is super fast,
and is meant to be used as a hashtable keyed lookup function.
SipHash isn't just some new trendy hash function. It's been around for a
while, and there really isn't anything that comes remotely close to
being useful in the way SipHash is. With that said, why do we need this?
There are a variety of attacks known as "hashtable poisoning" in which an
attacker forms some data such that the hash of that data will be the
same, and then preceeds to fill up all entries of a hashbucket. This is
a realistic and well-known denial-of-service vector.
Linux developers already seem to be aware that this is an issue, and
various places that use hash tables in, say, a network context, use a
non-cryptographically secure function (usually jhash) and then try to
twiddle with the key on a time basis (or in many cases just do nothing
and hope that nobody notices). While this is an admirable attempt at
solving the problem, it doesn't actually fix it. SipHash fixes it.
(It fixes it in such a sound way that you could even build a stream
cipher out of SipHash that would resist the modern cryptanalysis.)
There are a modicum of places in the kernel that are vulnerable to
hashtable poisoning attacks, either via userspace vectors or network
vectors, and there's not a reliable mechanism inside the kernel at the
moment to fix it. The first step toward fixing these issues is actually
getting a secure primitive into the kernel for developers to use. Then
we can, bit by bit, port things over to it as deemed appropriate.
Dozens of languages are already using this internally for their hash
tables. Some of the BSDs already use this in their kernels. SipHash is
a widely known high-speed solution to a widely known problem, and it's
time we catch-up.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Cc: Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com>
Cc: Daniel J. Bernstein <djb@cr.yp.to>
---
include/linux/siphash.h | 20 +++++++++
lib/Makefile | 5 ++-
lib/siphash.c | 72 ++++++++++++++++++++++++++++++
lib/test_siphash.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 211 insertions(+), 2 deletions(-)
create mode 100644 include/linux/siphash.h
create mode 100644 lib/siphash.c
create mode 100644 lib/test_siphash.c
diff --git a/include/linux/siphash.h b/include/linux/siphash.h
new file mode 100644
index 000000000000..6623b3090645
--- /dev/null
+++ b/include/linux/siphash.h
@@ -0,0 +1,20 @@
+/* Copyright (C) 2016 Jason A. Donenfeld <Jason@zx2c4.com>
+ *
+ * This file is provided under a dual BSD/GPLv2 license.
+ *
+ * SipHash: a fast short-input PRF
+ * https://131002.net/siphash/
+ */
+
+#ifndef _LINUX_SIPHASH_H
+#define _LINUX_SIPHASH_H
+
+#include <linux/types.h>
+
+enum siphash_lengths {
+ SIPHASH24_KEY_LEN = 16
+};
+
+u64 siphash24(const u8 *data, size_t len, const u8 key[SIPHASH24_KEY_LEN]);
+
+#endif /* _LINUX_SIPHASH_H */
diff --git a/lib/Makefile b/lib/Makefile
index 50144a3aeebd..71d398b04a74 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -22,7 +22,8 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
sha1.o chacha20.o md5.o irq_regs.o argv_split.o \
flex_proportions.o ratelimit.o show_mem.o \
is_single_threaded.o plist.o decompress.o kobject_uevent.o \
- earlycpio.o seq_buf.o nmi_backtrace.o nodemask.o win_minmax.o
+ earlycpio.o seq_buf.o siphash.o \
+ nmi_backtrace.o nodemask.o win_minmax.o
lib-$(CONFIG_MMU) += ioremap.o
lib-$(CONFIG_SMP) += cpumask.o
@@ -44,7 +45,7 @@ obj-$(CONFIG_TEST_HEXDUMP) += test_hexdump.o
obj-y += kstrtox.o
obj-$(CONFIG_TEST_BPF) += test_bpf.o
obj-$(CONFIG_TEST_FIRMWARE) += test_firmware.o
-obj-$(CONFIG_TEST_HASH) += test_hash.o
+obj-$(CONFIG_TEST_HASH) += test_hash.o test_siphash.o
obj-$(CONFIG_TEST_KASAN) += test_kasan.o
obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o
obj-$(CONFIG_TEST_LKM) += test_module.o
diff --git a/lib/siphash.c b/lib/siphash.c
new file mode 100644
index 000000000000..e78dc36d19b9
--- /dev/null
+++ b/lib/siphash.c
@@ -0,0 +1,72 @@
+/* Copyright (C) 2015-2016 Jason A. Donenfeld <Jason@zx2c4.com>
+ * Copyright (C) 2012-2014 Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com>
+ * Copyright (C) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
+ *
+ * This file is provided under a dual BSD/GPLv2 license.
+ *
+ * SipHash: a fast short-input PRF
+ * https://131002.net/siphash/
+ */
+
+#include <linux/siphash.h>
+#include <linux/kernel.h>
+
+static inline u64 le64_to_cpuvp(const void *p)
+{
+ return le64_to_cpup(p);
+}
+
+#define SIPROUND \
+ do { \
+ v0 += v1; v1 = rol64(v1, 13); v1 ^= v0; v0 = rol64(v0, 32); \
+ v2 += v3; v3 = rol64(v3, 16); v3 ^= v2; \
+ v0 += v3; v3 = rol64(v3, 21); v3 ^= v0; \
+ v2 += v1; v1 = rol64(v1, 17); v1 ^= v2; v2 = rol64(v2, 32); \
+ } while(0)
+
+u64 siphash24(const u8 *data, size_t len, const u8 key[SIPHASH24_KEY_LEN])
+{
+ u64 v0 = 0x736f6d6570736575ULL;
+ u64 v1 = 0x646f72616e646f6dULL;
+ u64 v2 = 0x6c7967656e657261ULL;
+ u64 v3 = 0x7465646279746573ULL;
+ u64 b = ((u64)len) << 56;
+ u64 k0 = le64_to_cpuvp(key);
+ u64 k1 = le64_to_cpuvp(key + sizeof(u64));
+ u64 m;
+ const u8 *end = data + len - (len % sizeof(u64));
+ const u8 left = len & (sizeof(u64) - 1);
+ v3 ^= k1;
+ v2 ^= k0;
+ v1 ^= k1;
+ v0 ^= k0;
+ for (; data != end; data += sizeof(u64)) {
+ m = le64_to_cpuvp(data);
+ v3 ^= m;
+ SIPROUND;
+ SIPROUND;
+ v0 ^= m;
+ }
+ switch (left) {
+ case 7: b |= ((u64)data[6]) << 48;
+ case 6: b |= ((u64)data[5]) << 40;
+ case 5: b |= ((u64)data[4]) << 32;
+ case 4: b |= ((u64)data[3]) << 24;
+ case 3: b |= ((u64)data[2]) << 16;
+ case 2: b |= ((u64)data[1]) << 8;
+ case 1: b |= ((u64)data[0]); break;
+ case 0: break;
+ }
+ v3 ^= b;
+ SIPROUND;
+ SIPROUND;
+ v0 ^= b;
+ v2 ^= 0xff;
+ SIPROUND;
+ SIPROUND;
+ SIPROUND;
+ SIPROUND;
+ b = (v0 ^ v1) ^ (v2 ^ v3);
+ return (__force u64)cpu_to_le64(b);
+}
+EXPORT_SYMBOL(siphash24);
diff --git a/lib/test_siphash.c b/lib/test_siphash.c
new file mode 100644
index 000000000000..45b5435540e9
--- /dev/null
+++ b/lib/test_siphash.c
@@ -0,0 +1,116 @@
+/* Test cases for siphash.c
+ *
+ * Copyright (C) 2015-2016 Jason A. Donenfeld <Jason@zx2c4.com>
+ *
+ * This file is provided under a dual BSD/GPLv2 license.
+ *
+ * SipHash: a fast short-input PRF
+ * https://131002.net/siphash/
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/siphash.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+
+static const u8 test_vectors[64][8] = {
+ { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72 },
+ { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74 },
+ { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d },
+ { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85 },
+ { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf },
+ { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18 },
+ { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb },
+ { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab },
+ { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93 },
+ { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e },
+ { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a },
+ { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4 },
+ { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75 },
+ { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14 },
+ { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7 },
+ { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1 },
+ { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f },
+ { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69 },
+ { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b },
+ { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb },
+ { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe },
+ { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0 },
+ { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93 },
+ { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8 },
+ { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8 },
+ { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc },
+ { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17 },
+ { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f },
+ { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde },
+ { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6 },
+ { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad },
+ { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32 },
+ { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71 },
+ { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7 },
+ { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12 },
+ { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15 },
+ { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31 },
+ { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02 },
+ { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca },
+ { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a },
+ { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e },
+ { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad },
+ { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18 },
+ { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4 },
+ { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9 },
+ { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9 },
+ { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb },
+ { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0 },
+ { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6 },
+ { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7 },
+ { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee },
+ { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1 },
+ { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a },
+ { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81 },
+ { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f },
+ { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24 },
+ { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7 },
+ { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea },
+ { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60 },
+ { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66 },
+ { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c },
+ { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f },
+ { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5 },
+ { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95 }
+};
+
+static int __init siphash_test_init(void)
+{
+ u8 in[64], k[16], i;
+ u64 out;
+ int ret = 0;
+
+ for (i = 0; i < 16; ++i)
+ k[i] = i;
+
+ for (i = 0; i < 64; ++i) {
+ in[i] = i;
+ out = siphash24(in, i, k);
+ if (memcmp(&out, test_vectors[i], 8)) {
+ pr_info("self-test %u: FAIL\n", i + 1);
+ ret = -EINVAL;
+ }
+ }
+ if (!ret)
+ pr_info("self-tests: pass\n");
+ return ret;
+}
+
+static void __exit siphash_test_exit(void)
+{
+}
+
+module_init(siphash_test_init);
+module_exit(siphash_test_exit);
+
+MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>");
+MODULE_LICENSE("Dual BSD/GPL");
--
2.11.0
^ permalink raw reply related
* Re: [PATCH v2] siphash: add cryptographically secure hashtable function
From: Linus Torvalds @ 2016-12-12 4:01 UTC (permalink / raw)
To: Jason A. Donenfeld
Cc: kernel-hardening@lists.openwall.com, LKML,
Linux Crypto Mailing List, George Spelvin, Scott Bauer,
Andi Kleen, Andy Lutomirski, Greg KH, Jean-Philippe Aumasson,
Daniel J . Bernstein
In-Reply-To: <20161212034817.1773-1-Jason@zx2c4.com>
On Sun, Dec 11, 2016 at 7:48 PM, Jason A. Donenfeld <Jason@zx2c4.com> wrote:
> + switch (left) {
> + case 7: b |= ((u64)data[6]) << 48;
> + case 6: b |= ((u64)data[5]) << 40;
> + case 5: b |= ((u64)data[4]) << 32;
> + case 4: b |= ((u64)data[3]) << 24;
> + case 3: b |= ((u64)data[2]) << 16;
> + case 2: b |= ((u64)data[1]) << 8;
> + case 1: b |= ((u64)data[0]); break;
> + case 0: break;
> + }
The above is extremely inefficient. Considering that most kernel data
would be expected to be smallish, that matters (ie the usual benchmark
would not be about hashing megabytes of data, but instead millions of
hashes of small data).
I think this could be rewritten (at least for 64-bit architectures) as
#ifdef CONFIG_DCACHE_WORD_ACCESS
if (left)
b |= le64_to_cpu(load_unaligned_zeropad(data) &
bytemask_from_count(left));
#else
.. do the duff's device thing with the switch() ..
#endif
which should give you basically perfect code generation (ie a single
64-bit load and a byte mask).
Totally untested, just looking at the code and trying to make sense of it.
... and obviously, it requires an actual high-performance use-case to
make any difference.
Linus
^ permalink raw reply
* Re: [PATCH v2] siphash: add cryptographically secure hashtable function
From: Eric Biggers @ 2016-12-12 5:42 UTC (permalink / raw)
To: Jason A. Donenfeld
Cc: kernel-hardening, LKML, linux-crypto, Linus Torvalds,
George Spelvin, Scott Bauer, ak, Andy Lutomirski, Greg KH,
Jean-Philippe Aumasson, Daniel J . Bernstein
In-Reply-To: <20161212034817.1773-1-Jason@zx2c4.com>
On Mon, Dec 12, 2016 at 04:48:17AM +0100, Jason A. Donenfeld wrote:
>
> diff --git a/lib/Makefile b/lib/Makefile
> index 50144a3aeebd..71d398b04a74 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -22,7 +22,8 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
> sha1.o chacha20.o md5.o irq_regs.o argv_split.o \
> flex_proportions.o ratelimit.o show_mem.o \
> is_single_threaded.o plist.o decompress.o kobject_uevent.o \
> - earlycpio.o seq_buf.o nmi_backtrace.o nodemask.o win_minmax.o
> + earlycpio.o seq_buf.o siphash.o \
> + nmi_backtrace.o nodemask.o win_minmax.o
>
> lib-$(CONFIG_MMU) += ioremap.o
> lib-$(CONFIG_SMP) += cpumask.o
> @@ -44,7 +45,7 @@ obj-$(CONFIG_TEST_HEXDUMP) += test_hexdump.o
> obj-y += kstrtox.o
> obj-$(CONFIG_TEST_BPF) += test_bpf.o
> obj-$(CONFIG_TEST_FIRMWARE) += test_firmware.o
> -obj-$(CONFIG_TEST_HASH) += test_hash.o
> +obj-$(CONFIG_TEST_HASH) += test_hash.o test_siphash.o
Maybe add to the help text for CONFIG_TEST_HASH that it now tests siphash too?
> +static inline u64 le64_to_cpuvp(const void *p)
> +{
> + return le64_to_cpup(p);
> +}
This assumes the key and message buffers are aligned to __alignof__(u64).
Unless that's going to be a clearly documented requirement for callers, you
should use get_unaligned_le64() instead. And you can pass a 'u8 *' directly to
get_unaligned_le64(), no need for a helper function.
> + b = (v0 ^ v1) ^ (v2 ^ v3);
> + return (__force u64)cpu_to_le64(b);
> +}
It makes sense for this to return a u64, but that means the cpu_to_le64() is
wrong, since u64 indicates CPU endianness. It should just return 'b'.
> +++ b/lib/test_siphash.c
> @@ -0,0 +1,116 @@
> +/* Test cases for siphash.c
> + *
> + * Copyright (C) 2015-2016 Jason A. Donenfeld <Jason@zx2c4.com>
> + *
> + * This file is provided under a dual BSD/GPLv2 license.
> + *
> + * SipHash: a fast short-input PRF
> + * https://131002.net/siphash/
> + */
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> +#include <linux/siphash.h>
> +#include <linux/kernel.h>
> +#include <linux/string.h>
> +#include <linux/errno.h>
> +#include <linux/module.h>
> +
> +static const u8 test_vectors[64][8] = {
> + { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72 },
Can you mention in a comment where the test vectors came from?
> + if (memcmp(&out, test_vectors[i], 8)) {
> + pr_info("self-test %u: FAIL\n", i + 1);
> + ret = -EINVAL;
> + }
If you make the output really be CPU-endian like I'm suggesting then this will
need to be something like:
if (out != get_unaligned_le64(test_vectors[i])) {
Or else make the test vectors be an array of u64.
- Eric
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox