Re: [PATCH] crypto: stm32: use of_device_get_match_data

2017-10-06 Thread Herbert Xu
On Wed, Sep 20, 2017 at 08:31:40PM +0200, Corentin Labbe wrote:
> The usage of of_device_get_match_data reduce the code size a bit.
> Furthermore, it prevents an improbable dereference when
> of_match_device() return NULL.
> 
> Signed-off-by: Corentin Labbe 

Patch applied.  Thanks.
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [PATCH] crypto: bcm: use of_device_get_match_data

2017-10-06 Thread Herbert Xu
On Wed, Sep 20, 2017 at 08:47:26PM +0200, Corentin Labbe wrote:
> The usage of of_device_get_match_data reduce the code size a bit.
> Furthermore, it prevents an improbable dereference when
> of_match_device() return NULL.
> 
> Signed-off-by: Corentin Labbe 

Patch applied.  Thanks.
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [PATCH] crypto: omap: use of_device_get_match_data

2017-10-06 Thread Herbert Xu
On Wed, Sep 20, 2017 at 08:42:48PM +0200, Corentin Labbe wrote:
> The usage of of_device_get_match_data reduce the code size a bit.
> Furthermore, it prevents an improbable dereference when
> of_match_device() return NULL.
> 
> Signed-off-by: Corentin Labbe 

Patch applied.  Thanks.
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [PATCH] crypto: algboss: remove redundant setting of len to zero

2017-10-06 Thread Herbert Xu
On Thu, Sep 14, 2017 at 07:02:19PM +0100, Colin King wrote:
> From: Colin Ian King 
> 
> The variable len is set to zero, never read and then later updated
> to p - name, so clearly the zero'ing of len is redundant and
> can be removed.
> 
> Detected by clang scan-build:
> " warning: Value stored to 'len' is never read"
> 
> Signed-off-by: Colin Ian King 

Patch applied.  Thanks.
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [PATCH 02/10] drivers:crypto: return -ENOMEM on allocation failure.

2017-10-06 Thread Herbert Xu
Allen Pais  wrote:
> Signed-off-by: Allen Pais 

Patch applied.  Thanks.
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [PATCH 1/2] crypto: stm32 - Fix uninitialized data usage

2017-10-06 Thread Herbert Xu
On Tue, Sep 12, 2017 at 11:35:38AM +0200, Arnd Bergmann wrote:
> The error handling in stm32_hash_irq_thread passes
> uninitialized data into stm32_hash_finish_req, as gcc
> points out:
> 
> drivers/crypto/stm32/stm32-hash.c: In function 'stm32_hash_irq_thread':
> drivers/crypto/stm32/stm32-hash.c:1088:2: error: 'err' may be used 
> uninitialized in this function [-Werror=maybe-uninitialized]
> 
> I could not tell what data should be passed there instead,
> so this changes the code to always pass zero, making it
> well-defined, though possibly still wrong. Please check.
> 
> Signed-off-by: Arnd Bergmann 

This is already fixed in cryptodev.
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [PATCH 2/2] crypto: stm32 - Try to fix hash padding

2017-10-06 Thread Herbert Xu
On Tue, Sep 12, 2017 at 11:35:39AM +0200, Arnd Bergmann wrote:
> gcc warns that the length for the extra unaligned data in the hash
> function may be used unaligned. In theory this could happen if
> we pass a zero-length sg_list, or if sg_is_last() was never true:
> 
> In file included from drivers/crypto/stm32/stm32-hash.c:23:
> drivers/crypto/stm32/stm32-hash.c: In function 'stm32_hash_one_request':
> include/uapi/linux/kernel.h:12:49: error: 'ncp' may be used uninitialized in 
> this function [-Werror=maybe-uninitialized]
>  #define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
> 
> Neither of these can happen in practice, so the warning is harmless.
> 
> However while trying to suppress the warning, I noticed multiple
> problems with that code:
> 
> - On big-endian kernels, we byte-swap the data like we do for
>   register accesses, however this is a data stream and almost
>   certainly needs to use a single writesl() instead of series
>   of writel() to give the correct hash.
> 
> - If the length is not a multiple of four bytes, we skip the
>   last word entirely, since we write the truncated length
>   using stm32_hash_set_nblw().
> 
> - If we change the code to round the length up rather than
>   down, the last bytes contain stale data, so it needs some
>   form of padding.
> 
> This tries to address all four problems, by correctly
> initializing the length to zero, using endian-safe copy
> functions, adding zero-padding and passing the padded length.
> 
> I have done no testing on this patch, so please review
> carefully and if possible test with an unaligned length
> and big-endian kernel builds.
> 
> Fixes: 8a1012d3f2ab ("crypto: stm32 - Support for STM32 HASH module")
> Signed-off-by: Arnd Bergmann 

Patch applied.  Thanks.
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [PATCH] crc32-pclmul: remove useless relative addressing

2017-10-06 Thread Herbert Xu
On Wed, Sep 06, 2017 at 10:41:21PM -0400, Mikulas Patocka wrote:
> In 32-bit mode, the x86 architecture can hold full 32-bit pointers.
> Therefore, the code that copies the current address to the %ecx register
> and uses %ecx-relative addressing is useless, we could just use absolute
> addressing.
> 
> The processors have a stack of return addresses for branch prediction. If 
> we use a call instruction and pop the return address, it desynchronizes 
> the return stack and causes branch prediction misses.
> 
> This patch also moves the data to the .rodata section.
> 
> Signed-off-by: Mikulas Patocka 

Patch applied.  Thanks.
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [PATCH] crypto: xts - Fix an error handling path in 'create()'

2017-10-06 Thread Herbert Xu
On Tue, Sep 26, 2017 at 08:17:44AM +0200, Christophe JAILLET wrote:
> All error handling paths 'goto err_drop_spawn' except this one.
> In order to avoid some resources leak, we should do it as well here.
> 
> Fixes: f1c131b45410 ("crypto: xts - Convert to skcipher")
> Signed-off-by: Christophe JAILLET 

Patch applied.  Thanks.
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [PATCH] crypto: ccp - unmap pages and remove unmap objects in callback

2017-10-06 Thread Herbert Xu
On Tue, Sep 05, 2017 at 05:01:51PM -0500, Gary R Hook wrote:
> From: amd 
> 
> Clean up the mapped pages and the unmap object once we are done with
> it. This enables the final clean-up of the object once the transfer
> is complete.
> 
> Signed-off-by: Gary R Hook 

Patch applied.  Thanks.
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [PATCH] crypto:ccp - invoke the DMA callback in a standard way

2017-10-06 Thread Herbert Xu
On Tue, Sep 05, 2017 at 05:08:14PM -0500, Gary R Hook wrote:
> From: amd 
> 
> Use the provided mechanism in dmaengine.h to invoke the
> completion callback.
> 
> Signed-off-by: Gary R Hook 

Patch applied.  Thanks.
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [PATCH 0/3] padata cpu awareness fixes

2017-10-06 Thread Herbert Xu
On Fri, Sep 08, 2017 at 08:57:08PM +0200, Mathias Krause wrote:
> Hi Steffen, Herbert,
> 
> this series solves multiple issues of padata I ran into while trying to
> make use of pcrypt for IPsec.
> 
> The first issue is that the reorder timer callback may run on a CPU that
> isn't part of the parallel set, as it runs on the CPU where the timer
> interrupt gets handled. As a result, padata_reorder() may run on a CPU
> with uninitialized per-cpu parallel queues, so the __this_cpu_read() in
> padata_get_next() refers to an uninitialized cpu_index. However, as
> per-cpu memory gets memset(0) on allocation time, it'll read 0. If the
> next CPU index we're waiting for is 0 too, the compare will succeed and
> we'll return with -ENODATA, making padata_reorder() think there's
> nothing to do, stop any pending timer and return immediately. This is
> wrong as the pending timer might have been the one to trigger the needed
> reordering, but, as it was canceled, will never happen -- if no other
> parallel requests arrive afterwards.
> 
> That issue is addressed with the first two patches, ensuring we're not
> using a bogus cpu_index value for the compare and thereby not wrongly
> cancel a pending timer. The second patch then ensures the reorder timer
> callback runs on the correct CPU or, at least, on a CPU from the
> parallel set to generate forward progress.
> 
> The third patch addresses a similar issues for the serialization
> callback. We implicitly require padata_do_serial() to be called on the
> very same CPU padata_do_parallel() was called on to ensure the correct
> ordering of requests -- and correct functioning of padata, even. If the
> algorithm we're parallelizing is asynchronous itself, that invariant
> might not be true, as, e.g. crypto hardware may execute the callback on
> the CPU its interrupt gets handled on which isn't necessarily the one
> the request got issued on.
> 
> To handle that issue we track the CPU we're supposed to handle the
> request on and ensure we'll call padata_reorder() on that CPU when
> padata_do_serial() gets called -- either by already running on the
> corect CPU or by deferring the call to a worker. 
> 
> Please apply!
> 
> Mathias Krause (3):
>   padata: set cpu_index of unused CPUs to -1
>   padata: ensure the reorder timer callback runs on the correct CPU
>   padata: ensure padata_do_serial() runs on the correct CPU

All applied.  Thanks.
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [RFC PATCH] crypto: make the seed() function optional

2017-10-06 Thread Herbert Xu
Mathieu Malaterre  wrote:
> This makes it simplier for driver author to not provide the seed() function
> in case of a pseudo RNG where the seed operation is a no-op.
> 
> Document that the seed() function pointer is optional in header.
> 
> Signed-off-by: Mathieu Malaterre 
> ---
> The PRNG as found on Ingenic JZ4780 is one such example. This is found on a
> MIPS Creator CI20 SoC.

So how does it seed itself? This also contradicts with the JZ4780
driver that's currently in the patch queue as it does contain a
seed function.

Cheers,
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [PATCH 1/2] crypto: skcipher - noop for enc/dec with NULL data

2017-10-06 Thread Herbert Xu
On Sat, Oct 07, 2017 at 05:21:38AM +0200, Stephan Müller wrote:
>
> The bug happens with the following invocation sequence:
> 
> setsockopt(3, SOL_ALG, 5, NULL, 1)  = -1 EBUSY (Device or resource busy)
> sendmsg(6, {msg_name=NULL, msg_namelen=0, msg_iov=NULL, msg_iovlen=0, 
> msg_control=[{cmsg_len=20, cmsg_level=SOL_ALG, cmsg_type=0x3}, {cmsg_len=40, 
> cmsg_level=SOL_ALG, cmsg_type=0x2}, {cmsg_len=20, cmsg_level=SOL_ALG, 
> cmsg_type=0x4}], msg_controllen=88, msg_flags=0}, MSG_MORE) = 0
> vmsplice(5, [{iov_base="V", iov_len=1}], 1, SPLICE_F_GIFT) = 1
> splice(4, NULL, 6, NULL, 1, 0)  = 1
> read(6,  )  = ?
> +++ killed by SIGKILL +++

I see the problem now.  This was introduced with the skcipher walk
interface.  The blkcipher walk interface didn't have this issue.

I guess we should add a zero test vector once this is fixed.

---8<---
Subject: crypto: skcipher - Fix crash on zero-length input

The skcipher walk interface doesn't handle zero-length input
properly as the old blkcipher walk interface did.  This is due
to the fact that the length check is done too late.

This patch moves the length check forward so that it does the
right thing.

Fixes: b286d8b1a690 ("crypto: skcipher - Add skcipher walk...")
Cc: 
Reported-by: Stephan Müller 
Signed-off-by: Herbert Xu 

diff --git a/crypto/skcipher.c b/crypto/skcipher.c
index 4faa0fd..d5692e3 100644
--- a/crypto/skcipher.c
+++ b/crypto/skcipher.c
@@ -426,14 +426,9 @@ static int skcipher_copy_iv(struct skcipher_walk *walk)
 
 static int skcipher_walk_first(struct skcipher_walk *walk)
 {
-   walk->nbytes = 0;
-
if (WARN_ON_ONCE(in_irq()))
return -EDEADLK;
 
-   if (unlikely(!walk->total))
-   return 0;
-
walk->buffer = NULL;
if (unlikely(((unsigned long)walk->iv & walk->alignmask))) {
int err = skcipher_copy_iv(walk);
@@ -452,10 +447,15 @@ static int skcipher_walk_skcipher(struct skcipher_walk 
*walk,
 {
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
 
+   walk->total = req->cryptlen;
+   walk->nbytes = 0;
+
+   if (unlikely(!walk->total))
+   return 0;
+
scatterwalk_start(>in, req->src);
scatterwalk_start(>out, req->dst);
 
-   walk->total = req->cryptlen;
walk->iv = req->iv;
walk->oiv = req->iv;
 
@@ -509,6 +509,11 @@ static int skcipher_walk_aead_common(struct skcipher_walk 
*walk,
struct crypto_aead *tfm = crypto_aead_reqtfm(req);
int err;
 
+   walk->nbytes = 0;
+
+   if (unlikely(!walk->total))
+   return 0;
+
walk->flags &= ~SKCIPHER_WALK_PHYS;
 
scatterwalk_start(>in, req->src);
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [PATCH 1/2] crypto: skcipher - noop for enc/dec with NULL data

2017-10-06 Thread Stephan Müller
Am Samstag, 7. Oktober 2017, 05:07:52 CEST schrieb Herbert Xu:

Hi Herbert,

> On Sat, Oct 07, 2017 at 04:53:46AM +0200, Stephan Müller wrote:
> > I use authenc(hmac(sha256),cbc(aes)) which in turn uses cbc-aes-aesni on
> > my
> > system.
> 
> So where exactly is it crashing in cbc-aes-aesni? AFAICS it should
> handle the zero case just fine.  Or is it hmac that's crashing as
> your other patch suggested?

The bug happens with the following invocation sequence:

setsockopt(3, SOL_ALG, 5, NULL, 1)  = -1 EBUSY (Device or resource busy)
sendmsg(6, {msg_name=NULL, msg_namelen=0, msg_iov=NULL, msg_iovlen=0, 
msg_control=[{cmsg_len=20, cmsg_level=SOL_ALG, cmsg_type=0x3}, {cmsg_len=40, 
cmsg_level=SOL_ALG, cmsg_type=0x2}, {cmsg_len=20, cmsg_level=SOL_ALG, 
cmsg_type=0x4}], msg_controllen=88, msg_flags=0}, MSG_MORE) = 0
vmsplice(5, [{iov_base="V", iov_len=1}], 1, SPLICE_F_GIFT) = 1
splice(4, NULL, 6, NULL, 1, 0)  = 1
read(6,  )  = ?
+++ killed by SIGKILL +++

The kernel reports the following crash:

[135385.003653] BUG: unable to handle kernel NULL pointer dereference at 
0010
[135385.004007] IP: skcipher_walk_skcipher+0x18/0xb0
[135385.004007] PGD 7bbf4067 P4D 7bbf4067 PUD 784a6067 PMD 0 
[135385.004007] Oops:  [#1] SMP
[135385.004007] Modules linked in: authenc algif_aead algif_rng algif_skcipher 
crypto_user algif_hash af_alg ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 
nf_conntrack_ipv6 nf_defrag_ipv6 nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack 
nf_conntrack ip_set nfnetlink ebtable_nat ebtable_broute bridge stp llc 
ip6table_mangle ip6table_raw ip6table_security iptable_mangle iptable_raw 
iptable_security ebtable_filter ebtables ip6table_filter ip6_tables 
crct10dif_pclmul crc32_pclmul ghash_clmulni_intel virtio_net virtio_balloon 
pcspkr i2c_piix4 sch_fq_codel virtio_blk virtio_console virtio_pci 
crc32c_intel virtio_ring serio_raw virtio
[135385.004007] CPU: 3 PID: 1148 Comm: lt-kcapi Not tainted 4.14.0-rc1+ #554
[135385.004007] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
1.10.2-1.fc26 04/01/2014
[135385.004007] task: 976fb9380d40 task.stack: 9fd280e24000
[135385.004007] RIP: 0010:skcipher_walk_skcipher+0x18/0xb0
[135385.004007] RSP: 0018:9fd280e27ba0 EFLAGS: 00010246
[135385.004007] RAX:  RBX: 9fd280e27be0 RCX: 

[135385.004007] RDX: 976fb85a5428 RSI: 976f76330d08 RDI: 
9fd280e27be0
[135385.004007] RBP: 9fd280e27bc0 R08: 87654321 R09: 
976fb842b880
[135385.004007] R10: 9fd280e27cb8 R11:  R12: 
0001
[135385.004007] R13: 976f76330d08 R14: 976fb842b800 R15: 

[135385.004007] FS:  7fcb922bb700() GS:976fbfd8() knlGS:

[135385.004007] CS:  0010 DS:  ES:  CR0: 80050033
[135385.004007] CR2: 0010 CR3: 798c4001 CR4: 
003606e0
[135385.004007] Call Trace:
[135385.004007]  ? skcipher_walk_virt+0x1e/0x40
[135385.004007]  cbc_encrypt+0x3e/0xc0
[135385.004007]  ? skcipher_null_crypt+0x64/0x80
[135385.004007]  simd_skcipher_encrypt+0xb7/0xc0
[135385.004007]  ? simd_skcipher_encrypt+0xb7/0xc0
[135385.004007]  crypto_authenc_encrypt+0x94/0x170 [authenc]
[135385.004007]  aead_recvmsg+0x2dd/0x5f0 [algif_aead]
[135385.004007]  sock_recvmsg+0x3d/0x50
[135385.004007]  sock_read_iter+0x86/0xc0
[135385.004007]  __vfs_read+0xcb/0x120
[135385.004007]  vfs_read+0x8e/0x130
[135385.004007]  SyS_read+0x46/0xa0
[135385.004007]  do_syscall_64+0x5f/0xf0
[135385.004007]  entry_SYSCALL64_slow_path+0x25/0x25
[135385.004007] RIP: 0033:0x7fcb91bc71b0
[135385.004007] RSP: 002b:7ffe41fc2898 EFLAGS: 0246 ORIG_RAX: 

[135385.004007] RAX: ffda RBX: 1000 RCX: 
7fcb91bc71b0
[135385.004007] RDX: 1000 RSI: 7ffe41fc39a0 RDI: 
0006
[135385.004007] RBP: 012f601c R08: 0001 R09: 

[135385.004007] R10:  R11: 0246 R12: 

[135385.004007] R13: 7ffe41fc39a0 R14: 7ffe41fc39a0 R15: 
7ffe41fc29a0
[135385.004007] Code: ff ff ff e9 42 ff ff ff 90 66 2e 0f 1f 84 00 00 00 00 00 
0f 1f 44 00 00 48 8b 46 10 48 8b 56 40 55 8b 8f 84 00 00 00 48 89 47 20 <8b> 
40 10 48 89 e5 83 e1 ef 89 47 28 48 8b 46 18 48 89 47 38 8b 
[135385.004007] RIP: skcipher_walk_skcipher+0x18/0xb0 RSP: 9fd280e27ba0
[135385.004007] CR2: 0010
[135385.004007] ---[ end trace 25c44edb63da431d ]---
[135385.004007] Kernel panic - not syncing: Fatal exception
[135385.004007] Kernel Offset: 0x1100 from 0x8100 (relocation 
range: 0x8000-0xbfff)
[135385.004007] ---[ end Kernel panic - not syncing: Fatal exception
> 
> Cheers,


Ciao
Stephan


Re: [PATCH 1/2] crypto: skcipher - noop for enc/dec with NULL data

2017-10-06 Thread Herbert Xu
On Sat, Oct 07, 2017 at 04:53:46AM +0200, Stephan Müller wrote:
>
> I use authenc(hmac(sha256),cbc(aes)) which in turn uses cbc-aes-aesni on my 
> system.

So where exactly is it crashing in cbc-aes-aesni? AFAICS it should
handle the zero case just fine.  Or is it hmac that's crashing as
your other patch suggested?

Cheers,
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [PATCH 1/2] crypto: skcipher - noop for enc/dec with NULL data

2017-10-06 Thread Stephan Müller
Am Samstag, 7. Oktober 2017, 04:46:35 CEST schrieb Herbert Xu:

Hi Herbert,

> Hmm this just papers over bugs in the underlying code.  Which
> algorithm is causing the crash with a zero input? They're supposed
> to handle this case.

The bug happens with authenc. It is surely possible to modify authenc. Yet I 
thought that covering such issue at a central spot at least prevents similar 
buts to be exploitable from userspace.

Ciao
Stephan


Re: [PATCH 1/2] crypto: skcipher - noop for enc/dec with NULL data

2017-10-06 Thread Herbert Xu
On Sun, Sep 24, 2017 at 08:24:58AM +0200, Stephan Müller wrote:
> The encryption / decryption operation is a noop in case the caller
> provides zero input data. As this noop is a "valid" operation, the API
> calls will return no error, but simply skip any processing.
> 
> This fixes a kernel crash with authenc() ciphers and zero plaintext /
> ciphertext that can be triggered via AF_ALG from unprivileged user
> space.
> 
> Fixes: 7a7ffe65c8c5f ("crypto: skcipher - Add top-level skcipher
> interface")
> CC: Herbert Xu 
> CC: 
> Signed-off-by: Stephan Mueller 

Hmm this just papers over bugs in the underlying code.  Which
algorithm is causing the crash with a zero input? They're supposed
to handle this case.

Cheers,
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [PATCH 2/2] crypto: shash - no kmap of zero SG

2017-10-06 Thread Herbert Xu
On Sun, Sep 24, 2017 at 08:25:17AM +0200, Stephan Müller wrote:
> In case the caller provides an SG with zero data, prevent a kmap of the
> page pointed to by the SG. In this case, it is possible that the page
> does not exist.
> 
> This fixes a crash in authenc() when the plaintext is zero and thus the
> encryption operation is a noop. In this case, no input data exists that
> can be hashed. The crash is triggerable via AF_ALG from unprivileged
> user space.
> 
> Fixes: 3b2f6df08258e ("crypto: hash - Export shash through ahash")
> CC: Herbert Xu 
> CC: 
> Signed-off-by: Stephan Mueller 
> ---
>  crypto/shash.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/crypto/shash.c b/crypto/shash.c
> index 5e31c8d776df..32d0e1806bf4 100644
> --- a/crypto/shash.c
> +++ b/crypto/shash.c
> @@ -278,9 +278,11 @@ int shash_ahash_digest(struct ahash_request *req, struct 
> shash_desc *desc)
>   struct scatterlist *sg = req->src;
>   unsigned int offset = sg->offset;
>   unsigned int nbytes = req->nbytes;
> + unsigned int process = min(sg->length,
> +((unsigned int)(PAGE_SIZE)) - offset);
>   int err;
>  
> - if (nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset)) {
> + if (process && nbytes < process) {

Sorry but your patch makes no sense.  The only difference between
your patch and the status quo is when process == zero.  However,
if process is zero then the if condition cannot hold since it's
an unsigned comparison.  So how can this patch make any difference
at all?

Cheers,
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


[Part2 PATCH v5.1 12.3/31] crypto: ccp: Implement SEV_FACTORY_RESET ioctl command

2017-10-06 Thread Brijesh Singh
The SEV_FACTORY_RESET command can be used by the platform owner to
reset the non-volatile SEV related data. The command is defined in
SEV spec section 5.4

Cc: Paolo Bonzini 
Cc: "Radim Krčmář" 
Cc: Borislav Petkov 
Cc: Herbert Xu 
Cc: Gary Hook 
Cc: Tom Lendacky 
Cc: linux-crypto@vger.kernel.org
Cc: k...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Brijesh Singh 
---
 drivers/crypto/ccp/psp-dev.c | 29 -
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index e9b776c3acb2..94a08c371bda 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -179,7 +179,34 @@ static int sev_handle_cmd(int cmd, void *data, int 
*psp_ret)
 
 static long sev_ioctl(struct file *file, unsigned int ioctl, unsigned long arg)
 {
-   return -ENOTTY;
+   void __user *argp = (void __user *)arg;
+   struct sev_issue_cmd input;
+   int ret = -EFAULT;
+
+   if (ioctl != SEV_ISSUE_CMD)
+   return -EINVAL;
+
+   if (copy_from_user(, argp, sizeof(struct sev_issue_cmd)))
+   return -EFAULT;
+
+   if (input.cmd > SEV_CMD_MAX)
+   return -EINVAL;
+
+   switch (input.cmd) {
+
+   case SEV_FACTORY_RESET: {
+   ret = sev_handle_cmd(SEV_CMD_FACTORY_RESET, 0, );
+   break;
+   }
+   default:
+   ret = -EINVAL;
+   break;
+   }
+
+   if (copy_to_user(argp, , sizeof(struct sev_issue_cmd)))
+   ret = -EFAULT;
+
+   return ret;
 }
 
 const struct file_operations sev_fops = {
-- 
2.9.5



[Part2 PATCH v5.1 12.5/31] crypto: ccp: Implement SEV_PEK_GEN ioctl command

2017-10-06 Thread Brijesh Singh
The SEV_PEK_GEN command is used to generate a new Platform Endorsement
Key (PEK). The command is defined in SEV spec section 5.6.

Cc: Paolo Bonzini 
Cc: "Radim Krčmář" 
Cc: Borislav Petkov 
Cc: Herbert Xu 
Cc: Gary Hook 
Cc: Tom Lendacky 
Cc: linux-crypto@vger.kernel.org
Cc: k...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Brijesh Singh 
---
 drivers/crypto/ccp/psp-dev.c | 68 
 1 file changed, 68 insertions(+)

diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index d68303a06464..03d7bd03ad58 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -207,6 +207,70 @@ static int sev_ioctl_platform_status(struct sev_issue_cmd 
*argp)
return ret;
 }
 
+static int sev_platform_get_state(int *state, int *error)
+{
+   struct sev_data_status *data;
+   int ret;
+
+   data = kzalloc(sizeof(*data), GFP_KERNEL);
+   if (!data)
+   return -ENOMEM;
+
+   ret = sev_handle_cmd(SEV_CMD_PLATFORM_STATUS, data, error);
+   if (!ret)
+   *state = data->state;
+
+   kfree(data);
+   return ret;
+}
+
+static int sev_firmware_init(int *error)
+{
+   struct sev_data_init *data;
+   int rc;
+
+   data = kzalloc(sizeof(*data), GFP_KERNEL);
+   if (!data)
+   return -ENOMEM;
+
+   rc = sev_handle_cmd(SEV_CMD_INIT, data, error);
+
+   kfree(data);
+   return rc;
+}
+
+static int sev_ioctl_pek_gen(struct sev_issue_cmd *argp)
+{
+   int do_shutdown = 0;
+   int ret, state;
+
+   /*
+* PEK_GEN command can be issued only when firmware is in INIT state.
+* If firmware is in UNINIT state then we transition it in INIT state
+* and issue the command.
+*/
+   ret = sev_platform_get_state(, >error);
+   if (ret)
+   return ret;
+
+   if (state == SEV_STATE_WORKING) {
+   return -EBUSY;
+   } else if (state == SEV_STATE_UNINIT) {
+   ret = sev_firmware_init(>error);
+   if (ret)
+   return ret;
+
+   do_shutdown = 1;
+   }
+
+   ret = sev_handle_cmd(SEV_CMD_PEK_GEN, 0, >error);
+
+   if (do_shutdown)
+   sev_handle_cmd(SEV_CMD_SHUTDOWN, 0, NULL);
+
+   return ret;
+}
+
 static long sev_ioctl(struct file *file, unsigned int ioctl, unsigned long arg)
 {
void __user *argp = (void __user *)arg;
@@ -232,6 +296,10 @@ static long sev_ioctl(struct file *file, unsigned int 
ioctl, unsigned long arg)
ret = sev_ioctl_platform_status();
break;
}
+   case SEV_PEK_GEN: {
+   ret = sev_ioctl_pek_gen();
+   break;
+   }
default:
ret = -EINVAL;
break;
-- 
2.9.5



[Part2 PATCH v5.1 12.1/31] crypto: ccp: Add Secure Encrypted Virtualization (SEV) command support

2017-10-06 Thread Brijesh Singh
AMD's new Secure Encrypted Virtualization (SEV) feature allows the
memory contents of virtual machines to be transparently encrypted with a
key unique to the VM. The programming and management of the encryption
keys are handled by the AMD Secure Processor (AMD-SP) which exposes the
commands for these tasks. The complete spec is available at:

http://support.amd.com/TechDocs/55766_SEV-KM%20API_Specification.pdf

Extend the AMD-SP driver to provide the following support:

 - an in-kernel API to communicate with the SEV firmware. The API can be
   used by the hypervisor to create encryption context for a SEV guest.

 - a userspace IOCTL to manage the platform certificates.

Cc: Paolo Bonzini 
Cc: "Radim Krčmář" 
Cc: Borislav Petkov 
Cc: Herbert Xu 
Cc: Gary Hook 
Cc: Tom Lendacky 
Cc: linux-crypto@vger.kernel.org
Cc: k...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Improvements-by: Borislav Petkov 
Signed-off-by: Brijesh Singh 
---

Based on Boris feedback split this patch in 9 logical patches, they are
numbers from 12.1 to 12.9.

 drivers/crypto/ccp/psp-dev.c | 244 +++
 drivers/crypto/ccp/psp-dev.h |  17 +++
 include/linux/psp-sev.h  | 159 
 3 files changed, 420 insertions(+)

diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index b5789f878560..e9b776c3acb2 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -23,9 +23,16 @@
 #include 
 #include 
 
+#include 
+
 #include "sp-dev.h"
 #include "psp-dev.h"
 
+#define DEVICE_NAME"sev"
+
+static DEFINE_MUTEX(sev_cmd_mutex);
+static bool sev_fops_registered;
+
 static struct psp_device *psp_alloc_struct(struct sp_device *sp)
 {
struct device *dev = sp->dev;
@@ -45,9 +52,239 @@ static struct psp_device *psp_alloc_struct(struct sp_device 
*sp)
 
 static irqreturn_t psp_irq_handler(int irq, void *data)
 {
+   struct psp_device *psp = data;
+   unsigned int status;
+   int reg;
+
+   /* Read the interrupt status: */
+   status = ioread32(psp->io_regs + PSP_P2CMSG_INTSTS);
+
+   /* Check if it is command completion: */
+   if (!(status & BIT(PSP_CMD_COMPLETE_REG)))
+   goto done;
+
+   /* Check if it is SEV command completion: */
+   reg = ioread32(psp->io_regs + PSP_CMDRESP);
+   if (reg & PSP_CMDRESP_RESP) {
+   psp->sev_int_rcvd = 1;
+   wake_up(>sev_int_queue);
+   }
+
+done:
+   /* Clear the interrupt status by writing the same value we read. */
+   iowrite32(status, psp->io_regs + PSP_P2CMSG_INTSTS);
+
return IRQ_HANDLED;
 }
 
+static int sev_wait_cmd_ioc(struct psp_device *psp, unsigned int *reg)
+{
+   psp->sev_int_rcvd = 0;
+
+   wait_event(psp->sev_int_queue, psp->sev_int_rcvd);
+   *reg = ioread32(psp->io_regs + PSP_CMDRESP);
+
+   return 0;
+}
+
+static int sev_cmd_buffer_len(int cmd)
+{
+   switch (cmd) {
+   case SEV_CMD_INIT:  return sizeof(struct 
sev_data_init);
+   case SEV_CMD_PLATFORM_STATUS:   return sizeof(struct 
sev_data_status);
+   case SEV_CMD_PEK_CSR:   return sizeof(struct 
sev_data_pek_csr);
+   case SEV_CMD_PEK_CERT_IMPORT:   return sizeof(struct 
sev_data_pek_cert_import);
+   case SEV_CMD_PDH_CERT_EXPORT:   return sizeof(struct 
sev_data_pdh_cert_export);
+   case SEV_CMD_LAUNCH_START:  return sizeof(struct 
sev_data_launch_start);
+   case SEV_CMD_LAUNCH_UPDATE_DATA:return sizeof(struct 
sev_data_launch_update_data);
+   case SEV_CMD_LAUNCH_UPDATE_VMSA:return sizeof(struct 
sev_data_launch_update_vmsa);
+   case SEV_CMD_LAUNCH_FINISH: return sizeof(struct 
sev_data_launch_finish);
+   case SEV_CMD_LAUNCH_MEASURE:return sizeof(struct 
sev_data_launch_measure);
+   case SEV_CMD_ACTIVATE:  return sizeof(struct 
sev_data_activate);
+   case SEV_CMD_DEACTIVATE:return sizeof(struct 
sev_data_deactivate);
+   case SEV_CMD_DECOMMISSION:  return sizeof(struct 
sev_data_decommission);
+   case SEV_CMD_GUEST_STATUS:  return sizeof(struct 
sev_data_guest_status);
+   case SEV_CMD_DBG_DECRYPT:   return sizeof(struct 
sev_data_dbg);
+   case SEV_CMD_DBG_ENCRYPT:   return sizeof(struct 
sev_data_dbg);
+   case SEV_CMD_SEND_START:return sizeof(struct 
sev_data_send_start);
+   case SEV_CMD_SEND_UPDATE_DATA:  return sizeof(struct 
sev_data_send_update_data);
+   case SEV_CMD_SEND_UPDATE_VMSA:  return sizeof(struct 
sev_data_send_update_vmsa);
+   case SEV_CMD_SEND_FINISH:   return sizeof(struct 
sev_data_send_finish);
+   

[Part2 PATCH v5.1 12.4/31] crypto: ccp: Implement SEV_PLATFORM_STATUS ioctl command

2017-10-06 Thread Brijesh Singh
The SEV_PLATFORM_STATUS command can be used by the platform owner to
get the current status of the platform. The command is defined in
SEV spec section 5.5.

Cc: Paolo Bonzini 
Cc: "Radim Krčmář" 
Cc: Borislav Petkov 
Cc: Herbert Xu 
Cc: Gary Hook 
Cc: Tom Lendacky 
Cc: linux-crypto@vger.kernel.org
Cc: k...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Brijesh Singh 
---
 drivers/crypto/ccp/psp-dev.c | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index 94a08c371bda..d68303a06464 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -177,6 +177,36 @@ static int sev_handle_cmd(int cmd, void *data, int 
*psp_ret)
return ret;
 }
 
+static int sev_ioctl_platform_status(struct sev_issue_cmd *argp)
+{
+   struct sev_user_data_status out;
+   struct sev_data_status *data;
+   int ret;
+
+   data = kzalloc(sizeof(*data), GFP_KERNEL);
+   if (!data)
+   return -ENOMEM;
+
+   ret = sev_handle_cmd(SEV_CMD_PLATFORM_STATUS, data, >error);
+   if (ret)
+   goto e_free;
+
+   out.api_major = data->api_major;
+   out.api_minor = data->api_minor;
+   out.state = data->state;
+   out.owner = data->owner;
+   out.config = data->config;
+   out.build = data->build;
+   out.guest_count = data->guest_count;
+   if (copy_to_user((void __user *)(uintptr_t) argp->data,
+, sizeof(struct sev_user_data_status)))
+   ret = -EFAULT;
+
+e_free:
+   kfree(data);
+   return ret;
+}
+
 static long sev_ioctl(struct file *file, unsigned int ioctl, unsigned long arg)
 {
void __user *argp = (void __user *)arg;
@@ -198,6 +228,10 @@ static long sev_ioctl(struct file *file, unsigned int 
ioctl, unsigned long arg)
ret = sev_handle_cmd(SEV_CMD_FACTORY_RESET, 0, );
break;
}
+   case SEV_PLATFORM_STATUS: {
+   ret = sev_ioctl_platform_status();
+   break;
+   }
default:
ret = -EINVAL;
break;
-- 
2.9.5



[Part2 PATCH v5.1 12.9/31] crypto: ccp: Implement SEV_PDH_CERT_EXPORT ioctl command

2017-10-06 Thread Brijesh Singh
The SEV_PDH_CERT_EXPORT command can be used to export the PDH and its
certificate chain. The command is defined in SEV spec section 5.10.

Cc: Paolo Bonzini 
Cc: "Radim Krčmář" 
Cc: Borislav Petkov 
Cc: Herbert Xu 
Cc: Gary Hook 
Cc: Tom Lendacky 
Cc: linux-crypto@vger.kernel.org
Cc: k...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Brijesh Singh 
---
 drivers/crypto/ccp/psp-dev.c | 110 +++
 1 file changed, 110 insertions(+)

diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index 861c44bf2910..0a069e3c7b8c 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -473,6 +473,112 @@ static int sev_ioctl_pek_cert_import(struct sev_issue_cmd 
*argp)
return ret;
 }
 
+static int sev_ioctl_pdh_cert_export(struct sev_issue_cmd *argp)
+{
+   struct sev_user_data_pdh_cert_export input;
+   struct sev_data_pdh_cert_export *data;
+   int ret, state, need_shutdown = 0;
+   void *pdh_blob, *cert_blob;
+
+   if (copy_from_user(, (void __user *)(uintptr_t)argp->data,
+  sizeof(struct sev_user_data_pdh_cert_export)))
+   return -EFAULT;
+
+   data = kzalloc(sizeof(*data), GFP_KERNEL);
+   if (!data)
+   return -ENOMEM;
+
+   pdh_blob = NULL;
+   if (input.pdh_cert_address) {
+   if (!access_ok(VERIFY_WRITE, input.pdh_cert_address, 
input.pdh_cert_len) ||
+(input.pdh_cert_len > SEV_FW_BLOB_MAX_SIZE)) {
+   ret = -EFAULT;
+   goto e_free;
+   }
+
+   pdh_blob = kmalloc(input.pdh_cert_len, GFP_KERNEL);
+   if (!pdh_blob) {
+   ret = -ENOMEM;
+   goto e_free;
+   }
+
+   data->pdh_cert_address = __psp_pa(pdh_blob);
+   data->pdh_cert_len = input.pdh_cert_len;
+   }
+
+   cert_blob = NULL;
+   if (input.cert_chain_address) {
+   if (!access_ok(VERIFY_WRITE, input.cert_chain_address, 
input.cert_chain_len) ||
+   (input.cert_chain_len > SEV_FW_BLOB_MAX_SIZE)) {
+   ret = -EFAULT;
+   goto e_free_pdh;
+   }
+
+   cert_blob = kmalloc(input.cert_chain_len, GFP_KERNEL);
+   if (!cert_blob) {
+   ret = -ENOMEM;
+   goto e_free_pdh;
+   }
+
+   data->cert_chain_address = __psp_pa(cert_blob);
+   data->cert_chain_len = input.cert_chain_len;
+   }
+
+   ret = sev_platform_get_state(, >error);
+   if (ret)
+   goto e_free_cert;
+
+   /*
+* CERT_EXPORT command can be issued in INIT or WORKING state.
+* If we are in UNINIT state then transition to INIT.
+*/
+   if (state == SEV_STATE_UNINIT) {
+   ret = sev_firmware_init(>error);
+   if (ret)
+   goto e_free_cert;
+
+   need_shutdown = 1;
+   }
+
+   ret = sev_handle_cmd(SEV_CMD_PDH_CERT_EXPORT, data, >error);
+
+   input.cert_chain_len = data->cert_chain_len;
+   input.pdh_cert_len = data->pdh_cert_len;
+
+   /* copy certificate length to userspace */
+   if (copy_to_user((void __user *)(uintptr_t)argp->data, ,
+sizeof(struct sev_user_data_pdh_cert_export)))
+   ret = -EFAULT;
+
+   if (ret)
+   goto e_shutdown;
+
+   /* copy PDH certificate to userspace */
+   if (pdh_blob &&
+   copy_to_user((void __user *)(uintptr_t)input.pdh_cert_address,
+pdh_blob, input.pdh_cert_len)) {
+   ret = -EFAULT;
+   goto e_shutdown;
+   }
+
+   /* copy certificate chain to userspace */
+   if (cert_blob &&
+   copy_to_user((void __user *)(uintptr_t)input.cert_chain_address,
+cert_blob, input.cert_chain_len))
+   ret = -EFAULT;
+
+e_shutdown:
+   if (need_shutdown)
+   sev_handle_cmd(SEV_CMD_SHUTDOWN, 0, NULL);
+e_free_cert:
+   kfree(cert_blob);
+e_free_pdh:
+   kfree(pdh_blob);
+e_free:
+   kfree(data);
+   return ret;
+}
+
 static long sev_ioctl(struct file *file, unsigned int ioctl, unsigned long arg)
 {
void __user *argp = (void __user *)arg;
@@ -514,6 +620,10 @@ static long sev_ioctl(struct file *file, unsigned int 
ioctl, unsigned long arg)
ret = sev_ioctl_pek_cert_import();
break;
}
+   case SEV_PDH_CERT_EXPORT: {
+   ret = sev_ioctl_pdh_cert_export();
+   break;
+   }
default:
ret = -EINVAL;
break;
-- 
2.9.5



[Part2 PATCH v5.1 12.8/31] crypto: ccp: Implement SEV_PEK_CERT_IMPORT ioctl command

2017-10-06 Thread Brijesh Singh
The SEV_PEK_CERT_IMPORT command can be used to import the signed PEK
certificate. The command is defined in SEV spec section 5.8.

Cc: Paolo Bonzini 
Cc: "Radim Krčmář" 
Cc: Borislav Petkov 
Cc: Herbert Xu 
Cc: Gary Hook 
Cc: Tom Lendacky 
Cc: linux-crypto@vger.kernel.org
Cc: k...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Brijesh Singh 
---
 drivers/crypto/ccp/psp-dev.c | 97 
 1 file changed, 97 insertions(+)

diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index 8038ca7aef03..861c44bf2910 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -380,6 +380,99 @@ static int sev_ioctl_pek_csr(struct sev_issue_cmd *argp)
return ret;
 }
 
+static void *copy_user_blob(u64 __user uaddr, u32 len)
+{
+   void *data;
+
+   if (!uaddr || !len)
+   return ERR_PTR(-EINVAL);
+
+   /* verify that blob length does not exceed our limit */
+   if (len > SEV_FW_BLOB_MAX_SIZE)
+   return ERR_PTR(-EINVAL);
+
+   data = kmalloc(len, GFP_KERNEL);
+   if (!data)
+   return ERR_PTR(-ENOMEM);
+
+   if (copy_from_user(data, (void __user *)(uintptr_t)uaddr, len))
+   goto e_free;
+
+   return data;
+
+e_free:
+   kfree(data);
+   return ERR_PTR(-EFAULT);
+}
+
+static int sev_ioctl_pek_cert_import(struct sev_issue_cmd *argp)
+{
+   struct sev_user_data_pek_cert_import input;
+   struct sev_data_pek_cert_import *data;
+   int ret, state, do_shutdown = 0;
+   void *pek_blob, *oca_blob;
+
+   if (copy_from_user(, (void __user *)(uintptr_t) argp->data,
+  sizeof(struct sev_user_data_pek_cert_import)))
+   return -EFAULT;
+
+   data = kzalloc(sizeof(*data), GFP_KERNEL);
+   if (!data)
+   return -ENOMEM;
+
+   /* copy PEK certificate blobs from userspace */
+   pek_blob = copy_user_blob(input.pek_cert_address, input.pek_cert_len);
+   if (IS_ERR(pek_blob)) {
+   ret = PTR_ERR(pek_blob);
+   goto e_free;
+   }
+
+   data->pek_cert_address = __psp_pa(pek_blob);
+   data->pek_cert_len = input.pek_cert_len;
+
+   /* copy PEK certificate blobs from userspace */
+   oca_blob = copy_user_blob(input.oca_cert_address, input.oca_cert_len);
+   if (IS_ERR(oca_blob)) {
+   ret = PTR_ERR(oca_blob);
+   goto e_free_pek;
+   }
+
+   data->oca_cert_address = __psp_pa(oca_blob);
+   data->oca_cert_len = input.oca_cert_len;
+
+   ret = sev_platform_get_state(, >error);
+   if (ret)
+   goto e_free_oca;
+
+   /*
+* PEK_CERT_IMPORT command can be issued only when platform is in INIT
+* state. If we are in UNINIT state then transition in INIT state
+* before issuing the command.
+*/
+   if (state == SEV_STATE_WORKING) {
+   ret = -EBUSY;
+   goto e_free_oca;
+   } else if (state == SEV_STATE_UNINIT) {
+   ret = sev_firmware_init(>error);
+   if (ret)
+   goto e_free_oca;
+   do_shutdown = 1;
+   }
+
+   ret = sev_handle_cmd(SEV_CMD_PEK_CERT_IMPORT, data, >error);
+
+   if (do_shutdown)
+   sev_handle_cmd(SEV_CMD_SHUTDOWN, 0, NULL);
+
+e_free_oca:
+   kfree(oca_blob);
+e_free_pek:
+   kfree(pek_blob);
+e_free:
+   kfree(data);
+   return ret;
+}
+
 static long sev_ioctl(struct file *file, unsigned int ioctl, unsigned long arg)
 {
void __user *argp = (void __user *)arg;
@@ -417,6 +510,10 @@ static long sev_ioctl(struct file *file, unsigned int 
ioctl, unsigned long arg)
ret = sev_ioctl_pek_csr();
break;
}
+   case SEV_PEK_CERT_IMPORT: {
+   ret = sev_ioctl_pek_cert_import();
+   break;
+   }
default:
ret = -EINVAL;
break;
-- 
2.9.5



[Part2 PATCH v5.1 12.6/31] crypto: ccp: Implement SEV_PDH_GEN ioctl command

2017-10-06 Thread Brijesh Singh
The SEV_PDH_GEN command is used to re-generate the Platform
Diffie-Hellman (PDH) key. The command is defined in SEV spec section
5.9.

Cc: Paolo Bonzini 
Cc: "Radim Krčmář" 
Cc: Borislav Petkov 
Cc: Herbert Xu 
Cc: Gary Hook 
Cc: Tom Lendacky 
Cc: linux-crypto@vger.kernel.org
Cc: k...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Brijesh Singh 
---
 drivers/crypto/ccp/psp-dev.c | 32 
 1 file changed, 32 insertions(+)

diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index 03d7bd03ad58..28efb7a9245a 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -271,6 +271,34 @@ static int sev_ioctl_pek_gen(struct sev_issue_cmd *argp)
return ret;
 }
 
+static int sev_ioctl_pdh_gen(struct sev_issue_cmd *argp)
+{
+   int ret, state, do_shutdown = 0;
+
+   /*
+* PDH_GEN command can be issued when platform is in INIT or WORKING
+* state. If we are in UNINIT state then transition in INIT state
+* before issuing the command.
+*/
+   ret = sev_platform_get_state(, >error);
+   if (ret)
+   return ret;
+
+   if (state == SEV_STATE_UNINIT) {
+   ret = sev_firmware_init(>error);
+   if (ret)
+   return ret;
+   do_shutdown = 1;
+   }
+
+   ret = sev_handle_cmd(SEV_CMD_PDH_GEN, 0, >error);
+
+   if (do_shutdown)
+   sev_handle_cmd(SEV_CMD_SHUTDOWN, 0, NULL);
+
+   return ret;
+}
+
 static long sev_ioctl(struct file *file, unsigned int ioctl, unsigned long arg)
 {
void __user *argp = (void __user *)arg;
@@ -300,6 +328,10 @@ static long sev_ioctl(struct file *file, unsigned int 
ioctl, unsigned long arg)
ret = sev_ioctl_pek_gen();
break;
}
+   case SEV_PDH_GEN: {
+   ret = sev_ioctl_pdh_gen();
+   break;
+   }
default:
ret = -EINVAL;
break;
-- 
2.9.5



[Part2 PATCH v5.1 12.7/31] crypto: ccp: Implement SEV_PEK_CSR ioctl command

2017-10-06 Thread Brijesh Singh
The SEV_PEK_CSR command can be used to generate a PEK certificate
signing request. The command is defined in SEV spec section 5.7.

Cc: Paolo Bonzini 
Cc: "Radim Krčmář" 
Cc: Borislav Petkov 
Cc: Herbert Xu 
Cc: Gary Hook 
Cc: Tom Lendacky 
Cc: linux-crypto@vger.kernel.org
Cc: k...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Brijesh Singh 
---
 drivers/crypto/ccp/psp-dev.c | 85 
 1 file changed, 85 insertions(+)

diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index 28efb7a9245a..8038ca7aef03 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -299,6 +299,87 @@ static int sev_ioctl_pdh_gen(struct sev_issue_cmd *argp)
return ret;
 }
 
+static int sev_ioctl_pek_csr(struct sev_issue_cmd *argp)
+{
+   struct sev_user_data_pek_csr input;
+   struct sev_data_pek_csr *data;
+   int do_shutdown = 0;
+   int ret, state;
+   void *blob;
+
+   if (copy_from_user(, (void __user *)(uintptr_t)argp->data,
+  sizeof(struct sev_user_data_pek_csr)))
+   return -EFAULT;
+
+   data = kzalloc(sizeof(*data), GFP_KERNEL);
+   if (!data)
+   return -ENOMEM;
+
+   /* allocate a temporary physical contigous buffer to store the CSR blob 
*/
+   blob = NULL;
+   if (input.address) {
+   if (!access_ok(VERIFY_WRITE, input.address, input.length) ||
+   input.length > SEV_FW_BLOB_MAX_SIZE) {
+   ret = -EFAULT;
+   goto e_free;
+   }
+
+   blob = kmalloc(input.length, GFP_KERNEL);
+   if (!blob) {
+   ret = -ENOMEM;
+   goto e_free;
+   }
+
+   data->address = __psp_pa(blob);
+   data->len = input.length;
+   }
+
+   ret = sev_platform_get_state(, >error);
+   if (ret)
+   goto e_free_blob;
+
+   /*
+* PEK_CERT command can be issued only when we are in INIT state.
+* if current state is WORKING then reject it, if state is UNINIT
+* then transition the platform to INIT state before issuing the
+* command.
+*/
+   if (state == SEV_STATE_WORKING) {
+   ret = -EBUSY;
+   goto e_free_blob;
+   } else if (state == SEV_STATE_UNINIT) {
+   ret = sev_firmware_init(>error);
+   if (ret)
+   goto e_free_blob;
+   do_shutdown = 1;
+   }
+
+   ret = sev_handle_cmd(SEV_CMD_PEK_CSR, data, >error);
+
+   input.length = data->len;
+
+   /* copy blob to userspace */
+   if (blob &&
+   copy_to_user((void __user *)(uintptr_t)input.address,
+   blob, input.length)) {
+   ret = -EFAULT;
+   goto e_shutdown;
+   }
+
+   if (copy_to_user((void __user *)(uintptr_t)argp->data, ,
+sizeof(struct sev_user_data_pek_csr)))
+   ret = -EFAULT;
+
+e_shutdown:
+   if (do_shutdown)
+   sev_handle_cmd(SEV_CMD_SHUTDOWN, 0, NULL);
+e_free_blob:
+   kfree(blob);
+e_free:
+   kfree(data);
+   return ret;
+}
+
 static long sev_ioctl(struct file *file, unsigned int ioctl, unsigned long arg)
 {
void __user *argp = (void __user *)arg;
@@ -332,6 +413,10 @@ static long sev_ioctl(struct file *file, unsigned int 
ioctl, unsigned long arg)
ret = sev_ioctl_pdh_gen();
break;
}
+   case SEV_PEK_CSR: {
+   ret = sev_ioctl_pek_csr();
+   break;
+   }
default:
ret = -EINVAL;
break;
-- 
2.9.5



[Part2 PATCH v5.1 12.2/31] crypto: ccp: Define SEV userspace ioctl and command id

2017-10-06 Thread Brijesh Singh
Add a include file which defines the ioctl and command id used for
issuing SEV platform management specific commands.

Cc: Paolo Bonzini 
Cc: "Radim Krčmář" 
Cc: Borislav Petkov 
Cc: Herbert Xu 
Cc: Gary Hook 
Cc: Tom Lendacky 
Cc: linux-crypto@vger.kernel.org
Cc: k...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Brijesh Singh 
---
 include/uapi/linux/psp-sev.h | 115 +++
 1 file changed, 115 insertions(+)
 create mode 100644 include/uapi/linux/psp-sev.h

diff --git a/include/uapi/linux/psp-sev.h b/include/uapi/linux/psp-sev.h
new file mode 100644
index ..a385bf2b8d2a
--- /dev/null
+++ b/include/uapi/linux/psp-sev.h
@@ -0,0 +1,115 @@
+/*
+ * Userspace interface for AMD Secure Encrypted Virtualization (SEV)
+ * platform management commands.
+ *
+ * Copyright (C) 2016-2017 Advanced Micro Devices, Inc.
+ *
+ * Author: Brijesh Singh 
+ *
+ * SEV spec 0.14 is available at:
+ * http://support.amd.com/TechDocs/55766_SEV-KM%20API_Specification.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __PSP_SEV_USER_H__
+#define __PSP_SEV_USER_H__
+
+#include 
+
+/**
+ * SEV platform commands
+ */
+enum {
+   SEV_FACTORY_RESET = 0,
+   SEV_PLATFORM_STATUS,
+   SEV_PEK_GEN,
+   SEV_PEK_CSR,
+   SEV_PDH_GEN,
+   SEV_PDH_CERT_EXPORT,
+   SEV_PEK_CERT_IMPORT,
+
+   SEV_MAX,
+};
+
+/**
+ * struct sev_user_data_status - PLATFORM_STATUS command parameters
+ *
+ * @major: major API version
+ * @minor: minor API version
+ * @state: platform state
+ * @owner: self-owned or externally owned
+ * @config: platform config flags
+ * @build: firmware build id for API version
+ * @guest_count: number of active guests
+ */
+struct sev_user_data_status {
+   __u8 api_major; /* Out */
+   __u8 api_minor; /* Out */
+   __u8 state; /* Out */
+   __u8 owner; /* Out */
+   __u32 config;   /* Out */
+   __u8 build; /* Out */
+   __u32 guest_count;  /* Out */
+};
+
+/**
+ * struct sev_user_data_pek_csr - PEK_CSR command parameters
+ *
+ * @address: PEK certificate chain
+ * @length: length of certificate
+ */
+struct sev_user_data_pek_csr {
+   __u64 address;  /* In */
+   __u32 length;   /* In/Out */
+};
+
+/**
+ * struct sev_user_data_cert_import - PEK_CERT_IMPORT command parameters
+ *
+ * @pek_address: PEK certificate chain
+ * @pek_len: length of PEK certificate
+ * @oca_address: OCA certificate chain
+ * @oca_len: length of OCA certificate
+ */
+struct sev_user_data_pek_cert_import {
+   __u64 pek_cert_address; /* In */
+   __u32 pek_cert_len; /* In */
+   __u64 oca_cert_address; /* In */
+   __u32 oca_cert_len; /* In */
+};
+
+/**
+ * struct sev_user_data_pdh_cert_export - PDH_CERT_EXPORT command parameters
+ *
+ * @pdh_address: PDH certificate address
+ * @pdh_len: length of PDH certificate
+ * @cert_chain_address: PDH certificate chain
+ * @cert_chain_len: length of PDH certificate chain
+ */
+struct sev_user_data_pdh_cert_export {
+   __u64 pdh_cert_address; /* In */
+   __u32 pdh_cert_len; /* In/Out */
+   __u64 cert_chain_address;   /* In */
+   __u32 cert_chain_len;   /* In/Out */
+};
+
+/**
+ * struct sev_issue_cmd - SEV ioctl parameters
+ *
+ * @cmd: SEV commands to execute
+ * @opaque: pointer to the command structure
+ * @error: SEV FW return code on failure
+ */
+struct sev_issue_cmd {
+   __u32 cmd;  /* In */
+   __u64 data; /* In */
+   __u32 error;/* Out */
+};
+
+#define SEV_IOC_TYPE   'S'
+#define SEV_ISSUE_CMD  _IOWR(SEV_IOC_TYPE, 0x0, struct sev_issue_cmd)
+
+#endif /* __PSP_USER_SEV_H */
-- 
2.9.5



[Part2 PATCH v5.1 10/31] crypto: ccp: Add Platform Security Processor (PSP) device support

2017-10-06 Thread Brijesh Singh
The Platform Security Processor (PSP) is part of the AMD Secure
Processor (AMD-SP) functionality. The PSP is a dedicated processor
that provides support for key management commands in Secure Encrypted
Virtualization (SEV) mode, along with software-based Trusted Execution
Environment (TEE) to enable third-party trusted applications.

Note that the key management functionality provided by the SEV firmware
can be used outside of the kvm-amd driver hence it doesn't need to
depend on CONFIG_KVM_AMD.

Cc: Paolo Bonzini 
Cc: "Radim Krčmář" 
Cc: Borislav Petkov 
Cc: Herbert Xu 
Cc: Gary Hook 
Cc: Tom Lendacky 
Cc: linux-crypto@vger.kernel.org
Cc: k...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Improvements-by: Borislav Petkov 
Signed-off-by: Brijesh Singh 
Reviewed-by: Borislav Petkov 
---

Changes since v5:
 * move psp_entry in sp-pci.c (based on Boris improvement patch)

 drivers/crypto/ccp/Kconfig   |  11 +
 drivers/crypto/ccp/Makefile  |   1 +
 drivers/crypto/ccp/psp-dev.c | 105 +++
 drivers/crypto/ccp/psp-dev.h |  59 
 drivers/crypto/ccp/sp-dev.c  |  26 +++
 drivers/crypto/ccp/sp-dev.h  |  26 ++-
 drivers/crypto/ccp/sp-pci.c  |  52 +
 7 files changed, 279 insertions(+), 1 deletion(-)
 create mode 100644 drivers/crypto/ccp/psp-dev.c
 create mode 100644 drivers/crypto/ccp/psp-dev.h

diff --git a/drivers/crypto/ccp/Kconfig b/drivers/crypto/ccp/Kconfig
index 9c84f9838931..b9dfae47aefd 100644
--- a/drivers/crypto/ccp/Kconfig
+++ b/drivers/crypto/ccp/Kconfig
@@ -33,3 +33,14 @@ config CRYPTO_DEV_CCP_CRYPTO
  Support for using the cryptographic API with the AMD Cryptographic
  Coprocessor. This module supports offload of SHA and AES algorithms.
  If you choose 'M' here, this module will be called ccp_crypto.
+
+config CRYPTO_DEV_SP_PSP
+   bool "Platform Security Processor (PSP) device"
+   default y
+   depends on CRYPTO_DEV_CCP_DD && X86_64
+   help
+Provide support for the AMD Platform Security Processor (PSP).
+The PSP is a dedicated processor that provides support for key
+management commands in Secure Encrypted Virtualization (SEV) mode,
+along with software-based Trusted Execution Environment (TEE) to
+enable third-party trusted applications.
diff --git a/drivers/crypto/ccp/Makefile b/drivers/crypto/ccp/Makefile
index 57f8debfcfb3..008bae7e26ec 100644
--- a/drivers/crypto/ccp/Makefile
+++ b/drivers/crypto/ccp/Makefile
@@ -7,6 +7,7 @@ ccp-$(CONFIG_CRYPTO_DEV_SP_CCP) += ccp-dev.o \
ccp-dmaengine.o \
ccp-debugfs.o
 ccp-$(CONFIG_PCI) += sp-pci.o
+ccp-$(CONFIG_CRYPTO_DEV_SP_PSP) += psp-dev.o
 
 obj-$(CONFIG_CRYPTO_DEV_CCP_CRYPTO) += ccp-crypto.o
 ccp-crypto-objs := ccp-crypto-main.o \
diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
new file mode 100644
index ..b5789f878560
--- /dev/null
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -0,0 +1,105 @@
+/*
+ * AMD Platform Security Processor (PSP) interface
+ *
+ * Copyright (C) 2016-2017 Advanced Micro Devices, Inc.
+ *
+ * Author: Brijesh Singh 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "sp-dev.h"
+#include "psp-dev.h"
+
+static struct psp_device *psp_alloc_struct(struct sp_device *sp)
+{
+   struct device *dev = sp->dev;
+   struct psp_device *psp;
+
+   psp = devm_kzalloc(dev, sizeof(*psp), GFP_KERNEL);
+   if (!psp)
+   return NULL;
+
+   psp->dev = dev;
+   psp->sp = sp;
+
+   snprintf(psp->name, sizeof(psp->name), "psp-%u", sp->ord);
+
+   return psp;
+}
+
+static irqreturn_t psp_irq_handler(int irq, void *data)
+{
+   return IRQ_HANDLED;
+}
+
+int psp_dev_init(struct sp_device *sp)
+{
+   struct device *dev = sp->dev;
+   struct psp_device *psp;
+   int ret;
+
+   ret = -ENOMEM;
+   psp = psp_alloc_struct(sp);
+   if (!psp)
+   goto e_err;
+
+   sp->psp_data = psp;
+
+   psp->vdata = (struct psp_vdata *)sp->dev_vdata->psp_vdata;
+   if (!psp->vdata) {
+   ret = -ENODEV;
+   dev_err(dev, "missing driver data\n");
+   goto e_err;
+   }
+
+   psp->io_regs = sp->io_map + psp->vdata->offset;
+
+   /* Disable and clear interrupts until ready */
+   iowrite32(0, psp->io_regs + PSP_P2CMSG_INTEN);
+   iowrite32(-1, psp->io_regs + PSP_P2CMSG_INTSTS);
+
+   /* Request an irq */
+   

Re: [Part2 PATCH v5 12/31] crypto: ccp: Add Secure Encrypted Virtualization (SEV) command support

2017-10-06 Thread Brijesh Singh


On 10/6/17 1:49 PM, Borislav Petkov wrote:
...
>> +
>> +static unsigned int sev_poll;
>> +module_param(sev_poll, uint, 0444);
>> +MODULE_PARM_DESC(sev_poll, "Poll for sev command completion - any non-zero 
>> value");
> What is that used for? Some debugging leftover probably? If not, add a
> comment for why it is useful.
>

Yes, it was used for debug and can be removed. I will it in next rev.

.

> Ok, this patch is humongous. Please split it in at least 3 or 4 separate
> logical patches as it is very hard to review as one huge chunk right
> now. Like, for example, the header file additions could be one patch,
> then part of psp-dev.c and so on.
>
> You can then send me those split-up ones as a reply here so that I can
> take a look again.

I will see what I can do, Maybe I will add one command at a time like we
do in svm.c.

> Also, here are a bunch of fixes ontop. Please add
>
> "Improvements by Borislav Petkov "
>
> to the commit message when you decide to use them.

Sure, I will add your Improved-by-tag.

> Btw, the psp_entry thing I've moved to sp-pci.c, you probably should do
> that in the patch which adds it, not here.
>
> Also, I've fixed:
>
> +   /* Clear the interrupt status by writing 1. */
> +   iowrite32(1, psp->io_regs + PSP_P2CMSG_INTSTS);
>
> to really write 1 and not reuse the old status value.

Actually this one is interesting. When we read the status register, one
of the bit in status register will be 1 (i.e it may not always be bit 0)
and we need to write 1 on same bit position to clear it -- basically
write the same value you read. I will improve the comment. 

> And so on, they should be obvious from the diff.
>
> Thx.
>
> ---
> diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
> index 1b87a699bd3f..13633eaa7889 100644
> --- a/drivers/crypto/ccp/psp-dev.c
> +++ b/drivers/crypto/ccp/psp-dev.c
> @@ -32,15 +32,11 @@
>  
>  static unsigned int sev_poll;
>  module_param(sev_poll, uint, 0444);
> -MODULE_PARM_DESC(sev_poll, "Poll for sev command completion - any non-zero 
> value");
> +MODULE_PARM_DESC(sev_poll, "Poll for SEV command completion - any non-zero 
> value");
>  
> -DEFINE_MUTEX(sev_cmd_mutex);
> +static DEFINE_MUTEX(sev_cmd_mutex);
>  static bool sev_fops_registered;
>  
> -const struct psp_vdata psp_entry = {
> - .offset = 0x10500,
> -};
> -
>  static struct psp_device *psp_alloc_struct(struct sp_device *sp)
>  {
>   struct device *dev = sp->dev;
> @@ -62,34 +58,37 @@ static irqreturn_t psp_irq_handler(int irq, void *data)
>  {
>   struct psp_device *psp = data;
>   unsigned int status;
> + int reg;
>  
> - /* read the interrupt status */
> + /* Read the interrupt status: */
>   status = ioread32(psp->io_regs + PSP_P2CMSG_INTSTS);
>  
> - /* check if its command completion */
> - if (status & (1 << PSP_CMD_COMPLETE_REG)) {
> - int reg;
> + /* Check if it is command completion: */
> + if (!(status & BIT(PSP_CMD_COMPLETE_REG)))
> + goto done;
>  
> - /* check if its SEV command completion */
> - reg = ioread32(psp->io_regs + PSP_CMDRESP);
> - if (reg & PSP_CMDRESP_RESP) {
> - psp->sev_int_rcvd = 1;
> - wake_up(>sev_int_queue);
> - }
> + /* Check if it is SEV command completion: */
> + reg = ioread32(psp->io_regs + PSP_CMDRESP);
> + if (reg & PSP_CMDRESP_RESP) {
> + psp->sev_int_rcvd = 1;
> + wake_up(>sev_int_queue);
>   }
>  
> - /* clear the interrupt status by writing 1 */
> - iowrite32(status, psp->io_regs + PSP_P2CMSG_INTSTS);
> +done:
> + /* Clear the interrupt status by writing 1. */
> + iowrite32(1, psp->io_regs + PSP_P2CMSG_INTSTS);
>  
>   return IRQ_HANDLED;
>  }
>  
> -static int sev_wait_cmd_poll(struct psp_device *psp, unsigned int timeout,
> +static int sev_wait_cmd_poll(struct psp_device *psp, unsigned int timeouts,
>unsigned int *reg)
>  {
> - int wait = timeout * 10;/* 100ms sleep => timeout * 10 */
> + /* 10*100ms max timeout */
> + if (timeouts > 10)
> + timeouts = 10;
>  
> - while (--wait) {
> + while (--timeouts) {
>   msleep(100);
>  
>   *reg = ioread32(psp->io_regs + PSP_CMDRESP);
> @@ -97,8 +96,8 @@ static int sev_wait_cmd_poll(struct psp_device *psp, 
> unsigned int timeout,
>   break;
>   }
>  
> - if (!wait) {
> - dev_err(psp->dev, "sev command timed out\n");
> + if (!timeouts) {
> + dev_err(psp->dev, "SEV command timed out\n");
>   return -ETIMEDOUT;
>   }
>  
> @@ -157,11 +156,16 @@ static int sev_cmd_buffer_len(int cmd)
>  
>  static int sev_handle_cmd(int cmd, void *data, int *psp_ret)
>  {
> - struct sp_device *sp = sp_get_psp_master_device();
>   unsigned int phys_lsb, phys_msb;
> - struct psp_device *psp 

Re: [Part2 PATCH v5 12/31] crypto: ccp: Add Secure Encrypted Virtualization (SEV) command support

2017-10-06 Thread Borislav Petkov
On Wed, Oct 04, 2017 at 08:13:53AM -0500, Brijesh Singh wrote:
> AMDs new Secure Encrypted Virtualization (SEV) feature allows the memory
> contents of a virtual machines to be transparently encrypted with a key
> unique to the guest VM. The programming and management of the encryption
> keys are handled by the AMD Secure Processor (AMD-SP), which exposes the
> commands for these tasks. The complete spec is available at:
> 
> http://support.amd.com/TechDocs/55766_SEV-KM%20API_Specification.pdf
> 
> Extend the AMD-SP driver to provide the following support:
> 
>  - an in-kernel APIs to communicate with a SEV firmware. The APIs can be
>used by the hypervisor to create encryption context for the SEV guests.
> 
>  - a userspace IOCTL to manage the platform certificates

Change that commit message to:

"AMD's new Secure Encrypted Virtualization (SEV) feature allows the
memory contents of virtual machines to be transparently encrypted with a
key unique to the VM. The programming and management of the encryption
keys are handled by the AMD Secure Processor (AMD-SP) which exposes the
commands for these tasks. The complete spec is available at:

http://support.amd.com/TechDocs/55766_SEV-KM%20API_Specification.pdf

Extend the AMD-SP driver to provide the following support:

 - an in-kernel API to communicate with the SEV firmware. The API can be
   used by the hypervisor to create encryption context for a SEV guest.

 - a userspace IOCTL to manage the platform certificates."

> 
> Cc: Paolo Bonzini 
> Cc: "Radim Krčmář" 
> Cc: Borislav Petkov 
> Cc: Herbert Xu 
> Cc: Gary Hook 
> Cc: Tom Lendacky 
> Cc: linux-crypto@vger.kernel.org
> Cc: k...@vger.kernel.org
> Cc: linux-ker...@vger.kernel.org
> Signed-off-by: Brijesh Singh 
> ---
>  drivers/crypto/ccp/psp-dev.c | 734 
> +++
>  drivers/crypto/ccp/psp-dev.h |  17 +
>  include/linux/psp-sev.h  | 159 ++
>  include/uapi/linux/psp-sev.h | 116 +++
>  4 files changed, 1026 insertions(+)
>  create mode 100644 include/uapi/linux/psp-sev.h
> 
> diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
> index 7480d4316239..1b87a699bd3f 100644
> --- a/drivers/crypto/ccp/psp-dev.c
> +++ b/drivers/crypto/ccp/psp-dev.c
> @@ -23,9 +23,20 @@
>  #include 
>  #include 
>  
> +#include 
> +
>  #include "sp-dev.h"
>  #include "psp-dev.h"
>  
> +#define DEVICE_NAME  "sev"
> +
> +static unsigned int sev_poll;
> +module_param(sev_poll, uint, 0444);
> +MODULE_PARM_DESC(sev_poll, "Poll for sev command completion - any non-zero 
> value");

What is that used for? Some debugging leftover probably? If not, add a
comment for why it is useful.

> +
> +DEFINE_MUTEX(sev_cmd_mutex);
> +static bool sev_fops_registered;
> +
>  const struct psp_vdata psp_entry = {
>   .offset = 0x10500,
>  };
> @@ -49,9 +60,725 @@ static struct psp_device *psp_alloc_struct(struct 
> sp_device *sp)
>  
>  static irqreturn_t psp_irq_handler(int irq, void *data)
>  {
> + struct psp_device *psp = data;
> + unsigned int status;
> +
> + /* read the interrupt status */
> + status = ioread32(psp->io_regs + PSP_P2CMSG_INTSTS);
> +
> + /* check if its command completion */
> + if (status & (1 << PSP_CMD_COMPLETE_REG)) {
> + int reg;
> +
> + /* check if its SEV command completion */
> + reg = ioread32(psp->io_regs + PSP_CMDRESP);
> + if (reg & PSP_CMDRESP_RESP) {
> + psp->sev_int_rcvd = 1;
> + wake_up(>sev_int_queue);
> + }
> + }
> +
> + /* clear the interrupt status by writing 1 */
> + iowrite32(status, psp->io_regs + PSP_P2CMSG_INTSTS);
> +
>   return IRQ_HANDLED;
>  }
>  
> +static int sev_wait_cmd_poll(struct psp_device *psp, unsigned int timeout,
> +  unsigned int *reg)
> +{
> + int wait = timeout * 10;/* 100ms sleep => timeout * 10 */

How is this a 100ms sleep?!

10 * 10 * 100ms = 1ms = 10 seconds max sleep is what my math says.

> +
> + while (--wait) {
> + msleep(100);
> +
> + *reg = ioread32(psp->io_regs + PSP_CMDRESP);
> + if (*reg & PSP_CMDRESP_RESP)
> + break;
> + }
> +
> + if (!wait) {
> + dev_err(psp->dev, "sev command timed out\n");
> + return -ETIMEDOUT;
> + }
> +
> + return 0;
> +}
> +
> +static int sev_wait_cmd_ioc(struct psp_device *psp, unsigned int *reg)
> +{
> + psp->sev_int_rcvd = 0;
> +
> + wait_event(psp->sev_int_queue, psp->sev_int_rcvd);

What happens if the command times out and it never sets psp->sev_int_rcvd?

> + *reg = ioread32(psp->io_regs + PSP_CMDRESP);
> +
> + return 0;
> +}
> +
> +static int sev_wait_cmd(struct psp_device *psp, unsigned int *reg)
> +{
> + return (*reg & 

Re: [PATCH v4] crypto: s5p-sss: Add HASH support for Exynos

2017-10-06 Thread Krzysztof Kozlowski
On Wed, Oct 04, 2017 at 06:38:11PM +0200, Kamil Konieczny wrote:
> Add support for MD5, SHA1, SHA256 hash algorithms for Exynos HW.
> It uses the crypto framework asynchronous hash api.
> It is based on omap-sham.c driver.
> S5P has some HW differencies and is not implemented.
> 
> Modifications in s5p-sss:
> 
> - Add hash supporting structures and functions.
> 
> - Modify irq handler to handle both aes and hash signals.
> 
> - Resize resource end in probe if EXYNOS_HASH is enabled in
>   Kconfig.
> 
> - Add new copyright line and new author.
> 
> - Tested on Odroid-U3 with Exynos 4412 CPU, kernel 4.13-rc6
>   with crypto run-time self test testmgr
>   and with tcrypt module with: modprobe tcrypt sec=1 mode=N
>   where N=402, 403, 404 (MD5, SHA1, SHA256).
> 
> Modifications in drivers/crypto/Kconfig:
> 
> - Add new CRYPTO_DEV_EXYNOS_HASH, depend on !EXYNOS_RNG
>   and CRYPTO_DEV_S5P
> 
> - Select sw algorithms MD5, SHA1 and SHA256 in EXYNOS_HASH
>   as they are nedded for fallback.
> 
> Signed-off-by: Kamil Konieczny 
> ---
> version 4:
> - fixes suggested by Krzysztof Kozlowski: reformat comments, convert context
>   flag into two bool vars, drop SSS_ALIGNED, change name of SSS_DMA_ALIGN and
>   SSS_DMA_ALIGN_MASK, split assignments into separate lines, use IS_ENABLED in
>   place of ifdef, remove sss_hash_algs_info and simplify register and 
> deregister
>   HASH algs
> 
> version 3:
> - many fixes suggested by Krzysztof Kozlowski: comments, uppercases in const,
>   remove unused defines, remove unused variable bs, constify aes_variant,
>   remove global var use_hash, remove WARN_ON, improve hash_import(),
>   change goto label into 'out' in s5p_hash_handle_queue(), reorder variable
>   declarations, add spinlock to protect clearing HASH_FLAGS_BUSY
> - simplify code: replace one-line functions s5p_hash_update_req(),
>   s5p_hash_final_req() with call to s5p_hash_xmit_dma(), and delete them
> - replace call to s5p_hash_hw_init() into s5p_ahash_dma_init() and delete it
> - fix clearing shash flag CRYPTO_TFM_REQ_MAY_SLEEP
> - fix s5p_hash_set_flow()
> 
> version 2:
> - change patch format so number of lines drops
> - change in Kconfig as suggested by Krzysztof Kozlowski, add
>   EXYNOS_HASH subsection
> - change #ifndef EXYNOS_RNG into #ifdef CRYPTO_DEV_EXYNOS_HASH
> - remove style fixups in aes, as they should go in separate patch
> - remove FLOW_LOG, FLOW_DUMP macros and its uses
> - remove #if 0 ... endif
> - remove unused function hash_wait and its defines
> - fix compiler warning in dev_dbg
> - remove some comments
> - other minor fixes in comments
> 
>  drivers/crypto/Kconfig   |   14 +
>  drivers/crypto/s5p-sss.c | 1441 
> +-
>  2 files changed, 1445 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
> index fe33c199fc1a..01cf07ce34c5 100644
> --- a/drivers/crypto/Kconfig
> +++ b/drivers/crypto/Kconfig
> @@ -439,6 +439,20 @@ config CRYPTO_DEV_S5P
> Select this to offload Samsung S5PV210 or S5PC110, Exynos from AES
> algorithms execution.
>  
> +config CRYPTO_DEV_EXYNOS_HASH
> + bool "Support for Samsung Exynos HASH accelerator"
> + depends on CRYPTO_DEV_S5P
> + depends on !CRYPTO_DEV_EXYNOS_RNG && CRYPTO_DEV_EXYNOS_RNG!=m
> + select CRYPTO_SHA1
> + select CRYPTO_MD5
> + select CRYPTO_SHA256
> + help
> +   Select this to offload Exynos from HASH MD5/SHA1/SHA256.
> +   This will select software SHA1, MD5 and SHA256 as they are
> +   needed for small and zero-size messages.
> +   HASH algorithms will be disabled if EXYNOS_RNG
> +   is enabled due to hw conflict.
> +
>  config CRYPTO_DEV_NX
>   bool "Support for IBM PowerPC Nest (NX) cryptographic acceleration"
>   depends on PPC64
> diff --git a/drivers/crypto/s5p-sss.c b/drivers/crypto/s5p-sss.c
> index 7ac657f46d15..2864efeaf8f8 100644
> --- a/drivers/crypto/s5p-sss.c
> +++ b/drivers/crypto/s5p-sss.c
> @@ -1,18 +1,21 @@
>  /*
>   * Cryptographic API.
>   *
> - * Support for Samsung S5PV210 HW acceleration.
> + * Support for Samsung S5PV210 and Exynos HW acceleration.
>   *
>   * Copyright (C) 2011 NetUP Inc. All rights reserved.
> + * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License version 2 as 
> published
>   * by the Free Software Foundation.
>   *
> + * Hash part based on omap-sham.c driver.
>   */
>  
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -30,28 +33,41 @@
>  #include 
>  #include 
>  
> +#include 
> +#include 
> +#include 
> +#include 
> +
>  #define _SBF(s, v)  ((v) << (s))
>  
>  /* Feed control registers */
>  #define SSS_REG_FCINTSTAT   0x
> +#define SSS_FCINTSTAT_HPARTINT   BIT(7)
> +#define 

Re: [PATCH] iommu/vt-d: Fix scatterlist offset handling

2017-10-06 Thread Raj, Ashok
On Fri, Oct 06, 2017 at 04:43:09PM +0200, Joerg Roedel wrote:
> On Tue, Oct 03, 2017 at 07:05:17PM +0100, Robin Murphy wrote:
> > Now, there are indeed plenty of drivers and subsystems which do work on
> > lists of explicitly single pages - anything doing some variant of
> > "addr = kmap_atomic(sg_page(sg)) + sg->offset;" is easy to spot - but I
> > don't think DMA API implementations are in a position to make any kind
> > of assumption; nearly all of them just shut up and handle sg->length
> > bytes from sg_phys(sg) without questioning the caller, and I reckon
> > that's exactly what they should be doing.
> 
> I agree with that, it is not explicitly forbidden to have an
> sg->offset > PAGE_SIZE and most IOMMU drivers handle this case.
> 
> So this is a problem I'd like to see resolved in the VT-d driver too. If
> nobody comes up with a correct fix soon I'll apply this one and rip out
> the large-page support from __domain_mapping() to make it work.

That seems like a good start. I have reviewed Robin's fix and it seems
to make sense. I'll start looking at making __domain_mapping() 
to make it more manageable.

> 
> Speaking of __domain_mapping(), this function is a big unmaintainable
> mess which should be split and rewritten. A clean and maintainable
> rewrite can alse re-add the large-page support.
> 
> 
> Regards,
> 
>   Joerg
> 


[PATCH] crypto: atmel-aes - properly set IV after {en,de}crypt

2017-10-06 Thread Romain Izard
Certain cipher modes like CTS expect the IV (req->info) of
ablkcipher_request (or equivalently req->iv of skcipher_request) to
contain the last ciphertext block when the {en,de}crypt operation is done.

Fix this issue for the Atmel AES hardware engine. The tcrypt test
case for cts(cbc(aes)) is now correctly passed.

To handle the case of in-place decryption, copy the ciphertext in an
intermediate buffer before decryption.

Signed-off-by: Romain Izard 
---
 drivers/crypto/atmel-aes.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c
index 29e20c37f3a6..f22300babb45 100644
--- a/drivers/crypto/atmel-aes.c
+++ b/drivers/crypto/atmel-aes.c
@@ -156,6 +156,7 @@ struct atmel_aes_authenc_ctx {
 
 struct atmel_aes_reqctx {
unsigned long   mode;
+   u8  *backup_info;
 };
 
 #ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC
@@ -496,6 +497,12 @@ static void atmel_aes_authenc_complete(struct 
atmel_aes_dev *dd, int err);
 
 static inline int atmel_aes_complete(struct atmel_aes_dev *dd, int err)
 {
+   struct ablkcipher_request *req = ablkcipher_request_cast(dd->areq);
+   struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
+   struct atmel_aes_reqctx *rctx = ablkcipher_request_ctx(req);
+   int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
+   bool enc = atmel_aes_is_encrypt(dd);
+
 #ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC
atmel_aes_authenc_complete(dd, err);
 #endif
@@ -503,6 +510,15 @@ static inline int atmel_aes_complete(struct atmel_aes_dev 
*dd, int err)
clk_disable(dd->iclk);
dd->flags &= ~AES_FLAGS_BUSY;
 
+   if (enc) {
+   scatterwalk_map_and_copy(req->info, req->dst,
+req->nbytes - ivsize, ivsize, 0);
+   } else if (rctx->backup_info) {
+   memcpy(req->info, rctx->backup_info, ivsize);
+   kfree(rctx->backup_info);
+   rctx->backup_info = NULL;
+   }
+
if (dd->is_async)
dd->areq->complete(dd->areq, err);
 
@@ -959,13 +975,25 @@ static int atmel_aes_transfer_complete(struct 
atmel_aes_dev *dd)
 static int atmel_aes_start(struct atmel_aes_dev *dd)
 {
struct ablkcipher_request *req = ablkcipher_request_cast(dd->areq);
+   struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
struct atmel_aes_reqctx *rctx = ablkcipher_request_ctx(req);
+   int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
+   bool enc = atmel_aes_is_encrypt(dd);
bool use_dma = (req->nbytes >= ATMEL_AES_DMA_THRESHOLD ||
dd->ctx->block_size != AES_BLOCK_SIZE);
int err;
 
atmel_aes_set_mode(dd, rctx);
 
+   if (!enc) {
+   rctx->backup_info = kzalloc(ivsize, GFP_KERNEL);
+   if (rctx->backup_info == NULL)
+   return atmel_aes_complete(dd, -ENOMEM);
+
+   scatterwalk_map_and_copy(rctx->backup_info, req->src,
+(req->nbytes - ivsize), ivsize, 0);
+   }
+
err = atmel_aes_hw_init(dd);
if (err)
return atmel_aes_complete(dd, err);
-- 
2.11.0



Re: [PATCH] iommu/vt-d: Fix scatterlist offset handling

2017-10-06 Thread Joerg Roedel
On Tue, Oct 03, 2017 at 07:05:17PM +0100, Robin Murphy wrote:
> Now, there are indeed plenty of drivers and subsystems which do work on
> lists of explicitly single pages - anything doing some variant of
> "addr = kmap_atomic(sg_page(sg)) + sg->offset;" is easy to spot - but I
> don't think DMA API implementations are in a position to make any kind
> of assumption; nearly all of them just shut up and handle sg->length
> bytes from sg_phys(sg) without questioning the caller, and I reckon
> that's exactly what they should be doing.

I agree with that, it is not explicitly forbidden to have an
sg->offset > PAGE_SIZE and most IOMMU drivers handle this case.

So this is a problem I'd like to see resolved in the VT-d driver too. If
nobody comes up with a correct fix soon I'll apply this one and rip out
the large-page support from __domain_mapping() to make it work.

Speaking of __domain_mapping(), this function is a big unmaintainable
mess which should be split and rewritten. A clean and maintainable
rewrite can alse re-add the large-page support.


Regards,

Joerg



Hi

2017-10-06 Thread moses mahadum
Hello, please did you receive my previous email to you?


[PATCH 00/18] crypto: talitos - fixes and performance improvement

2017-10-06 Thread Christophe Leroy
This serie fixes and improves the talitos crypto driver.

First 6 patchs are fixes of failures reported by the new tests in the
kernel crypto test manager.

The 8 following patches are cleanups and simplifications.

The last 4 ones are performance improvement. The main improvement is
in the one before the last, it divides by 2 the time needed for a md5
hash on the SEC1.

Christophe Leroy (18):
  crypto: talitos - fix AEAD test failures
  crypto: talitos - fix memory corruption on SEC2
  crypto: talitos - fix setkey to check key weakness
  crypto: talitos - fix AEAD for sha224 on non sha224 capable chips
  crypto: talitos - fix use of sg_link_tbl_len
  crypto: talitos - fix ctr-aes-talitos
  crypto: talitos - zeroize the descriptor with memset()
  crypto: talitos - declare local functions static
  crypto: talitos - use devm_kmalloc()
  crypto: talitos - use of_property_read_u32()
  crypto: talitos - use devm_ioremap()
  crypto: talitos - don't check the number of channels at each interrupt
  crypto: talitos - remove to_talitos_ptr_len()
  crypto: talitos - simplify tests in ipsec_esp()
  crypto: talitos - DMA map key in setkey()
  crypto: talitos - do hw_context DMA mapping outside the requests
  crypto: talitos - chain in buffered data for ahash on SEC1
  crypto: talitos - avoid useless copy

 drivers/crypto/talitos.c | 544 ++-
 drivers/crypto/talitos.h |   7 +-
 2 files changed, 356 insertions(+), 195 deletions(-)

-- 
2.13.3



[PATCH 01/18] crypto: talitos - fix AEAD test failures

2017-10-06 Thread Christophe Leroy
AEAD tests fail when destination SG list has more than 1 element.

[2.058752] alg: aead: Test 1 failed on encryption for 
authenc-hmac-sha1-cbc-aes-talitos
[2.066965] : 53 69 6e 67 6c 65 20 62 6c 6f 63 6b 20 6d 73 67
0010: c0 43 ff 74 c0 43 ff e0 de 83 d1 20 de 84 8e 54
0020: de 83 d7 c4
[2.082138] alg: aead: Test 1 failed on encryption for 
authenc-hmac-sha1-cbc-aes-talitos
[2.090435] : 53 69 6e 67 6c 65 20 62 6c 6f 63 6b 20 6d 73 67
0010: de 84 ea 58 c0 93 1a 24 de 84 e8 59 de 84 f1 20
0020: 00 00 00 00
[2.105721] alg: aead: Test 1 failed on encryption for 
authenc-hmac-sha1-cbc-3des-talitos
[2.114259] : 6f 54 20 6f 61 4d 79 6e 53 20 63 65 65 72 73 74
0010: 54 20 6f 6f 4d 20 6e 61 20 79 65 53 72 63 74 65
0020: 20 73 6f 54 20 6f 61 4d 79 6e 53 20 63 65 65 72
0030: 73 74 54 20 6f 6f 4d 20 6e 61 20 79 65 53 72 63
0040: 74 65 20 73 6f 54 20 6f 61 4d 79 6e 53 20 63 65
0050: 65 72 73 74 54 20 6f 6f 4d 20 6e 61 20 79 65 53
0060: 72 63 74 65 20 73 6f 54 20 6f 61 4d 79 6e 53 20
0070: 63 65 65 72 73 74 54 20 6f 6f 4d 20 6e 61 0a 79
0080: c0 50 f1 ac c0 50 f3 38 c0 50 f3 94 c0 50 f5 30
0090: c0 99 74 3c
[2.166410] alg: aead: Test 1 failed on encryption for 
authenc-hmac-sha1-cbc-3des-talitos
[2.174794] : 6f 54 20 6f 61 4d 79 6e 53 20 63 65 65 72 73 74
0010: 54 20 6f 6f 4d 20 6e 61 20 79 65 53 72 63 74 65
0020: 20 73 6f 54 20 6f 61 4d 79 6e 53 20 63 65 65 72
0030: 73 74 54 20 6f 6f 4d 20 6e 61 20 79 65 53 72 63
0040: 74 65 20 73 6f 54 20 6f 61 4d 79 6e 53 20 63 65
0050: 65 72 73 74 54 20 6f 6f 4d 20 6e 61 20 79 65 53
0060: 72 63 74 65 20 73 6f 54 20 6f 61 4d 79 6e 53 20
0070: 63 65 65 72 73 74 54 20 6f 6f 4d 20 6e 61 0a 79
0080: c0 50 f1 ac c0 50 f3 38 c0 50 f3 94 c0 50 f5 30
0090: c0 99 74 3c
[2.226486] alg: No test for authenc(hmac(sha224),cbc(aes)) 
(authenc-hmac-sha224-cbc-aes-talitos)
[2.236459] alg: No test for authenc(hmac(sha224),cbc(aes)) 
(authenc-hmac-sha224-cbc-aes-talitos)
[2.247196] alg: aead: Test 1 failed on encryption for 
authenc-hmac-sha224-cbc-3des-talitos
[2.25] : 6f 54 20 6f 61 4d 79 6e 53 20 63 65 65 72 73 74
0010: 54 20 6f 6f 4d 20 6e 61 20 79 65 53 72 63 74 65
0020: 20 73 6f 54 20 6f 61 4d 79 6e 53 20 63 65 65 72
0030: 73 74 54 20 6f 6f 4d 20 6e 61 20 79 65 53 72 63
0040: 74 65 20 73 6f 54 20 6f 61 4d 79 6e 53 20 63 65
0050: 65 72 73 74 54 20 6f 6f 4d 20 6e 61 20 79 65 53
0060: 72 63 74 65 20 73 6f 54 20 6f 61 4d 79 6e 53 20
0070: 63 65 65 72 73 74 54 20 6f 6f 4d 20 6e 61 0a 79
0080: c0 50 f1 ac c0 50 f3 38 c0 50 f3 94 c0 50 f5 30
0090: c0 99 74 3c c0 96 e5 b8
[2.309004] alg: aead: Test 1 failed on encryption for 
authenc-hmac-sha224-cbc-3des-talitos
[2.317562] : 6f 54 20 6f 61 4d 79 6e 53 20 63 65 65 72 73 74
0010: 54 20 6f 6f 4d 20 6e 61 20 79 65 53 72 63 74 65
0020: 20 73 6f 54 20 6f 61 4d 79 6e 53 20 63 65 65 72
0030: 73 74 54 20 6f 6f 4d 20 6e 61 20 79 65 53 72 63
0040: 74 65 20 73 6f 54 20 6f 61 4d 79 6e 53 20 63 65
0050: 65 72 73 74 54 20 6f 6f 4d 20 6e 61 20 79 65 53
0060: 72 63 74 65 20 73 6f 54 20 6f 61 4d 79 6e 53 20
0070: 63 65 65 72 73 74 54 20 6f 6f 4d 20 6e 61 0a 79
0080: c0 50 f1 ac c0 50 f3 38 c0 50 f3 94 c0 50 f5 30
0090: c0 99 74 3c c0 96 e5 b8
[2.370710] alg: aead: Test 1 failed on encryption for 
authenc-hmac-sha256-cbc-aes-talitos
[2.379177] : 53 69 6e 67 6c 65 20 62 6c 6f 63 6b 20 6d 73 67
0010: 54 20 6f 6f 4d 20 6e 61 20 79 65 53 72 63 74 65
0020: 20 73 6f 54 20 6f 61 4d 79 6e 53 20 63 65 65 72
[2.397863] alg: aead: Test 1 failed on encryption for 
authenc-hmac-sha256-cbc-aes-talitos
[2.406134] : 53 69 6e 67 6c 65 20 62 6c 6f 63 6b 20 6d 73 67
0010: 54 20 6f 6f 4d 20 6e 61 20 79 65 53 72 63 74 65
0020: 20 73 6f 54 20 6f 61 4d 79 6e 53 20 63 65 65 72
[2.424789] alg: aead: Test 1 failed on encryption for 
authenc-hmac-sha256-cbc-3des-talitos
[2.433491] : 6f 54 20 6f 61 4d 79 6e 53 20 63 65 65 72 73 74
0010: 54 20 6f 6f 4d 20 6e 61 20 79 65 53 72 63 74 65
0020: 20 73 6f 54 20 6f 61 4d 79 6e 53 20 63 65 65 72
0030: 73 74 54 20 6f 6f 4d 20 6e 61 20 79 65 53 72 63
0040: 74 65 20 73 6f 54 20 6f 61 4d 79 6e 53 20 63 65
0050: 65 72 73 74 54 20 6f 6f 4d 20 6e 61 20 79 65 53
0060: 72 63 74 65 20 73 6f 54 20 6f 61 4d 79 6e 53 20
0070: 63 65 65 72 73 74 54 20 6f 6f 4d 20 6e 61 0a 79
0080: c0 50 f1 ac c0 50 f3 38 c0 50 f3 94 c0 50 f5 30
0090: c0 99 74 3c c0 96 e5 b8 c0 96 e9 20 c0 00 3d dc
[2.488832] alg: aead: Test 1 failed on encryption for 
authenc-hmac-sha256-cbc-3des-talitos
[2.497387] : 6f 54 20 6f 61 4d 79 6e 53 20 63 65 65 72 73 74
0010: 54 20 6f 6f 4d 20 6e 61 20 79 65 53 72 63 74 65
0020: 20 73 6f 54 20 6f 61 4d 79 6e 53 20 63 65 65 72
0030: 73 74 54 20 6f 6f 4d 20 6e 61 20 79 65 53 

[PATCH 05/18] crypto: talitos - fix use of sg_link_tbl_len

2017-10-06 Thread Christophe Leroy
sg_link_tbl_len shall be used instead of cryptlen, otherwise
SECs which perform HW CICV verification will fail.

Signed-off-by: Christophe Leroy 
---
 drivers/crypto/talitos.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index b7184f305867..cf5c9701b898 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1232,8 +1232,8 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
sg_link_tbl_len += authsize;
}
 
-   ret = talitos_sg_map(dev, areq->src, cryptlen, edesc, >ptr[4],
-sg_count, areq->assoclen, tbl_off);
+   ret = talitos_sg_map(dev, areq->src, sg_link_tbl_len, edesc,
+>ptr[4], sg_count, areq->assoclen, tbl_off);
 
if (ret > 1) {
tbl_off += ret;
-- 
2.13.3



[PATCH 03/18] crypto: talitos - fix setkey to check key weakness

2017-10-06 Thread Christophe Leroy
Crypto manager test report the following failures:
[3.061081] alg: skcipher: setkey failed on test 5 for ecb-des-talitos: 
flags=100
[3.069342] alg: skcipher-ddst: setkey failed on test 5 for ecb-des-talitos: 
flags=100
[3.077754] alg: skcipher-ddst: setkey failed on test 5 for ecb-des-talitos: 
flags=100

This is due to setkey being expected to detect weak keys.

Signed-off-by: Christophe Leroy 
---
 drivers/crypto/talitos.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 1e799886c57d..8aa1212086f4 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1507,12 +1507,20 @@ static int ablkcipher_setkey(struct crypto_ablkcipher 
*cipher,
 const u8 *key, unsigned int keylen)
 {
struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+   u32 tmp[DES_EXPKEY_WORDS];
 
if (keylen > TALITOS_MAX_KEY_SIZE) {
crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
return -EINVAL;
}
 
+   if (unlikely(crypto_ablkcipher_get_flags(cipher) &
+CRYPTO_TFM_REQ_WEAK_KEY) &&
+   !des_ekey(tmp, key)) {
+   crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_WEAK_KEY);
+   return -EINVAL;
+   }
+
memcpy(>key, key, keylen);
ctx->keylen = keylen;
 
-- 
2.13.3



[PATCH 04/18] crypto: talitos - fix AEAD for sha224 on non sha224 capable chips

2017-10-06 Thread Christophe Leroy
sha224 AEAD test fails with:

[2.803125] talitos ff02.crypto: DEUISR 0x_
[2.808743] talitos ff02.crypto: MDEUISR 0x8010_
[2.814678] talitos ff02.crypto: DESCBUF 0x20731f21_0018
[2.820616] talitos ff02.crypto: DESCBUF 0x0628d64c_0010
[2.826554] talitos ff02.crypto: DESCBUF 0x0631005c_0018
[2.832492] talitos ff02.crypto: DESCBUF 0x0628d664_0008
[2.838430] talitos ff02.crypto: DESCBUF 0x061b13a0_0080
[2.844369] talitos ff02.crypto: DESCBUF 0x0631006c_0080
[2.850307] talitos ff02.crypto: DESCBUF 0x0631006c_0018
[2.856245] talitos ff02.crypto: DESCBUF 0x063100ec_
[2.884972] talitos ff02.crypto: failed to reset channel 0
[2.890503] talitos ff02.crypto: done overflow, internal time out, or 
rngu error: ISR 0x2000_0002
[2.900652] alg: aead: encryption failed on test 1 for 
authenc-hmac-sha224-cbc-3des-talitos: ret=22

This is due to SHA224 not being supported by the HW. Allthough for
hash we are able to init the hash context by SW, it is not
possible for AEAD. Therefore SHA224 AEAD has to be deactivated.

Signed-off-by: Christophe Leroy 
---
 drivers/crypto/talitos.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 8aa1212086f4..b7184f305867 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -3068,6 +3068,11 @@ static struct talitos_crypto_alg 
*talitos_alg_alloc(struct device *dev,
t_alg->algt.alg.aead.setkey = aead_setkey;
t_alg->algt.alg.aead.encrypt = aead_encrypt;
t_alg->algt.alg.aead.decrypt = aead_decrypt;
+   if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
+   !strncmp(alg->cra_name, "authenc(hmac(sha224)", 20)) {
+   kfree(t_alg);
+   return ERR_PTR(-ENOTSUPP);
+   }
break;
case CRYPTO_ALG_TYPE_AHASH:
alg = _alg->algt.alg.hash.halg.base;
-- 
2.13.3



[PATCH 02/18] crypto: talitos - fix memory corruption on SEC2

2017-10-06 Thread Christophe Leroy
On SEC2, when using the old descriptors type (hmac snoop no afeu)
for doing IPsec, the CICV out pointeur points out of the allocated
memory.

[2.502554] 
=
[2.510740] BUG dma-kmalloc-256 (Not tainted): Redzone overwritten
[2.516907] 
-
[2.516907]
[2.526535] Disabling lock debugging due to kernel taint
[2.531845] INFO: 0xde858108-0xde85810b. First byte 0xf8 instead of 0xcc
[2.538549] INFO: Allocated in 0x806181a9 age=0 cpu=0 pid=58
[2.544229]  __kmalloc+0x374/0x564
[2.547649]  talitos_edesc_alloc+0x17c/0x48c
[2.551929]  aead_edesc_alloc+0x80/0x154
[2.555863]  aead_encrypt+0x30/0xe0
[2.559368]  __test_aead+0x5a0/0x1f3c
[2.563042]  test_aead+0x2c/0x110
[2.566371]  alg_test_aead+0x5c/0xf4
[2.569958]  alg_test+0x1dc/0x5a0
[2.573305]  cryptomgr_test+0x50/0x70
[2.576984]  kthread+0xd8/0x134
[2.580155]  ret_from_kernel_thread+0x5c/0x64
[2.584534] INFO: Freed in ipsec_esp_encrypt_done+0x130/0x240 age=6 cpu=0 
pid=0
[2.591839]  ipsec_esp_encrypt_done+0x130/0x240
[2.596395]  flush_channel+0x1dc/0x488
[2.600161]  talitos2_done_4ch+0x30/0x200
[2.604185]  tasklet_action+0xa0/0x13c
[2.607948]  __do_softirq+0x148/0x6cc
[2.611623]  irq_exit+0xc0/0x124
[2.614869]  call_do_irq+0x24/0x3c
[2.618292]  do_IRQ+0x78/0x108
[2.621369]  ret_from_except+0x0/0x14
[2.625055]  finish_task_switch+0x58/0x350
[2.629165]  schedule+0x80/0x134
[2.632409]  schedule_preempt_disabled+0x38/0xc8
[2.637042]  cpu_startup_entry+0xe4/0x190
[2.641074]  start_kernel+0x3f4/0x408
[2.644741]  0x3438
[2.646857] INFO: Slab 0xdffbdb00 objects=9 used=1 fp=0xde8581c0 flags=0x0080
[2.653978] INFO: Object 0xde858008 @offset=8 fp=0xca4395df
[2.653978]
[2.661032] Redzone de858000: cc cc cc cc cc cc cc cc
  
[2.669029] Object de858008: 00 00 00 02 00 00 00 02 00 6b 6b 6b 1e 83 ea 28 
 .kkk...(
[2.677628] Object de858018: 00 00 00 70 1e 85 80 64 ff 73 1d 21 6b 6b 6b 6b 
 ...p...d.s.!
[2.686228] Object de858028: 00 20 00 00 1e 84 17 24 00 10 00 00 1e 85 70 00 
 . .$..p.
[2.694829] Object de858038: 00 18 00 00 1e 84 17 44 00 08 00 00 1e 83 ea 28 
 ...D...(
[2.703430] Object de858048: 00 80 00 00 1e 84 f0 00 00 80 00 00 1e 85 70 10 
 ..p.
[2.712030] Object de858058: 00 20 6b 00 1e 85 80 f4 6b 6b 6b 6b 00 80 02 00 
 . k.
[2.720629] Object de858068: 1e 84 f0 00 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 
 
[2.729230] Object de858078: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 
 
[2.737830] Object de858088: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 
 
[2.746429] Object de858098: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 
 
[2.755029] Object de8580a8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 
 
[2.763628] Object de8580b8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 
 
[2.772229] Object de8580c8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 
 
[2.780829] Object de8580d8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 
 
[2.789430] Object de8580e8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 73 b0 ea 9f 
 s...
[2.798030] Object de8580f8: e8 18 80 d6 56 38 44 c0 db e3 4f 71 f7 ce d1 d3 
 V8D...Oq
[2.806629] Redzone de858108: f8 bd 3e 4f
  ..>O
[2.814279] Padding de8581b0: 5a 5a 5a 5a 5a 5a 5a 5a
  
[2.822283] CPU: 0 PID: 0 Comm: swapper Tainted: GB   
4.9.50-g995be12679 #179
[2.831819] Call Trace:
[2.834301] [dffefd20] [c01aa9a8] check_bytes_and_report+0x100/0x194 
(unreliable)
[2.841801] [dffefd50] [c01aac3c] check_object+0x200/0x530
[2.847306] [dffefd80] [c01ae584] free_debug_processing+0x290/0x690
[2.853585] [dffefde0] [c01aec8c] __slab_free+0x308/0x628
[2.859000] [dffefe80] [c05057f4] ipsec_esp_encrypt_done+0x130/0x240
[2.865378] [dffefeb0] [c05002c4] flush_channel+0x1dc/0x488
[2.870968] [dffeff10] [c05007a8] talitos2_done_4ch+0x30/0x200
[2.876814] [dffeff30] [c002fe38] tasklet_action+0xa0/0x13c
[2.882399] [dffeff60] [c002f118] __do_softirq+0x148/0x6cc
[2.887896] [dffeffd0] [c002f954] irq_exit+0xc0/0x124
[2.892968] [dffefff0] [c0013adc] call_do_irq+0x24/0x3c
[2.898213] [c0d4be00] [c000757c] do_IRQ+0x78/0x108
[2.903113] [c0d4be30] [c0015c08] ret_from_except+0x0/0x14
[2.908634] --- interrupt: 501 at finish_task_switch+0x70/0x350
[2.908634] LR = finish_task_switch+0x58/0x350
[2.919327] [c0d4bf20] [c085e1d4] schedule+0x80/0x134
[2.924398] [c0d4bf50] [c085e2c0] schedule_preempt_disabled+0x38/0xc8
[

[PATCH 08/18] crypto: talitos - declare local functions static

2017-10-06 Thread Christophe Leroy
talitos_handle_buggy_hash() and talitos_sg_map() are only used
locally, make them static

Signed-off-by: Christophe Leroy 
---
 drivers/crypto/talitos.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 266e7e626e12..dd6b1fc90020 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1113,7 +1113,7 @@ static int sg_to_link_tbl_offset(struct scatterlist *sg, 
int sg_count,
return count;
 }
 
-int talitos_sg_map(struct device *dev, struct scatterlist *src,
+static int talitos_sg_map(struct device *dev, struct scatterlist *src,
   unsigned int len, struct talitos_edesc *edesc,
   struct talitos_ptr *ptr,
   int sg_count, unsigned int offset, int tbl_off)
@@ -1721,7 +1721,7 @@ static void ahash_done(struct device *dev,
  * SEC1 doesn't like hashing of 0 sized message, so we do the padding
  * ourself and submit a padded block
  */
-void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
+static void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
   struct talitos_edesc *edesc,
   struct talitos_ptr *ptr)
 {
-- 
2.13.3



[PATCH 09/18] crypto: talitos - use devm_kmalloc()

2017-10-06 Thread Christophe Leroy
Replace kmalloc() by devm_kmalloc()

Signed-off-by: Christophe Leroy 
---
 drivers/crypto/talitos.c | 30 --
 1 file changed, 12 insertions(+), 18 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index dd6b1fc90020..2a53d0f2a869 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -2993,17 +2993,11 @@ static int talitos_remove(struct platform_device *ofdev)
break;
}
list_del(_alg->entry);
-   kfree(t_alg);
}
 
if (hw_supports(dev, DESC_HDR_SEL0_RNG))
talitos_unregister_rng(dev);
 
-   for (i = 0; priv->chan && i < priv->num_channels; i++)
-   kfree(priv->chan[i].fifo);
-
-   kfree(priv->chan);
-
for (i = 0; i < 2; i++)
if (priv->irq[i]) {
free_irq(priv->irq[i], dev);
@@ -3016,8 +3010,6 @@ static int talitos_remove(struct platform_device *ofdev)
 
iounmap(priv->reg);
 
-   kfree(priv);
-
return 0;
 }
 
@@ -3029,7 +3021,8 @@ static struct talitos_crypto_alg 
*talitos_alg_alloc(struct device *dev,
struct talitos_crypto_alg *t_alg;
struct crypto_alg *alg;
 
-   t_alg = kzalloc(sizeof(struct talitos_crypto_alg), GFP_KERNEL);
+   t_alg = devm_kzalloc(dev, sizeof(struct talitos_crypto_alg),
+GFP_KERNEL);
if (!t_alg)
return ERR_PTR(-ENOMEM);
 
@@ -3053,7 +3046,7 @@ static struct talitos_crypto_alg 
*talitos_alg_alloc(struct device *dev,
t_alg->algt.alg.aead.decrypt = aead_decrypt;
if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
!strncmp(alg->cra_name, "authenc(hmac(sha224)", 20)) {
-   kfree(t_alg);
+   devm_kfree(dev, t_alg);
return ERR_PTR(-ENOTSUPP);
}
break;
@@ -3073,7 +3066,7 @@ static struct talitos_crypto_alg 
*talitos_alg_alloc(struct device *dev,
 
if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
!strncmp(alg->cra_name, "hmac", 4)) {
-   kfree(t_alg);
+   devm_kfree(dev, t_alg);
return ERR_PTR(-ENOTSUPP);
}
if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
@@ -3088,7 +3081,7 @@ static struct talitos_crypto_alg 
*talitos_alg_alloc(struct device *dev,
break;
default:
dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type);
-   kfree(t_alg);
+   devm_kfree(dev, t_alg);
return ERR_PTR(-EINVAL);
}
 
@@ -3169,7 +3162,7 @@ static int talitos_probe(struct platform_device *ofdev)
int i, err;
int stride;
 
-   priv = kzalloc(sizeof(struct talitos_private), GFP_KERNEL);
+   priv = devm_kzalloc(dev, sizeof(struct talitos_private), GFP_KERNEL);
if (!priv)
return -ENOMEM;
 
@@ -3267,8 +3260,8 @@ static int talitos_probe(struct platform_device *ofdev)
}
}
 
-   priv->chan = kzalloc(sizeof(struct talitos_channel) *
-priv->num_channels, GFP_KERNEL);
+   priv->chan = devm_kzalloc(dev, sizeof(struct talitos_channel) *
+  priv->num_channels, GFP_KERNEL);
if (!priv->chan) {
dev_err(dev, "failed to allocate channel management space\n");
err = -ENOMEM;
@@ -3285,8 +3278,9 @@ static int talitos_probe(struct platform_device *ofdev)
spin_lock_init(>chan[i].head_lock);
spin_lock_init(>chan[i].tail_lock);
 
-   priv->chan[i].fifo = kzalloc(sizeof(struct talitos_request) *
-priv->fifo_len, GFP_KERNEL);
+   priv->chan[i].fifo = devm_kzalloc(dev,
+   sizeof(struct talitos_request) *
+   priv->fifo_len, GFP_KERNEL);
if (!priv->chan[i].fifo) {
dev_err(dev, "failed to allocate request fifo %d\n", i);
err = -ENOMEM;
@@ -3352,7 +3346,7 @@ static int talitos_probe(struct platform_device *ofdev)
if (err) {
dev_err(dev, "%s alg registration failed\n",
alg->cra_driver_name);
-   kfree(t_alg);
+   devm_kfree(dev, t_alg);
} else
list_add_tail(_alg->entry, >alg_list);
}
-- 
2.13.3



[PATCH 12/18] crypto: talitos - don't check the number of channels at each interrupt

2017-10-06 Thread Christophe Leroy
The number of channels is known from the beginning, no need to
test it everytime.
This patch defines two additional done functions handling only channel 0.
Then the probe registers the correct one based on the number of channels.

Signed-off-by: Christophe Leroy 
---
 drivers/crypto/talitos.c | 27 +++
 drivers/crypto/talitos.h |  4 
 2 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 83b2a70a1ba7..e7e1bada03df 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -390,8 +390,6 @@ static void talitos1_done_##name(unsigned long data)
\
\
if (ch_done_mask & 0x1000)  \
flush_channel(dev, 0, 0, 0);\
-   if (priv->num_channels == 1)\
-   goto out;   \
if (ch_done_mask & 0x4000)  \
flush_channel(dev, 1, 0, 0);\
if (ch_done_mask & 0x0001)  \
@@ -399,7 +397,6 @@ static void talitos1_done_##name(unsigned long data)
\
if (ch_done_mask & 0x0004)  \
flush_channel(dev, 3, 0, 0);\
\
-out:   \
/* At this point, all completed channels have been processed */ \
/* Unmask done interrupts for channels completed later on. */   \
spin_lock_irqsave(>reg_lock, flags);  \
@@ -409,6 +406,7 @@ out:
\
 }
 
 DEF_TALITOS1_DONE(4ch, TALITOS1_ISR_4CHDONE)
+DEF_TALITOS1_DONE(ch0, TALITOS1_ISR_CH_0_DONE)
 
 #define DEF_TALITOS2_DONE(name, ch_done_mask)  \
 static void talitos2_done_##name(unsigned long data)   \
@@ -419,8 +417,6 @@ static void talitos2_done_##name(unsigned long data)
\
\
if (ch_done_mask & 1)   \
flush_channel(dev, 0, 0, 0);\
-   if (priv->num_channels == 1)\
-   goto out;   \
if (ch_done_mask & (1 << 2))\
flush_channel(dev, 1, 0, 0);\
if (ch_done_mask & (1 << 4))\
@@ -428,7 +424,6 @@ static void talitos2_done_##name(unsigned long data)
\
if (ch_done_mask & (1 << 6))\
flush_channel(dev, 3, 0, 0);\
\
-out:   \
/* At this point, all completed channels have been processed */ \
/* Unmask done interrupts for channels completed later on. */   \
spin_lock_irqsave(>reg_lock, flags);  \
@@ -438,6 +433,7 @@ out:
\
 }
 
 DEF_TALITOS2_DONE(4ch, TALITOS2_ISR_4CHDONE)
+DEF_TALITOS2_DONE(ch0, TALITOS2_ISR_CH_0_DONE)
 DEF_TALITOS2_DONE(ch0_2, TALITOS2_ISR_CH_0_2_DONE)
 DEF_TALITOS2_DONE(ch1_3, TALITOS2_ISR_CH_1_3_DONE)
 
@@ -3237,17 +3233,24 @@ static int talitos_probe(struct platform_device *ofdev)
goto err_out;
 
if (of_device_is_compatible(np, "fsl,sec1.0")) {
-   tasklet_init(>done_task[0], talitos1_done_4ch,
-(unsigned long)dev);
-   } else {
-   if (!priv->irq[1]) {
-   tasklet_init(>done_task[0], talitos2_done_4ch,
+   if (priv->num_channels == 1)
+   tasklet_init(>done_task[0], talitos1_done_ch0,
 (unsigned long)dev);
-   } else {
+   else
+   tasklet_init(>done_task[0], talitos1_done_4ch,
+(unsigned long)dev);
+   } else {
+   if (priv->irq[1]) {
tasklet_init(>done_task[0], talitos2_done_ch0_2,
 (unsigned long)dev);
tasklet_init(>done_task[1], talitos2_done_ch1_3,
 (unsigned long)dev);
+   } else if (priv->num_channels == 1) {
+   

[PATCH 10/18] crypto: talitos - use of_property_read_u32()

2017-10-06 Thread Christophe Leroy
Use of_property_read_u32() to simplify DT read

Signed-off-by: Christophe Leroy 
---
 drivers/crypto/talitos.c | 21 +
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 2a53d0f2a869..f139a0cef2e2 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -3158,7 +3158,6 @@ static int talitos_probe(struct platform_device *ofdev)
struct device *dev = >dev;
struct device_node *np = ofdev->dev.of_node;
struct talitos_private *priv;
-   const unsigned int *prop;
int i, err;
int stride;
 
@@ -3182,21 +3181,11 @@ static int talitos_probe(struct platform_device *ofdev)
}
 
/* get SEC version capabilities from device tree */
-   prop = of_get_property(np, "fsl,num-channels", NULL);
-   if (prop)
-   priv->num_channels = *prop;
-
-   prop = of_get_property(np, "fsl,channel-fifo-len", NULL);
-   if (prop)
-   priv->chfifo_len = *prop;
-
-   prop = of_get_property(np, "fsl,exec-units-mask", NULL);
-   if (prop)
-   priv->exec_units = *prop;
-
-   prop = of_get_property(np, "fsl,descriptor-types-mask", NULL);
-   if (prop)
-   priv->desc_types = *prop;
+   of_property_read_u32(np, "fsl,num-channels", >num_channels);
+   of_property_read_u32(np, "fsl,channel-fifo-len", >chfifo_len);
+   of_property_read_u32(np, "fsl,exec-units-mask", >exec_units);
+   of_property_read_u32(np, "fsl,descriptor-types-mask",
+>desc_types);
 
if (!is_power_of_2(priv->num_channels) || !priv->chfifo_len ||
!priv->exec_units || !priv->desc_types) {
-- 
2.13.3



[PATCH 14/18] crypto: talitos - simplify tests in ipsec_esp()

2017-10-06 Thread Christophe Leroy
Do (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP) only once.
Limit number of if/else paths

Signed-off-by: Christophe Leroy 
---
 drivers/crypto/talitos.c | 42 --
 1 file changed, 20 insertions(+), 22 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 7e96db75347a..307d534a0f2f 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -938,12 +938,15 @@ static void ipsec_esp_unmap(struct device *dev,
struct crypto_aead *aead = crypto_aead_reqtfm(areq);
struct talitos_ctx *ctx = crypto_aead_ctx(aead);
unsigned int ivsize = crypto_aead_ivsize(aead);
+   bool is_ipsec_esp = edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP;
+   struct talitos_ptr *civ_ptr = >desc.ptr[is_ipsec_esp ? 2 : 3];
+   struct talitos_ptr *ckey_ptr = >desc.ptr[is_ipsec_esp ? 3 : 2];
 
-   if (edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP)
+   if (is_ipsec_esp)
unmap_single_talitos_ptr(dev, >desc.ptr[6],
 DMA_FROM_DEVICE);
-   unmap_single_talitos_ptr(dev, >desc.ptr[3], DMA_TO_DEVICE);
-   unmap_single_talitos_ptr(dev, >desc.ptr[2], DMA_TO_DEVICE);
+   unmap_single_talitos_ptr(dev, ckey_ptr, DMA_TO_DEVICE);
+   unmap_single_talitos_ptr(dev, civ_ptr, DMA_TO_DEVICE);
unmap_single_talitos_ptr(dev, >desc.ptr[0], DMA_TO_DEVICE);
 
talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->cryptlen,
@@ -953,7 +956,7 @@ static void ipsec_esp_unmap(struct device *dev,
dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
 DMA_BIDIRECTIONAL);
 
-   if (!(edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP)) {
+   if (!is_ipsec_esp) {
unsigned int dst_nents = edesc->dst_nents ? : 1;
 
sg_pcopy_to_buffer(areq->dst, dst_nents, ctx->iv, ivsize,
@@ -1156,6 +1159,9 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
bool sync_needed = false;
struct talitos_private *priv = dev_get_drvdata(dev);
bool is_sec1 = has_ftr_sec1(priv);
+   bool is_ipsec_esp = desc->hdr & DESC_HDR_TYPE_IPSEC_ESP;
+   struct talitos_ptr *civ_ptr = >ptr[is_ipsec_esp ? 2 : 3];
+   struct talitos_ptr *ckey_ptr = >ptr[is_ipsec_esp ? 3 : 2];
 
/* hmac key */
map_single_talitos_ptr(dev, >ptr[0], ctx->authkeylen, >key,
@@ -1180,20 +1186,12 @@ static int ipsec_esp(struct talitos_edesc *edesc, 
struct aead_request *areq,
}
 
/* cipher iv */
-   if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)
-   to_talitos_ptr(>ptr[2], edesc->iv_dma, ivsize, is_sec1);
-   else
-   to_talitos_ptr(>ptr[3], edesc->iv_dma, ivsize, is_sec1);
+   to_talitos_ptr(civ_ptr, edesc->iv_dma, ivsize, is_sec1);
 
/* cipher key */
-   if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)
-   map_single_talitos_ptr(dev, >ptr[3], ctx->enckeylen,
-  (char *)>key + ctx->authkeylen,
-  DMA_TO_DEVICE);
-   else
-   map_single_talitos_ptr(dev, >ptr[2], ctx->enckeylen,
-  (char *)>key + ctx->authkeylen,
-  DMA_TO_DEVICE);
+   map_single_talitos_ptr(dev, ckey_ptr, ctx->enckeylen,
+  (char *)>key + ctx->authkeylen,
+  DMA_TO_DEVICE);
 
/*
 * cipher in
@@ -1203,10 +1201,10 @@ static int ipsec_esp(struct talitos_edesc *edesc, 
struct aead_request *areq,
 */
sg_link_tbl_len = cryptlen;
 
-   if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP) {
+   if (is_ipsec_esp) {
to_talitos_ptr_ext_set(>ptr[4], authsize, is_sec1);
 
-   if (edesc->desc.hdr & DESC_HDR_MODE1_MDEU_CICV)
+   if (desc->hdr & DESC_HDR_MODE1_MDEU_CICV)
sg_link_tbl_len += authsize;
}
 
@@ -1228,7 +1226,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, >ptr[5],
 sg_count, areq->assoclen, tbl_off);
 
-   if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)
+   if (is_ipsec_esp)
to_talitos_ptr_ext_or(>ptr[5], authsize, is_sec1);
 
/* ICV data */
@@ -1237,7 +1235,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
edesc->icv_ool = true;
sync_needed = true;
 
-   if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP) {
+   if (is_ipsec_esp) {
struct talitos_ptr *tbl_ptr = >link_tbl[tbl_off];
int offset = (edesc->src_nents + edesc->dst_nents + 2) *
 sizeof(struct talitos_ptr) + authsize;
@@ -1260,7 +1258,7 @@ static int 

[PATCH 15/18] crypto: talitos - DMA map key in setkey()

2017-10-06 Thread Christophe Leroy
dma_map_single() is an heavy operation which doesn't need to
be done at each request as the key doesn't change.

Instead of DMA mapping the key at every request, this patch maps it
once in setkey()

Signed-off-by: Christophe Leroy 
---
 drivers/crypto/talitos.c | 56 +---
 1 file changed, 39 insertions(+), 17 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 307d534a0f2f..ebfd6d982ed6 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -815,6 +815,7 @@ struct talitos_ctx {
__be32 desc_hdr_template;
u8 key[TALITOS_MAX_KEY_SIZE];
u8 iv[TALITOS_MAX_IV_LENGTH];
+   dma_addr_t dma_key;
unsigned int keylen;
unsigned int enckeylen;
unsigned int authkeylen;
@@ -851,6 +852,7 @@ static int aead_setkey(struct crypto_aead *authenc,
   const u8 *key, unsigned int keylen)
 {
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
+   struct device *dev = ctx->dev;
struct crypto_authenc_keys keys;
 
if (crypto_authenc_extractkeys(, key, keylen) != 0)
@@ -859,12 +861,17 @@ static int aead_setkey(struct crypto_aead *authenc,
if (keys.authkeylen + keys.enckeylen > TALITOS_MAX_KEY_SIZE)
goto badkey;
 
+   if (ctx->keylen)
+   dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
+
memcpy(ctx->key, keys.authkey, keys.authkeylen);
memcpy(>key[keys.authkeylen], keys.enckey, keys.enckeylen);
 
ctx->keylen = keys.authkeylen + keys.enckeylen;
ctx->enckeylen = keys.enckeylen;
ctx->authkeylen = keys.authkeylen;
+   ctx->dma_key = dma_map_single(dev, ctx->key, ctx->keylen,
+ DMA_TO_DEVICE);
 
return 0;
 
@@ -940,14 +947,11 @@ static void ipsec_esp_unmap(struct device *dev,
unsigned int ivsize = crypto_aead_ivsize(aead);
bool is_ipsec_esp = edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP;
struct talitos_ptr *civ_ptr = >desc.ptr[is_ipsec_esp ? 2 : 3];
-   struct talitos_ptr *ckey_ptr = >desc.ptr[is_ipsec_esp ? 3 : 2];
 
if (is_ipsec_esp)
unmap_single_talitos_ptr(dev, >desc.ptr[6],
 DMA_FROM_DEVICE);
-   unmap_single_talitos_ptr(dev, ckey_ptr, DMA_TO_DEVICE);
unmap_single_talitos_ptr(dev, civ_ptr, DMA_TO_DEVICE);
-   unmap_single_talitos_ptr(dev, >desc.ptr[0], DMA_TO_DEVICE);
 
talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->cryptlen,
 areq->assoclen);
@@ -976,6 +980,7 @@ static void ipsec_esp_encrypt_done(struct device *dev,
struct aead_request *areq = context;
struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
unsigned int authsize = crypto_aead_authsize(authenc);
+   unsigned int ivsize = crypto_aead_ivsize(authenc);
struct talitos_edesc *edesc;
struct scatterlist *sg;
void *icvdata;
@@ -996,6 +1001,8 @@ static void ipsec_esp_encrypt_done(struct device *dev,
   icvdata, authsize);
}
 
+   dma_unmap_single(dev, edesc->iv_dma, ivsize, DMA_TO_DEVICE);
+
kfree(edesc);
 
aead_request_complete(areq, err);
@@ -1164,8 +1171,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
struct talitos_ptr *ckey_ptr = >ptr[is_ipsec_esp ? 3 : 2];
 
/* hmac key */
-   map_single_talitos_ptr(dev, >ptr[0], ctx->authkeylen, >key,
-  DMA_TO_DEVICE);
+   to_talitos_ptr(>ptr[0], ctx->dma_key, ctx->authkeylen, is_sec1);
 
sg_count = edesc->src_nents ?: 1;
if (is_sec1 && sg_count > 1)
@@ -1189,9 +1195,8 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
to_talitos_ptr(civ_ptr, edesc->iv_dma, ivsize, is_sec1);
 
/* cipher key */
-   map_single_talitos_ptr(dev, ckey_ptr, ctx->enckeylen,
-  (char *)>key + ctx->authkeylen,
-  DMA_TO_DEVICE);
+   to_talitos_ptr(ckey_ptr, ctx->dma_key  + ctx->authkeylen,
+  ctx->enckeylen, is_sec1);
 
/*
 * cipher in
@@ -1481,6 +1486,7 @@ static int ablkcipher_setkey(struct crypto_ablkcipher 
*cipher,
 const u8 *key, unsigned int keylen)
 {
struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+   struct device *dev = ctx->dev;
u32 tmp[DES_EXPKEY_WORDS];
 
if (keylen > TALITOS_MAX_KEY_SIZE) {
@@ -1495,9 +1501,14 @@ static int ablkcipher_setkey(struct crypto_ablkcipher 
*cipher,
return -EINVAL;
}
 
+   if (ctx->keylen)
+   dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
+
memcpy(>key, key, keylen);
ctx->keylen = keylen;
 
+   ctx->dma_key = dma_map_single(dev, 

[PATCH 16/18] crypto: talitos - do hw_context DMA mapping outside the requests

2017-10-06 Thread Christophe Leroy
At every request, we map and unmap the same hash hw_context.

This patch moves the dma mapping/unmapping in functions ahash_init()
and ahash_import().

Signed-off-by: Christophe Leroy 
---
 drivers/crypto/talitos.c | 80 ++--
 1 file changed, 57 insertions(+), 23 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index ebfd6d982ed6..d495649d5267 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -819,6 +819,7 @@ struct talitos_ctx {
unsigned int keylen;
unsigned int enckeylen;
unsigned int authkeylen;
+   dma_addr_t dma_hw_context;
 };
 
 #define HASH_MAX_BLOCK_SIZESHA512_BLOCK_SIZE
@@ -1663,18 +1664,9 @@ static void common_nonsnoop_hash_unmap(struct device 
*dev,
   struct ahash_request *areq)
 {
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
-   struct talitos_private *priv = dev_get_drvdata(dev);
-   bool is_sec1 = has_ftr_sec1(priv);
-
-   unmap_single_talitos_ptr(dev, >desc.ptr[5], DMA_FROM_DEVICE);
 
talitos_sg_unmap(dev, edesc, req_ctx->psrc, NULL, 0, 0);
 
-   /* When using hashctx-in, must unmap it. */
-   if (from_talitos_ptr_len(>desc.ptr[1], is_sec1))
-   unmap_single_talitos_ptr(dev, >desc.ptr[1],
-DMA_TO_DEVICE);
-
if (edesc->dma_len)
dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
 DMA_BIDIRECTIONAL);
@@ -1744,10 +1736,8 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
 
/* hash context in */
if (!req_ctx->first || req_ctx->swinit) {
-   map_single_talitos_ptr(dev, >ptr[1],
-  req_ctx->hw_context_size,
-  (char *)req_ctx->hw_context,
-  DMA_TO_DEVICE);
+   to_talitos_ptr(>ptr[1], ctx->dma_hw_context,
+  req_ctx->hw_context_size, is_sec1);
req_ctx->swinit = 0;
}
/* Indicate next op is not the first. */
@@ -1780,9 +1770,8 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
   crypto_ahash_digestsize(tfm),
   areq->result, DMA_FROM_DEVICE);
else
-   map_single_talitos_ptr(dev, >ptr[5],
-  req_ctx->hw_context_size,
-  req_ctx->hw_context, DMA_FROM_DEVICE);
+   to_talitos_ptr(>ptr[5], ctx->dma_hw_context,
+  req_ctx->hw_context_size, is_sec1);
 
/* last DWORD empty */
 
@@ -1815,17 +1804,25 @@ static struct talitos_edesc *ahash_edesc_alloc(struct 
ahash_request *areq,
 static int ahash_init(struct ahash_request *areq)
 {
struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+   struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
+   struct device *dev = ctx->dev;
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+   unsigned int size;
 
/* Initialize the context */
req_ctx->nbuf = 0;
req_ctx->first = 1; /* first indicates h/w must init its context */
req_ctx->swinit = 0; /* assume h/w init of context */
-   req_ctx->hw_context_size =
-   (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
+   size =  (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
: TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
+   req_ctx->hw_context_size = size;
 
+   if (ctx->dma_hw_context)
+   dma_unmap_single(dev, ctx->dma_hw_context, size,
+DMA_BIDIRECTIONAL);
+   ctx->dma_hw_context = dma_map_single(dev, req_ctx->hw_context, size,
+DMA_BIDIRECTIONAL);
return 0;
 }
 
@@ -1836,6 +1833,9 @@ static int ahash_init(struct ahash_request *areq)
 static int ahash_init_sha224_swinit(struct ahash_request *areq)
 {
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+   struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+   struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
+   struct device *dev = ctx->dev;
 
ahash_init(areq);
req_ctx->swinit = 1;/* prevent h/w initting context with sha256 values*/
@@ -1853,6 +1853,9 @@ static int ahash_init_sha224_swinit(struct ahash_request 
*areq)
req_ctx->hw_context[8] = 0;
req_ctx->hw_context[9] = 0;
 
+   dma_sync_single_for_device(dev, ctx->dma_hw_context,
+  req_ctx->hw_context_size, DMA_TO_DEVICE);
+
return 0;
 }
 
@@ -1990,7 +1993,12 @@ static int ahash_export(struct ahash_request *areq, void 

[PATCH 13/18] crypto: talitos - remove to_talitos_ptr_len()

2017-10-06 Thread Christophe Leroy
to_talitos_ptr() and to_talitos_ptr_len() are always called together
in order to fully set a ptr, so lets merge them into a single
helper.

Signed-off-by: Christophe Leroy 
---
 drivers/crypto/talitos.c | 56 ++--
 1 file changed, 21 insertions(+), 35 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index e7e1bada03df..7e96db75347a 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -56,28 +56,26 @@
 #include "talitos.h"
 
 static void to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr,
-  bool is_sec1)
+  unsigned int len, bool is_sec1)
 {
ptr->ptr = cpu_to_be32(lower_32_bits(dma_addr));
-   if (!is_sec1)
+   if (is_sec1) {
+   ptr->len1 = cpu_to_be16(len);
+   } else {
+   ptr->len = cpu_to_be16(len);
ptr->eptr = upper_32_bits(dma_addr);
+   }
 }
 
 static void copy_talitos_ptr(struct talitos_ptr *dst_ptr,
 struct talitos_ptr *src_ptr, bool is_sec1)
 {
dst_ptr->ptr = src_ptr->ptr;
-   if (!is_sec1)
-   dst_ptr->eptr = src_ptr->eptr;
-}
-
-static void to_talitos_ptr_len(struct talitos_ptr *ptr, unsigned int len,
-  bool is_sec1)
-{
if (is_sec1) {
-   ptr->len1 = cpu_to_be16(len);
+   dst_ptr->len1 = src_ptr->len1;
} else {
-   ptr->len = cpu_to_be16(len);
+   dst_ptr->len = src_ptr->len;
+   dst_ptr->eptr = src_ptr->eptr;
}
 }
 
@@ -115,8 +113,7 @@ static void map_single_talitos_ptr(struct device *dev,
struct talitos_private *priv = dev_get_drvdata(dev);
bool is_sec1 = has_ftr_sec1(priv);
 
-   to_talitos_ptr_len(ptr, len, is_sec1);
-   to_talitos_ptr(ptr, dma_addr, is_sec1);
+   to_talitos_ptr(ptr, dma_addr, len, is_sec1);
 }
 
 /*
@@ -1090,8 +1087,7 @@ static int sg_to_link_tbl_offset(struct scatterlist *sg, 
int sg_count,
len = cryptlen;
 
to_talitos_ptr(link_tbl_ptr + count,
-  sg_dma_address(sg) + offset, 0);
-   to_talitos_ptr_len(link_tbl_ptr + count, len, 0);
+  sg_dma_address(sg) + offset, len, 0);
to_talitos_ptr_ext_set(link_tbl_ptr + count, 0, 0);
count++;
cryptlen -= len;
@@ -1117,14 +1113,12 @@ static int talitos_sg_map(struct device *dev, struct 
scatterlist *src,
struct talitos_private *priv = dev_get_drvdata(dev);
bool is_sec1 = has_ftr_sec1(priv);
 
-   to_talitos_ptr_len(ptr, len, is_sec1);
-
if (sg_count == 1) {
-   to_talitos_ptr(ptr, sg_dma_address(src) + offset, is_sec1);
+   to_talitos_ptr(ptr, sg_dma_address(src) + offset, len, is_sec1);
return sg_count;
}
if (is_sec1) {
-   to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, is_sec1);
+   to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, len, is_sec1);
return sg_count;
}
sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len,
@@ -1135,7 +1129,7 @@ static int talitos_sg_map(struct device *dev, struct 
scatterlist *src,
return sg_count;
}
to_talitos_ptr(ptr, edesc->dma_link_tbl +
-   tbl_off * sizeof(struct talitos_ptr), is_sec1);
+   tbl_off * sizeof(struct talitos_ptr), len, is_sec1);
to_talitos_ptr_ext_or(ptr, DESC_PTR_LNKTBL_JUMP, is_sec1);
 
return sg_count;
@@ -1186,13 +1180,10 @@ static int ipsec_esp(struct talitos_edesc *edesc, 
struct aead_request *areq,
}
 
/* cipher iv */
-   if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP) {
-   to_talitos_ptr(>ptr[2], edesc->iv_dma, is_sec1);
-   to_talitos_ptr_len(>ptr[2], ivsize, is_sec1);
-   } else {
-   to_talitos_ptr(>ptr[3], edesc->iv_dma, is_sec1);
-   to_talitos_ptr_len(>ptr[3], ivsize, is_sec1);
-   }
+   if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)
+   to_talitos_ptr(>ptr[2], edesc->iv_dma, ivsize, is_sec1);
+   else
+   to_talitos_ptr(>ptr[3], edesc->iv_dma, ivsize, is_sec1);
 
/* cipher key */
if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)
@@ -1210,8 +1201,6 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
 * extent is bytes of HMAC postpended to ciphertext,
 * typically 12 for ipsec
 */
-   to_talitos_ptr_len(>ptr[4], cryptlen, is_sec1);
-
sg_link_tbl_len = cryptlen;
 
if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP) {
@@ -1257,11 +1246,10 @@ static int ipsec_esp(struct talitos_edesc *edesc, 
struct aead_request *areq,
to_talitos_ptr_ext_set(tbl_ptr - 1, 0, is_sec1);
 

[PATCH 18/18] crypto: talitos - avoid useless copy

2017-10-06 Thread Christophe Leroy
This patch avoids copy of buffered data to hash from bufnext to buf

Signed-off-by: Christophe Leroy 
---
 drivers/crypto/talitos.c | 36 ++--
 1 file changed, 22 insertions(+), 14 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 5c4499a85611..5bd8191405d8 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -842,8 +842,8 @@ struct talitos_ctx {
 struct talitos_ahash_req_ctx {
u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
unsigned int hw_context_size;
-   u8 buf[HASH_MAX_BLOCK_SIZE];
-   u8 bufnext[HASH_MAX_BLOCK_SIZE];
+   u8 buf[2][HASH_MAX_BLOCK_SIZE];
+   int buf_idx;
unsigned int swinit;
unsigned int first;
unsigned int last;
@@ -1709,7 +1709,7 @@ static void ahash_done(struct device *dev,
 
if (!req_ctx->last && req_ctx->to_hash_later) {
/* Position any partial block for next update/final/finup */
-   memcpy(req_ctx->buf, req_ctx->bufnext, req_ctx->to_hash_later);
+   req_ctx->buf_idx = (req_ctx->buf_idx + 1) & 1;
req_ctx->nbuf = req_ctx->to_hash_later;
}
common_nonsnoop_hash_unmap(dev, edesc, areq);
@@ -1789,8 +1789,10 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
 * data in
 */
if (is_sec1 && req_ctx->nbuf) {
-   to_talitos_ptr(>ptr[3], ctx->dma_buf, req_ctx->nbuf,
-  is_sec1);
+   dma_addr_t dma_buf = ctx->dma_buf + req_ctx->buf_idx *
+   HASH_MAX_BLOCK_SIZE;
+
+   to_talitos_ptr(>ptr[3], dma_buf, req_ctx->nbuf, is_sec1);
} else {
sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
  >ptr[3], sg_count, offset, 0);
@@ -1883,6 +1885,7 @@ static int ahash_init(struct ahash_request *areq)
bool is_sec1 = has_ftr_sec1(priv);
 
/* Initialize the context */
+   req_ctx->buf_idx = 0;
req_ctx->nbuf = 0;
req_ctx->first = 1; /* first indicates h/w must init its context */
req_ctx->swinit = 0; /* assume h/w init of context */
@@ -1955,6 +1958,7 @@ static int ahash_process_req(struct ahash_request *areq, 
unsigned int nbytes)
struct talitos_private *priv = dev_get_drvdata(dev);
bool is_sec1 = has_ftr_sec1(priv);
int offset = 0;
+   u8 *ctx_buf = req_ctx->buf[req_ctx->buf_idx];
 
if (!req_ctx->last && (nbytes + req_ctx->nbuf <= blocksize)) {
/* Buffer up to one whole block */
@@ -1964,7 +1968,7 @@ static int ahash_process_req(struct ahash_request *areq, 
unsigned int nbytes)
return nents;
}
sg_copy_to_buffer(areq->src, nents,
- req_ctx->buf + req_ctx->nbuf, nbytes);
+ ctx_buf + req_ctx->nbuf, nbytes);
req_ctx->nbuf += nbytes;
return 0;
}
@@ -1988,7 +1992,7 @@ static int ahash_process_req(struct ahash_request *areq, 
unsigned int nbytes)
if (!is_sec1 && req_ctx->nbuf) {
nsg = (req_ctx->nbuf < nbytes_to_hash) ? 2 : 1;
sg_init_table(req_ctx->bufsl, nsg);
-   sg_set_buf(req_ctx->bufsl, req_ctx->buf, req_ctx->nbuf);
+   sg_set_buf(req_ctx->bufsl, ctx_buf, req_ctx->nbuf);
if (nsg > 1)
sg_chain(req_ctx->bufsl, 2, areq->src);
req_ctx->psrc = req_ctx->bufsl;
@@ -2003,7 +2007,7 @@ static int ahash_process_req(struct ahash_request *areq, 
unsigned int nbytes)
return nents;
}
sg_copy_to_buffer(areq->src, nents,
- req_ctx->buf + req_ctx->nbuf, offset);
+ ctx_buf + req_ctx->nbuf, offset);
req_ctx->nbuf += offset;
req_ctx->psrc = areq->src;
} else
@@ -2016,7 +2020,7 @@ static int ahash_process_req(struct ahash_request *areq, 
unsigned int nbytes)
return nents;
}
sg_pcopy_to_buffer(areq->src, nents,
- req_ctx->bufnext,
+  req_ctx->buf[(req_ctx->buf_idx + 1) & 1],
  to_hash_later,
  nbytes - to_hash_later);
}
@@ -2038,9 +2042,13 @@ static int ahash_process_req(struct ahash_request *areq, 
unsigned int nbytes)
/* request SEC to INIT hash. */
if (req_ctx->first && !req_ctx->swinit)
edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT;
-   if (is_sec1)
-   dma_sync_single_for_device(dev, ctx->dma_buf,
+   if (is_sec1) {
+   dma_addr_t dma_buf = ctx->dma_buf +