Re: [PATCH 2/2] crypto: DRBG - use caller buffer if suitable

2018-07-19 Thread Stephan Mueller



> Am 20.07.2018 um 05:54 schrieb Herbert Xu :
> 
>> On Thu, Jul 19, 2018 at 10:57:16PM +0200, Stephan Müller wrote:
>> 
>> Therefore, I am not sure that either having an SGL interface for the RNG API 
>> or a virtual address interface for the sync skcipher would be helpful.
> 
> Could you please explain again why a virtual address interface to
> sync skcipher algorithms won't be useful? It's something that others
> have asked for in the past too.

Maybe I have a different understanding of how such interface should look like.

Can you give me some more detail on how you envision such virtual address 
interface should work?

Thanks a lot
Stephan


Re: [PATCH] crypto: Add 0 walk-offset check in scatterwalk_pagedone()

2018-07-19 Thread 罗新强
Hi, Eric,
Thanks for your reply. I had tried your program on a original kernel and it 
reproduced the crash. And I also tried the program on a kernel with our patch, 
but there was no crash occur. 
I think the crash reason of the program is that, the parameter buffer is 
aligned with the page and its address starts at the beginning of the page, 
making walk->offset = 0 and generating the crash. I had added log in 
scatterwalk_pagedone() to print value of walk->offset, and the log before the 
crash showed that walk->offset = 0.
And what still confuses me is that why walk->offset = 0 means no data to be 
processed. In the structure scatterlist, the member offset represents the 
offset of the buffer in the page, while the member length represents the length 
of the buffer. In function af_alg_make_sg(), we also can see that, if a buffer 
occupies more than one pages, the offset will be set to 0 in the second and 
following pages. And In function scatterwalk_done(), walk->offset = 0 will also 
allow to call scatterwalk_pagedone(). So I think that walk->offset = 0 needs to 
flush the page as well. 

Thanks.

-邮件原件-
发件人: Eric Biggers [mailto:ebigge...@gmail.com] 
发送时间: 2018年7月15日 22:05
收件人: Liuchao (H) 
抄送: herb...@gondor.apana.org.au; da...@davemloft.net; 
linux-crypto@vger.kernel.org; dongjinguang ; 
ebigg...@google.com; 罗新强 ; gaokui (A) 

主题: Re: [PATCH] crypto: Add 0 walk-offset check in scatterwalk_pagedone()

Hi Liu,

On Mon, Jul 09, 2018 at 05:10:19PM +0800, Liu Chao wrote:
> From: Luo Xinqiang 
> 
> In function scatterwalk_pagedone(), a kernel panic of invalid page 
> will occur if walk->offset equals 0. This patch fixes the problem by 
> setting the page addresswith sg_page(walk->sg) directly if 
> walk->offset equals 0.
> 
> Panic call stack:
> [] blkcipher_walk_done+0x430/0x8dc 
> [] blkcipher_walk_next+0x750/0x9e8 
> [] blkcipher_walk_first+0x110/0x2c0 
> [] blkcipher_walk_virt+0xcc/0xe0 
> [] cbc_decrypt+0xdc/0x1a8 [] 
> ablk_decrypt+0x138/0x224 [] 
> skcipher_decrypt_ablkcipher+0x130/0x150
> [] skcipher_recvmsg_sync.isra.17+0x270/0x404
> [] skcipher_recvmsg+0x98/0xb8 [] 
> SyS_recvfrom+0x2ac/0x2fc [] el0_svc_naked+0x34/0x38
> 
> Test: do syskaller fuzz test on 4.9 & 4.4
> 
> Signed-off-by: Gao Kui 
> Signed-off-by: Luo Xinqiang 
> ---
>  crypto/scatterwalk.c | 6 +-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c index 
> bc769c4..a265907 100644
> --- a/crypto/scatterwalk.c
> +++ b/crypto/scatterwalk.c
> @@ -53,7 +53,11 @@ static void scatterwalk_pagedone(struct scatter_walk 
> *walk, int out,
>   if (out) {
>   struct page *page;
>  
> - page = sg_page(walk->sg) + ((walk->offset - 1) >> PAGE_SHIFT);
> + if (likely(walk->offset))
> + page = sg_page(walk->sg) +
> + ((walk->offset - 1) >> PAGE_SHIFT);
> + else
> + page = sg_page(walk->sg);
>   /* Test ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE first as
>* PageSlab cannot be optimised away per se due to
>* use of volatile pointer.

Interesting, I guess the reason this wasn't found by syzbot yet is that syzbot 
currently only runs on x86, where ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE isn't 
defined.  Otherwise this crash reproduces on the latest kernel by running the 
following program:

#include 
#include 
#include 

int main()
{
struct sockaddr_alg addr = {
.salg_type = "skcipher",
.salg_name = "cbc(aes)",
};
int algfd, reqfd;
char buffer[4096] __attribute__((aligned(4096))) = { 0 };

algfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
bind(algfd, (void *), sizeof(addr));
setsockopt(algfd, SOL_ALG, ALG_SET_KEY, buffer, 32);
reqfd = accept(algfd, NULL, NULL);
write(reqfd, buffer, 15);
read(reqfd, buffer, 15);
}

I don't think your fix makes sense though, because if walk->offset = 0 then no 
data was processed, so there would be no need to flush any page at all.  I 
think the original intent was that scatterwalk_pagedone() only be called when a 
nonzero length was processed.  So a better fix is probably to update
blkcipher_walk_done() (and skcipher_walk_done() and ablkcipher_walk_done()) to 
avoid calling scatterwalk_pagedone() in the error case where no bytes were 
processed.  I'm working on that fix but it's not ready quite yet.

Thanks!

- Eric


Re: [PATCH 2/2] crypto: DRBG - use caller buffer if suitable

2018-07-19 Thread Herbert Xu
On Thu, Jul 19, 2018 at 10:57:16PM +0200, Stephan Müller wrote:
>
> Therefore, I am not sure that either having an SGL interface for the RNG API 
> or a virtual address interface for the sync skcipher would be helpful.

Could you please explain again why a virtual address interface to
sync skcipher algorithms won't be useful? It's something that others
have asked for in the past too.

Thanks,
-- 
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: DRBG - use caller buffer if suitable

2018-07-19 Thread Stephan Müller
Am Donnerstag, 19. Juli 2018, 11:34:33 CEST schrieb Herbert Xu:

Hi Herbert,

> I think this is an abuse of virt_addr_valid.  It's meant to catch
> bogus uses of SG lists, it's not meant to be a guarantee that an
> address can be used on an SG list.

Thanks for your insights.
> 
> A better solution would be either an SG-list interface for rng,
> or alternatively a virtual address interface for sync skcipher.

My goal is to implement an in-place cipher operation drbg_kcapi_sym_ctr 
operating directly on the output buffer if possible. Without knowing whether 
the output buffer is valid for SGLs, I would need to use the scratchpad buffer 
as input/output buffer. That means that the data must be memcpy'ed from the 
scratchpad buffer to the output buffer.

To provide the fastest DRBG implementation, we should eliminate the memcpy in 
drbg_kcapi_sym_ctr and with it the restriction of generating 
DRBG_OUTSCRATCHLEN with one cipher invocation.

I.e. the ultimate goal is to operate directly on the output buffer if at all 
possible.

So far, all RNGs generate data for one buffer only. Thus, I would consider 
converting the RNG interface to use SGLs as overkill. Furthermore, if the RNG 
uses the SHASH ciphers (like the DRBG use case), the input data is expected to 
be a straight buffer.

Also, even the caller of the RNG may not know whether the destination buffer 
is valid for an SGL in case it is an intermediate layer.

Therefore, I am not sure that either having an SGL interface for the RNG API 
or a virtual address interface for the sync skcipher would be helpful.

Is there no way of identifying whether a buffer is valid for SGL operation?

PS: I experimented with the in-place cipher operation in drbg_kcapi_sym_ctr 
while operating directly on the output buffer. The result was a more than 3-
times increase in performance.

Current implementation:

  16 bytes|   12.267661 MB/s|61338304 bytes |  500213 ns
  32 bytes|   23.603770 MB/s|   118018848 bytes |  500073 ns
  64 bytes|   46.732262 MB/s|   233661312 bytes |  500241 ns
 128 bytes|   90.038042 MB/s|   450190208 bytes |  500244 ns
 256 bytes|  160.399616 MB/s|   801998080 bytes |  500393 ns
 512 bytes|  259.878400 MB/s|  1299392000 bytes |  501675 ns
1024 bytes|  386.050662 MB/s|  1930253312 bytes |  501661 ns
2048 bytes|  493.641728 MB/s|  2468208640 bytes |  501598 ns
4096 bytes|  581.835981 MB/s|  2909179904 bytes |  503426 ns

In-place cipher operation directly on output buffer:

  16 bytes|   16.017830 MB/s|80089152 bytes |  500752 ns
  32 bytes|   30.775686 MB/s|   153878432 bytes |  500701 ns
  64 bytes|   58.299430 MB/s|   291497152 bytes |  500466 ns
 128 bytes|  114.847462 MB/s|   574237312 bytes |  500385 ns
 256 bytes|  218.359859 MB/s|  1091799296 bytes |  500476 ns
 512 bytes|  416.003379 MB/s|  2080016896 bytes |  501105 ns
1024 bytes|  714.792346 MB/s|  3573961728 bytes |  5000718637 ns
2048 bytes|1.143480 GB/s|  5717401600 bytes |  500094 ns
4096 bytes|1.609953 GB/s|  8049766400 bytes |  501687 ns

Ciao
Stephan




Re: [PATCH 2/2] crypto: DRBG - use caller buffer if suitable

2018-07-19 Thread Herbert Xu
On Tue, Jul 10, 2018 at 05:57:00PM +0200, Stephan Müller wrote:
> The SGL can directly operate caller-provided memory with the exception
> of stack memory. The DRBG detects whether the caller provided
> non-suitable memory and uses the scratchpad only on those circumstances.
> 
> This patch increases the speed of the CTR DRBG by 1 to 3 percent
> depending on the buffer size of the output buffer.
> 
> Signed-off-by: Stephan Mueller 

I think this is an abuse of virt_addr_valid.  It's meant to catch
bogus uses of SG lists, it's not meant to be a guarantee that an
address can be used on an SG list.

A better solution would be either an SG-list interface for rng,
or alternatively a virtual address interface for sync skcipher.

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


Re: [PATCH] crypto: dh - fix calculating encoded key size

2018-07-19 Thread Herbert Xu
On Wed, Jul 11, 2018 at 09:27:56AM -0700, Eric Biggers wrote:
>
> The callers do check for errors, but at the point of the proposed BUG_ON() a
> buffer overflow may have already occurred, so I think a BUG_ON() would be more
> appropriate than a WARN_ON().  Of course, it would be better to prevent any
> buffer overflow from occurring in the first place, but that's already the
> purpose of the 'len != crypto_dh_key_len(params)' check; the issue was that
> 'crypto_dh_key_len()' calculated the wrong length.

How about adding an end argument to dh_pack_data so that it can
check that the buffer isn't overflown each time it's called?

Then if you cared you could also have one final check at the end
of the function to ensure the buffer is fully used.

As we can easily avoid having a BUG_ON here I think we should since
a BUG_ON would leave the machine unresponsive which should be a
last resort.

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