* [PATCH] crypto/sha1-mb: make sha1_x8_avx2() conform to C function ABI
From: Josh Poimboeuf @ 2016-05-16 20:16 UTC (permalink / raw)
To: Megha Dey; +Cc: Ingo Molnar, Herbert Xu, linux-crypto, linux-kernel
In-Reply-To: <1463423472.5329.6.camel@megha-Z97X-UD7-TH>
On Mon, May 16, 2016 at 11:31:12AM -0700, Megha Dey wrote:
> On Mon, 2016-05-16 at 09:44 -0500, Josh Poimboeuf wrote:
> > On Fri, May 13, 2016 at 10:32:26AM -0700, Megha Dey wrote:
> > > On Fri, 2016-05-13 at 07:51 +0200, Ingo Molnar wrote:
> > > > * Herbert Xu <herbert@gondor.apana.org.au> wrote:
> > > >
> > > > > On Thu, May 12, 2016 at 04:31:06PM -0700, Megha Dey wrote:
> > > > > > Hi,
> > > > > >
> > > > > > When booting latest kernel with the CONFIG_CRYPTO_SHA1_MB enabled, I
> > > > > > observe a panic.
> > > > > >
> > > > > > After having a quick look, on reverting the following patches, I am able
> > > > > > to complete the booting process.
> > > > > > aec4d0e301f17bb143341c82cc44685b8af0b945
> > > > > > 8691ccd764f9ecc69a6812dfe76214c86ac9ba06
> > > > > > 68874ac3304ade7ed5ebb12af00d6b9bbbca0a16
> > > > > >
> > > > > > Of the 3 patches, aec4d0e301f17bb143341c82cc44685b8af0b945 seems wrong.
> > > > > > The r10 to r15 registers are used in sha1_x8_avx2.S, which is called
> > > > > > from sha1_mb_mgr_flush_avx2.S.
> > > > > >
> > > > > > I do not think the functionality of the SHA1-MB crypto algorithm has
> > > > > > been tested after applying these changes. (I am not sure if any of the
> > > > > > other crypto algorithms have been affected by these changes).
> > > > >
> > > > > Josh, Ingo:
> > > > >
> > > > > Any ideas on this? Should we revert?
> > > >
> > > > Yeah, I think so - although another option would be to standardize sha1_x8_avx2()
> > > > - the problem is that it is a function that clobbers registers without
> > > > saving/restoring them, breaking the C function ABI. I realize it's written in
> > > > assembly, but unless there are strong performance reasons to deviate from the
> > > > regular calling convention it might make sense to fix that.
> > > >
> > > > Do any warnings get generated after the revert, if you enable
> > > > CONFIG_STACK_VALIDATION=y?
> > >
> > > After the revert and enabling CONFIG_STACK_VALIDATION:
> > > arch/x86/crypto/sha1-mb/sha1_mb_mgr_flush_avx2.o: warning: objtool:
> > > sha1_mb_mgr_flush_avx2()+0x20d: call without frame pointer save/setup
> > >
> > > arch/x86/crypto/sha1-mb/sha1_mb_mgr_submit_avx2.o: warning: objtool:
> > > sha1_mb_mgr_submit_avx2()+0x115: call without frame pointer save/setup
> >
> > Megha,
> >
> > Sorry for breaking it. I completely missed the fact that the function
> > calls sha1_x8_avx2() which clobbers registers.
> >
> > If the performance penalty isn't too bad, I'll submit a patch to
> > standardize sha1_x8_avx2() to follow the C ABI.
> >
> > Do you have any tips for testing this code? I've tried using the tcrypt
> > module, but no luck.
> >
> Josh,
> Build the kernel with the following configs:
> CONFIG_CRYPTO_SHA1_MB=y
> CONFIG_CRYPTO_TEST=m
> CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=n
> There was a kernel panic while booting.
> So if after applying your new patch, we are able to get complete the
> boot, then we are good.
>
> Could you please send a copy of the patch, I could test it on my end
> too.
Thanks. I was able to run the tests, though I didn't see a panic. Can
you test with this patch?
----
From: Josh Poimboeuf <jpoimboe@redhat.com>
Subject: [PATCH] crypto/sha1-mb: make sha1_x8_avx2() conform to C function ABI
Megha Day reported a kernel panic in crypto code. The problem is that
sha1_x8_avx2() clobbers registers r12-r15 without saving and restoring
them.
Before commit aec4d0e301f1 ("x86/asm/crypto: Simplify stack usage in
sha-mb functions"), those registers were saved and restored by the
callers of the function. I removed them with that commit because I
didn't realize sha1_x8_avx2() clobbered them.
Fix the potential undefined behavior associated with clobbering the
registers and make the behavior less surprising by changing the
registers to be callee saved/restored to conform with the C function
call ABI.
Also, rdx (aka RSP_SAVE) doesn't need to be saved: I verified that none
of the callers rely on it being saved, and it's not a callee-saved
register in the C ABI.
Fixes: aec4d0e301f1 ("x86/asm/crypto: Simplify stack usage in sha-mb functions")
Cc: stable@vger.kernel.org # 4.6
Reported-by: Megha Dey <megha.dey@linux.intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
---
arch/x86/crypto/sha-mb/sha1_x8_avx2.S | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/arch/x86/crypto/sha-mb/sha1_x8_avx2.S b/arch/x86/crypto/sha-mb/sha1_x8_avx2.S
index 8e1b477..c9dae1c 100644
--- a/arch/x86/crypto/sha-mb/sha1_x8_avx2.S
+++ b/arch/x86/crypto/sha-mb/sha1_x8_avx2.S
@@ -296,7 +296,11 @@ W14 = TMP_
#
ENTRY(sha1_x8_avx2)
- push RSP_SAVE
+ # save callee-saved clobbered registers to comply with C function ABI
+ push %r12
+ push %r13
+ push %r14
+ push %r15
#save rsp
mov %rsp, RSP_SAVE
@@ -446,7 +450,12 @@ lloop:
## Postamble
mov RSP_SAVE, %rsp
- pop RSP_SAVE
+
+ # restore callee-saved clobbered registers
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
ret
ENDPROC(sha1_x8_avx2)
--
2.4.11
^ permalink raw reply related
* Re: SHA1-MB algorithm broken on latest kernel
From: Megha Dey @ 2016-05-16 18:31 UTC (permalink / raw)
To: Josh Poimboeuf; +Cc: Ingo Molnar, Herbert Xu, linux-crypto, linux-kernel
In-Reply-To: <20160516144409.dkzqrpd3nlb36ygq@treble>
On Mon, 2016-05-16 at 09:44 -0500, Josh Poimboeuf wrote:
> On Fri, May 13, 2016 at 10:32:26AM -0700, Megha Dey wrote:
> > On Fri, 2016-05-13 at 07:51 +0200, Ingo Molnar wrote:
> > > * Herbert Xu <herbert@gondor.apana.org.au> wrote:
> > >
> > > > On Thu, May 12, 2016 at 04:31:06PM -0700, Megha Dey wrote:
> > > > > Hi,
> > > > >
> > > > > When booting latest kernel with the CONFIG_CRYPTO_SHA1_MB enabled, I
> > > > > observe a panic.
> > > > >
> > > > > After having a quick look, on reverting the following patches, I am able
> > > > > to complete the booting process.
> > > > > aec4d0e301f17bb143341c82cc44685b8af0b945
> > > > > 8691ccd764f9ecc69a6812dfe76214c86ac9ba06
> > > > > 68874ac3304ade7ed5ebb12af00d6b9bbbca0a16
> > > > >
> > > > > Of the 3 patches, aec4d0e301f17bb143341c82cc44685b8af0b945 seems wrong.
> > > > > The r10 to r15 registers are used in sha1_x8_avx2.S, which is called
> > > > > from sha1_mb_mgr_flush_avx2.S.
> > > > >
> > > > > I do not think the functionality of the SHA1-MB crypto algorithm has
> > > > > been tested after applying these changes. (I am not sure if any of the
> > > > > other crypto algorithms have been affected by these changes).
> > > >
> > > > Josh, Ingo:
> > > >
> > > > Any ideas on this? Should we revert?
> > >
> > > Yeah, I think so - although another option would be to standardize sha1_x8_avx2()
> > > - the problem is that it is a function that clobbers registers without
> > > saving/restoring them, breaking the C function ABI. I realize it's written in
> > > assembly, but unless there are strong performance reasons to deviate from the
> > > regular calling convention it might make sense to fix that.
> > >
> > > Do any warnings get generated after the revert, if you enable
> > > CONFIG_STACK_VALIDATION=y?
> >
> > After the revert and enabling CONFIG_STACK_VALIDATION:
> > arch/x86/crypto/sha1-mb/sha1_mb_mgr_flush_avx2.o: warning: objtool:
> > sha1_mb_mgr_flush_avx2()+0x20d: call without frame pointer save/setup
> >
> > arch/x86/crypto/sha1-mb/sha1_mb_mgr_submit_avx2.o: warning: objtool:
> > sha1_mb_mgr_submit_avx2()+0x115: call without frame pointer save/setup
>
> Megha,
>
> Sorry for breaking it. I completely missed the fact that the function
> calls sha1_x8_avx2() which clobbers registers.
>
> If the performance penalty isn't too bad, I'll submit a patch to
> standardize sha1_x8_avx2() to follow the C ABI.
>
> Do you have any tips for testing this code? I've tried using the tcrypt
> module, but no luck.
>
Josh,
Build the kernel with the following configs:
CONFIG_CRYPTO_SHA1_MB=y
CONFIG_CRYPTO_TEST=m
CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=n
There was a kernel panic while booting.
So if after applying your new patch, we are able to get complete the
boot, then we are good.
Could you please send a copy of the patch, I could test it on my end
too.
^ permalink raw reply
* RE: [PATCH v2 6/8] crypto: caam - handle core endianness != caam endianness
From: Tudor-Dan Ambarus @ 2016-05-16 14:52 UTC (permalink / raw)
To: Horia Ioan Geanta Neag, Herbert Xu
Cc: linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org,
David S. Miller, Scott Wood, Alexandru Porosanu, Cristian Stoica,
Fabio Estevam, Steven Cornelius
In-Reply-To: <1462462589-27873-1-git-send-email-horia.geanta@nxp.com>
> There are SoCs like LS1043A where CAAM endianness (BE) does not match
> the default endianness of the core (LE).
> Moreover, there are requirements for the driver to handle cases like
> CPU_BIG_ENDIAN=y on ARM-based SoCs.
> This requires for a complete rewrite of the I/O accessors.
>
> PPC-specific accessors - {in,out}_{le,be}XX - are replaced with
> generic ones - io{read,write}[be]XX.
>
> Endianness is detected dynamically (at runtime) to allow for
> multiplatform kernels, for e.g. running the same kernel image
> on LS1043A (BE CAAM) and LS2080A (LE CAAM) armv8-based SoCs.
>
> While here: debugfs entries need to take into consideration the
> endianness of the core when displaying data. Add the necessary
> glue code so the entries remain the same, but they are properly
> read, regardless of the core and/or SEC endianness.
>
> Note: pdb.h fixes only what is currently being used (IPsec).
>
> Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
> Signed-off-by: Alex Porosanu <alexandru.porosanu@nxp.com>
> ---
> drivers/crypto/caam/Kconfig | 4 -
> drivers/crypto/caam/caamhash.c | 5 +-
> drivers/crypto/caam/ctrl.c | 125 +++++++++++++++++++------------
> drivers/crypto/caam/desc.h | 7 +-
> drivers/crypto/caam/desc_constr.h | 44 +++++++----
> drivers/crypto/caam/jr.c | 22 +++---
> drivers/crypto/caam/pdb.h | 137 ++++++++++++++++++++++++++--------
> drivers/crypto/caam/regs.h | 151 +++++++++++++++++++++++++---------
> ----
> drivers/crypto/caam/sg_sw_sec4.h | 11 +--
> 9 files changed, 340 insertions(+), 166 deletions(-)
Reviewed-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
^ permalink raw reply
* Re: [PATCH v2 0/8] crypto: caam - add support for LS1043A SoC
From: Horia Ioan Geanta Neag @ 2016-05-16 15:49 UTC (permalink / raw)
To: Herbert Xu, Arnd Bergmann, Catalin Marinas, Will Deacon,
Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
Rob Herring, Olof Johansson
Cc: linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org,
David S. Miller, Cristian Stoica, Scott Wood, Alexandru Porosanu,
Tudor-Dan Ambarus
In-Reply-To: <1462462435-27403-1-git-send-email-horia.geanta@nxp.com>
On 5/5/2016 6:34 PM, Horia Geantă wrote:
> v2:
> As suggested by Arnd, patch 1 fixes io{read,write}{16,32}be accessors
> to prevent the case when {read,write}{w,l} are overriden by arch-specific
> ones having barriers, while the BE accessors previously mentioned are not
> (thus behaving differently, having no barriers).
>
> Hi,
>
> [Patches 2-4 add io{read,write}64[be] accessors (generic, arm64, ppc64),
> such that CAAM's accessors in regs.h are simplified a bit.
> Patch 8 adds crypto node for LS1043A platform.
> Let me know if it's ok to go with these through the cryptodev-2.6 tree.]
>
Herbert,
Could you apply the patch set, but without patch 8/8 I guess - since DT
maintainers haven't ack-ed it?
I assume it's too late for 4.7, however applying the patches would solve
dependencies b/w on-going caam development.
Thanks,
Horia
> This is a follow-up on the following RFC patch set:
> crypto: caam - Revamp I/O accessors
> https://www.mail-archive.com/linux-crypto@vger.kernel.org/msg15878.html
>
> There are platforms such as LS1043A (or LS1012A) where core endianness
> does not match CAAM/SEC endianness (LE vs. BE).
> Add support in caam driver for these cases.
>
> Current patch set detects device endianness at runtime (as opposed to
> compile-time endianness), in order to support multiplatform kernels.
> Detection of device endianness is not device-tree based.
> Instead, SSTA ("SEC STAtus") register has a property such that
> reading it in any endianness and masking it properly, it's possible
> to deduce device endianness.
>
> The performance drop due to the runtime detection is < 1.0%.
> (An alternative implementation using function pointers has been tried,
> but lead to a bigger performance drop.)
>
> Thanks,
> Horia
>
> Cristian Stoica (1):
> crypto: caam - fix offset field in hw sg entries
>
> Horia Geantă (7):
> asm-generic/io.h: allow barriers in io{read,write}{16,32}be
> asm-generic/io.h: add io{read,write}64 accessors
> arm64: add io{read,write}64be accessors
> powerpc: add io{read,write}64 accessors
> crypto: caam - handle core endianness != caam endianness
> crypto: caam - add ARCH_LAYERSCAPE to supported architectures
> arm64: dts: ls1043a: add crypto node
>
> arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts | 4 +
> arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 43 ++++++
> arch/arm64/include/asm/io.h | 4 +-
> arch/powerpc/kernel/iomap.c | 24 ++++
> drivers/crypto/caam/Kconfig | 6 +-
> drivers/crypto/caam/caamhash.c | 5 +-
> drivers/crypto/caam/ctrl.c | 125 +++++++++++-------
> drivers/crypto/caam/desc.h | 9 +-
> drivers/crypto/caam/desc_constr.h | 44 ++++---
> drivers/crypto/caam/jr.c | 22 ++--
> drivers/crypto/caam/pdb.h | 137 +++++++++++++++-----
> drivers/crypto/caam/regs.h | 151 +++++++++++++++-------
> drivers/crypto/caam/sg_sw_sec4.h | 17 +--
> include/asm-generic/io.h | 71 +++++++++-
> include/asm-generic/iomap.h | 8 ++
> 15 files changed, 494 insertions(+), 176 deletions(-)
>
^ permalink raw reply
* Re: SHA1-MB algorithm broken on latest kernel
From: Josh Poimboeuf @ 2016-05-16 14:44 UTC (permalink / raw)
To: Megha Dey; +Cc: Ingo Molnar, Herbert Xu, linux-crypto, linux-kernel
In-Reply-To: <1463160746.2594.11.camel@megha-Z97X-UD7-TH>
On Fri, May 13, 2016 at 10:32:26AM -0700, Megha Dey wrote:
> On Fri, 2016-05-13 at 07:51 +0200, Ingo Molnar wrote:
> > * Herbert Xu <herbert@gondor.apana.org.au> wrote:
> >
> > > On Thu, May 12, 2016 at 04:31:06PM -0700, Megha Dey wrote:
> > > > Hi,
> > > >
> > > > When booting latest kernel with the CONFIG_CRYPTO_SHA1_MB enabled, I
> > > > observe a panic.
> > > >
> > > > After having a quick look, on reverting the following patches, I am able
> > > > to complete the booting process.
> > > > aec4d0e301f17bb143341c82cc44685b8af0b945
> > > > 8691ccd764f9ecc69a6812dfe76214c86ac9ba06
> > > > 68874ac3304ade7ed5ebb12af00d6b9bbbca0a16
> > > >
> > > > Of the 3 patches, aec4d0e301f17bb143341c82cc44685b8af0b945 seems wrong.
> > > > The r10 to r15 registers are used in sha1_x8_avx2.S, which is called
> > > > from sha1_mb_mgr_flush_avx2.S.
> > > >
> > > > I do not think the functionality of the SHA1-MB crypto algorithm has
> > > > been tested after applying these changes. (I am not sure if any of the
> > > > other crypto algorithms have been affected by these changes).
> > >
> > > Josh, Ingo:
> > >
> > > Any ideas on this? Should we revert?
> >
> > Yeah, I think so - although another option would be to standardize sha1_x8_avx2()
> > - the problem is that it is a function that clobbers registers without
> > saving/restoring them, breaking the C function ABI. I realize it's written in
> > assembly, but unless there are strong performance reasons to deviate from the
> > regular calling convention it might make sense to fix that.
> >
> > Do any warnings get generated after the revert, if you enable
> > CONFIG_STACK_VALIDATION=y?
>
> After the revert and enabling CONFIG_STACK_VALIDATION:
> arch/x86/crypto/sha1-mb/sha1_mb_mgr_flush_avx2.o: warning: objtool:
> sha1_mb_mgr_flush_avx2()+0x20d: call without frame pointer save/setup
>
> arch/x86/crypto/sha1-mb/sha1_mb_mgr_submit_avx2.o: warning: objtool:
> sha1_mb_mgr_submit_avx2()+0x115: call without frame pointer save/setup
Megha,
Sorry for breaking it. I completely missed the fact that the function
calls sha1_x8_avx2() which clobbers registers.
If the performance penalty isn't too bad, I'll submit a patch to
standardize sha1_x8_avx2() to follow the C ABI.
Do you have any tips for testing this code? I've tried using the tcrypt
module, but no luck.
--
Josh
^ permalink raw reply
* Re: Decrypting data in RX path
From: Gadre Nayan @ 2016-05-16 14:40 UTC (permalink / raw)
To: Stephan Mueller, linux-crypto
In-Reply-To: <6061728.aByMvLa2kt@tauon.atsec.com>
Hi,
1. The context of the question "best place to decrypt in
kernel(module/driver)" is I want to encrypt network packets sent from
my system and decrypt them back to work with crypto apis. So the
encryption part I have done in a Kernel thread, decryption part could
be either in driver or a pre-routing hook. Which is appropriate.
2. I went through the esp_input function for rx.
As I understand, It allocates a decrypt request and and calls
crypto_aead_decrypt(req).
A. Since this request is asynchronous, it would be handled through
condition variables, Am i right on this?
B. Also the IPSEC routines like input and output would run in softirq context ?
C. esp_input_done() is a callback for decrypt, so as soon as
crypto_aead_decrypt(req) is called and the encryption does not happen
immediately, it will return the error _EINPROGRESS. Now this will
cause the esp_input function to return immediately. So then when is
the deferred decryption checked. I see esp_input_done2 as well. How is
the flow and call of these callbacks happening.
Apologize for being so verbose.
Thanks.
On Mon, May 16, 2016 at 6:02 PM, Stephan Mueller <smueller@chronox.de> wrote:
> Am Montag, 16. Mai 2016, 17:24:12 schrieb Gadre Nayan:
>
> Hi Gadre,
>
>> Hi,
>>
>> I am able to encrypt data using the asynchronous kernel crypto API's.
>> I can observe the encrypted data on the protocol analyzer.
>>
>> I wanted to decry-pt the data now on the receiver side, So I have
>> following questions.
>>
>> 1. What is the best place to decrypt the data, in kernel space (module
>> (pre-routing hook) or driver) OR user space using (maybe using raw
>> sockets or after socket recv).
>
> This is a very broad question and cannot be answered without knowning the
> context.
>>
>> What precautions should be taken in terms of locking while using
>> crypto api's in kernel space in RX path (Softirq context) --> Can
>> someone point to existing sample in kernel where decryption is done in
>> RX path.
>
> net/ipv4/esp4.c:esp_input for rx and esp_output for tx.
>>
>>
>> 2. If I encrypt data in kernel space can I decrypt it in User-space
>> using same encryption methods and Keys.
>
> Sure, if you have the keys and all information about the used crypto.
>>
>> Thanks.
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
> Ciao
> Stephan
^ permalink raw reply
* Re: [PATCH RESEND v5 6/6] crypto: AF_ALG - add support for key_id
From: Tadeusz Struk @ 2016-05-16 14:23 UTC (permalink / raw)
To: Mat Martineau
Cc: dhowells, herbert, smueller, linux-api, marcel, linux-kernel,
keyrings, linux-crypto, dwmw2, davem
In-Reply-To: <alpine.OSX.2.20.1605131616200.29074@mjmartin-mac01.local>
Hi Mat,
On 05/13/2016 04:32 PM, Mat Martineau wrote:
>
>> + params.data_len = req->src_len;
>> + params.enc_len = req->dst_len;
Thanks for info. I have sent an update for this.
>
> The params member names have changed (now in_len and out_len).
>> + ret = encrypt_blob(¶ms, in, out);
>
> The encrypt function for the key can now be called with params.key->type->asym_eds_op(). This also allows you to factor out the duplication in asym_key_encrypt, asym_key_decrypt, and asym_key_sign. See keyctl_pkey_e_d_s() in keyctl_pkey.c
>
>> +static int asym_key_verify(const struct key *key, struct akcipher_request *req)
> ...
>> + ret = verify_signature(key, NULL, &sig);
>
> key->type->asym_verify_signature() is available as well.
Since these operation will be triggered from userspace I think it's better to use the
official interface as defined in crypto/public_key.h instead of direct calls.
Some operation may not be implemented for a given key type and the official interface
performs necessary checks.
Thanks,
--
TS
^ permalink raw reply
* Costs of asym self tests
From: Stephan Mueller @ 2016-05-16 13:30 UTC (permalink / raw)
To: linux-crypto; +Cc: Struk, Tadeusz
Hi,
albeit it makes most sense to have asym self tests in the test manager as we
do right now, may I suggest some changes to it as follows. The issue I see is
that asym operations are very expensive.
As we currently have RSA only, I can only refer to its implementation. But in
general, all new-and-coming asym self tests should be assessed accordingly.
May I suggest to do the following:
- remove all self tests except the 2k tests. As the math works independent of
the key size, testing one key size is sufficient to demonstrate that the math
still works.
- If we booted in FIPS mode, and we have PKCS#1 compiled, then:
* do not execute the raw RSA self test mentioned above
* perform an enc/dec test using the kernel crypto API with a 2k key
* if the asym key API is compiled, add a self test for siggen/ver
With this approach, I would see that we limit the impact of the self test to
"normal" users as well as FIPS related use cases.
If agreed, I could offer to implement the changes.
Note, currently the self tests for RSA is not appropriate to allow the cipher
in FIPS mode (i.e. the fips_allowed=1 flag is actually not correct in the
current implementation).
Ciao
Stephan
^ permalink raw reply
* Re: Decrypting data in RX path
From: Stephan Mueller @ 2016-05-16 12:32 UTC (permalink / raw)
To: Gadre Nayan; +Cc: linux-crypto
In-Reply-To: <CAKJ7aR5v5LmgZ5XAv8+9mAtksdSu=LJz=oK9AmHO2t4bDiqSzw@mail.gmail.com>
Am Montag, 16. Mai 2016, 17:24:12 schrieb Gadre Nayan:
Hi Gadre,
> Hi,
>
> I am able to encrypt data using the asynchronous kernel crypto API's.
> I can observe the encrypted data on the protocol analyzer.
>
> I wanted to decry-pt the data now on the receiver side, So I have
> following questions.
>
> 1. What is the best place to decrypt the data, in kernel space (module
> (pre-routing hook) or driver) OR user space using (maybe using raw
> sockets or after socket recv).
This is a very broad question and cannot be answered without knowning the
context.
>
> What precautions should be taken in terms of locking while using
> crypto api's in kernel space in RX path (Softirq context) --> Can
> someone point to existing sample in kernel where decryption is done in
> RX path.
net/ipv4/esp4.c:esp_input for rx and esp_output for tx.
>
>
> 2. If I encrypt data in kernel space can I decrypt it in User-space
> using same encryption methods and Keys.
Sure, if you have the keys and all information about the used crypto.
>
> Thanks.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
Ciao
Stephan
^ permalink raw reply
* Re: Decrypting data in RX path
From: Catalin Vasile @ 2016-05-16 12:04 UTC (permalink / raw)
To: Gadre Nayan, linux-crypto@vger.kernel.org
In-Reply-To: <CAKJ7aR5v5LmgZ5XAv8+9mAtksdSu=LJz=oK9AmHO2t4bDiqSzw@mail.gmail.com>
Inline comments.
________________________________________
From: linux-crypto-owner@vger.kernel.org <linux-crypto-owner@vger.kernel.org> on behalf of Gadre Nayan <gadrenayan@gmail.com>
Sent: Monday, May 16, 2016 2:54 PM
To: linux-crypto@vger.kernel.org
Subject: Decrypting data in RX path
Hi,
I am able to encrypt data using the asynchronous kernel crypto API's.
I can observe the encrypted data on the protocol analyzer.
I wanted to decry-pt the data now on the receiver side, So I have
following questions.
1. What is the best place to decrypt the data, in kernel space (module
(pre-routing hook) or driver) OR user space using (maybe using raw
sockets or after socket recv).
What precautions should be taken in terms of locking while using
crypto api's in kernel space in RX path (Softirq context) --> Can
someone point to existing sample in kernel where decryption is done in
RX path.
[Catalin Vasile] Look into net/ipv6/esp6.c. It's related to IPsec.
2. If I encrypt data in kernel space can I decrypt it in User-space
using same encryption methods and Keys.
[Catalin Vasile] What do you mean by "using same encryption methods" ?
Thanks.
^ permalink raw reply
* Re: Decrypting data in RX path
From: Gadre Nayan @ 2016-05-16 12:11 UTC (permalink / raw)
To: Catalin Vasile, linux-crypto
In-Reply-To: <HE1PR04MB1306ADC0ADE1CB57D2AB4A7CEE770@HE1PR04MB1306.eurprd04.prod.outlook.com>
Hi,
[Catalin Vasile] What do you mean by "using same encryption methods" ?
What I meant was, in the module If I use "cbc(aes)" With say 16 blocks
of data to be encrypted with 16 bytes of iv-data and so on, are there
user space Api's to use in decryption which will take such arguments,
otherwise data won't be decrypted properly ?
On Mon, May 16, 2016 at 5:34 PM, Catalin Vasile <cata.vasile@nxp.com> wrote:
> Inline comments.
>
> ________________________________________
> From: linux-crypto-owner@vger.kernel.org <linux-crypto-owner@vger.kernel.org> on behalf of Gadre Nayan <gadrenayan@gmail.com>
> Sent: Monday, May 16, 2016 2:54 PM
> To: linux-crypto@vger.kernel.org
> Subject: Decrypting data in RX path
>
> Hi,
>
> I am able to encrypt data using the asynchronous kernel crypto API's.
> I can observe the encrypted data on the protocol analyzer.
>
> I wanted to decry-pt the data now on the receiver side, So I have
> following questions.
>
> 1. What is the best place to decrypt the data, in kernel space (module
> (pre-routing hook) or driver) OR user space using (maybe using raw
> sockets or after socket recv).
>
> What precautions should be taken in terms of locking while using
> crypto api's in kernel space in RX path (Softirq context) --> Can
> someone point to existing sample in kernel where decryption is done in
> RX path.
> [Catalin Vasile] Look into net/ipv6/esp6.c. It's related to IPsec.
>
> 2. If I encrypt data in kernel space can I decrypt it in User-space
> using same encryption methods and Keys.
> [Catalin Vasile] What do you mean by "using same encryption methods" ?
>
> Thanks.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Decrypting data in RX path
From: Gadre Nayan @ 2016-05-16 11:54 UTC (permalink / raw)
To: linux-crypto
Hi,
I am able to encrypt data using the asynchronous kernel crypto API's.
I can observe the encrypted data on the protocol analyzer.
I wanted to decry-pt the data now on the receiver side, So I have
following questions.
1. What is the best place to decrypt the data, in kernel space (module
(pre-routing hook) or driver) OR user space using (maybe using raw
sockets or after socket recv).
What precautions should be taken in terms of locking while using
crypto api's in kernel space in RX path (Softirq context) --> Can
someone point to existing sample in kernel where decryption is done in
RX path.
2. If I encrypt data in kernel space can I decrypt it in User-space
using same encryption methods and Keys.
Thanks.
^ permalink raw reply
* Crypto Update for 4.7
From: Herbert Xu @ 2016-05-16 7:16 UTC (permalink / raw)
To: Linus Torvalds, David S. Miller, Linux Kernel Mailing List,
Linux Crypto Mailing List
In-Reply-To: <20160315072040.GA18381@gondor.apana.org.au>
Hi Linus:
Here is the crypto update for 4.7:
API:
* Crypto self tests can now be disabled at boot/run time.
* Add async support to algif_aead.
Algorithms:
* A large number of fixes to MPI from Nicolai Stange.
* Performance improvement for HMAC DRBG.
Drivers:
* Use generic crypto engine in omap-des.
* Merge ppc4xx-rng and crypto4xx drivers.
* Fix lockups in sun4i-ss driver by disabling IRQs.
* Add DMA engine support to ccp.
* Reenable talitos hash algorithms.
* Add support for Hisilicon SoC RNG.
* Add basic crypto driver for the MXC SCC.
Others:
* Do not allocate crypto hash tfm in NORECLAIM context in ecryptfs.
Please pull from
git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6.git linus
Ahsan Atta (1):
crypto: qat - Remove redundant nrbg rings
Amitoj Kaur Chawla (1):
crypto: n2 - Remove return statement from void function
Baolin Wang (1):
crypto: omap-des - Integrate with the crypto engine framework
Catalin Vasile (1):
crypto: caam - fix caam_jr_alloc() ret code
Christian Lamparter (1):
crypto4xx: integrate ppc4xx-rng into crypto4xx
Colin Ian King (1):
PKCS#7: fix missing break on OID_sha224 case
Corentin LABBE (1):
crypto: sun4i-ss - Replace spinlock_bh by spin_lock_irq{save|restore}
Dan Carpenter (3):
crypto: marvell/cesa - remove unneeded condition
crypto: mxc-scc - signedness bugs in mxc_scc_ablkcipher_req_init()
crypto: mxc-scc - fix unwinding in mxc_scc_crypto_register()
Eric Biggers (1):
crypto: doc - document correct return value for request allocation
Gary R Hook (2):
crypto: ccp - Register the CCP as a DMA resource
crypto: ccp - Ensure all dependencies are specified
Herbert Xu (3):
eCryptfs: Do not allocate hash tfm in NORECLAIM context
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Horia Geant? (1):
crypto: talitos - fix ahash algorithms registration
Julia Lawall (2):
crypto: marvell/cesa - Use dma_pool_zalloc
crypto: ccp - constify ccp_actions structure
Kefeng Wang (2):
dt/bindings: Add bindings for hisilicon random number generator
hwrng: hisi - Add support for Hisilicon SoC RNG
Krzysztof Kozlowski (14):
hwrng: exynos - Runtime suspend device after init
hwrng: exynos - Fix unbalanced PM runtime put on timeout error path
hwrng: exynos - Disable runtime PM on probe failure
hwrng: exynos - Disable runtime PM on driver unbind
hwrng: exynos - Enable COMPILE_TEST
crypto: s5p-sss - Enable COMPILE_TEST
crypto: s5p-sss - Minor coding cleanups
crypto: s5p-sss - Handle unaligned buffers
crypto: s5p-sss - Sort the headers to improve readability
hwrng: exynos - Fix misspelled Samsung address
crypto: s5p-sss - Fix use after free of copied input buffer in error path
crypto: s5p-sss - Remove useless hash interrupt handler
crypto: s5p-sss - Use common BIT macro
crypto: s5p-sss - Fix missed interrupts when working with 8 kB blocks
Marek Szyprowski (1):
crypto: s5p-sss - fix incorrect usage of scatterlists api
Michal Hocko (1):
crypto: lzo - get rid of superfluous __GFP_REPEAT
Mike Galbraith (1):
crypto: ccp - Fix RT breaking #include <linux/rwlock_types.h>
Nicolai Stange (14):
lib/mpi: mpi_write_sgl(): fix skipping of leading zero limbs
lib/mpi: mpi_write_sgl(): fix style issue with lzero decrement
lib/mpi: mpi_write_sgl(): purge redundant pointer arithmetic
lib/mpi: mpi_write_sgl(): fix out-of-bounds stack access
lib/mpi: mpi_write_sgl(): replace open coded endian conversion
lib/mpi: mpi_read_buffer(): optimize skipping of leading zero limbs
lib/mpi: mpi_read_buffer(): replace open coded endian conversion
lib/mpi: mpi_read_buffer(): fix buffer overflow
lib/mpi: mpi_read_raw_from_sgl(): replace len argument by nbytes
lib/mpi: mpi_read_raw_from_sgl(): don't include leading zero SGEs in nbytes
lib/mpi: mpi_read_raw_from_sgl(): purge redundant clearing of nbits
lib/mpi: mpi_read_raw_from_sgl(): fix nbits calculation
lib/mpi: mpi_read_raw_from_sgl(): sanitize meaning of indices
lib/mpi: mpi_read_raw_from_sgl(): fix out-of-bounds buffer access
Paulo Flabiano Smorigo (1):
crypto: vmx - comply with ABIs that specify vrsave as reserved.
Peter Meerwald (1):
crypto: omap-des - Improve wording for CRYPTO_DEV_OMAP_DES in Kconfig
Peter Ujfalusi (3):
crypto: omap-aes - Use dma_request_chan() for requesting DMA channel
crypto: omap-des - Use dma_request_chan() for requesting DMA channel
crypto: omap-sham - Use dma_request_chan() for requesting DMA channel
Richard W.M. Jones (1):
crypto: testmgr - Add a flag allowing the self-tests to be disabled at runtime.
Romain Perier (1):
crypto: marvell/cesa - Improving code readability
Steffen Trumtrar (3):
Documentation: devicetree: add Freescale SCC bindings
ARM: i.MX25: add scc module to dtsi
crypto: mxc-scc - add basic driver for the MXC SCC
Stephan Mueller (1):
crypto: drbg - set HMAC key only when altered
Tadeusz Struk (12):
crypto: af_alg - add async support to algif_aead
crypto: qat - make sure const_tab is 1024 bytes aligned
crypto: qat - explicitly stop all VFs first
crypto: qat - changed adf_dev_stop to void
crypto: qat - adf_dev_stop should not be called in atomic context
crypto: qat - move vf2pf_init and vf2pf_exit to common
crypto: qat - check if PF is running
crypto: qat - interrupts need to be enabled when VFs are disabled
crypto: qat - fix section mismatch warning
crypto: qat - Fix typo in comments
crypto: qat - make adf_vf_isr.c dependant on IOV config
crypto: qat - change the adf_ctl_stop_devices to void
Tom Lendacky (1):
MAINTAINERS: Add a new maintainer for the CCP driver
Tudor Ambarus (3):
crypto: qat - avoid memory corruption or undefined behaviour
crypto: qat - fix address leaking of RSA public exponent
lib: asn1_decoder - add MODULE_LICENSE("GPL")
Documentation/DocBook/crypto-API.tmpl | 6 +-
.../devicetree/bindings/crypto/fsl-imx-scc.txt | 21 +
.../devicetree/bindings/crypto/samsung-sss.txt | 6 +-
Documentation/devicetree/bindings/rng/hisi-rng.txt | 12 +
Documentation/kernel-parameters.txt | 3 +
MAINTAINERS | 1 +
arch/arm/boot/dts/imx25.dtsi | 9 +
crypto/algif_aead.c | 268 ++++++-
crypto/asymmetric_keys/pkcs7_parser.c | 1 +
crypto/drbg.c | 39 +-
crypto/lzo.c | 2 +-
crypto/testmgr.c | 9 +
drivers/char/hw_random/Kconfig | 29 +-
drivers/char/hw_random/Makefile | 2 +-
drivers/char/hw_random/exynos-rng.c | 33 +-
drivers/char/hw_random/hisi-rng.c | 126 ++++
drivers/char/hw_random/ppc4xx-rng.c | 147 ----
drivers/crypto/Kconfig | 27 +-
drivers/crypto/Makefile | 1 +
drivers/crypto/amcc/Makefile | 1 +
drivers/crypto/amcc/crypto4xx_core.c | 7 +-
drivers/crypto/amcc/crypto4xx_core.h | 4 +
drivers/crypto/amcc/crypto4xx_reg_def.h | 1 +
drivers/crypto/amcc/crypto4xx_trng.c | 131 ++++
drivers/crypto/amcc/crypto4xx_trng.h | 34 +
drivers/crypto/caam/jr.c | 2 +-
drivers/crypto/ccp/Kconfig | 2 +
drivers/crypto/ccp/Makefile | 6 +-
drivers/crypto/ccp/ccp-dev-v3.c | 13 +-
drivers/crypto/ccp/ccp-dev.c | 2 +-
drivers/crypto/ccp/ccp-dev.h | 49 +-
drivers/crypto/ccp/ccp-dmaengine.c | 727 +++++++++++++++++++
drivers/crypto/ccp/ccp-ops.c | 69 +-
drivers/crypto/marvell/cesa.c | 10 +-
drivers/crypto/marvell/hash.c | 3 +-
drivers/crypto/marvell/tdma.c | 5 +-
drivers/crypto/mxc-scc.c | 765 ++++++++++++++++++++
drivers/crypto/n2_core.c | 2 +-
drivers/crypto/omap-aes.c | 62 +-
drivers/crypto/omap-des.c | 165 ++---
drivers/crypto/omap-sham.c | 25 +-
drivers/crypto/qat/qat_c3xxx/adf_drv.c | 4 +-
.../crypto/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c | 23 -
drivers/crypto/qat/qat_c3xxxvf/adf_drv.c | 6 +-
drivers/crypto/qat/qat_c62x/adf_drv.c | 4 +-
drivers/crypto/qat/qat_c62xvf/adf_c62xvf_hw_data.c | 23 -
drivers/crypto/qat/qat_c62xvf/adf_drv.c | 6 +-
drivers/crypto/qat/qat_common/Makefile | 4 +-
drivers/crypto/qat/qat_common/adf_admin.c | 2 +-
drivers/crypto/qat/qat_common/adf_cfg_strings.h | 2 -
drivers/crypto/qat/qat_common/adf_common_drv.h | 28 +-
drivers/crypto/qat/qat_common/adf_ctl_drv.c | 40 +-
drivers/crypto/qat/qat_common/adf_init.c | 15 +-
drivers/crypto/qat/qat_common/adf_isr.c | 4 +-
drivers/crypto/qat/qat_common/adf_sriov.c | 8 +-
drivers/crypto/qat/qat_common/adf_vf2pf_msg.c | 92 +++
drivers/crypto/qat/qat_common/adf_vf_isr.c | 61 +-
drivers/crypto/qat/qat_common/qat_asym_algs.c | 4 +-
drivers/crypto/qat/qat_dh895xcc/adf_drv.c | 4 +-
.../qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c | 23 -
drivers/crypto/qat/qat_dh895xccvf/adf_drv.c | 6 +-
drivers/crypto/s5p-sss.c | 368 ++++++----
drivers/crypto/sunxi-ss/sun4i-ss-cipher.c | 10 +-
drivers/crypto/talitos.c | 64 ++
drivers/crypto/vmx/ppc-xlate.pl | 20 +
fs/ecryptfs/crypto.c | 32 +-
fs/ecryptfs/ecryptfs_kernel.h | 3 +-
fs/ecryptfs/inode.c | 7 +-
fs/ecryptfs/super.c | 5 +-
include/crypto/aead.h | 3 +-
include/crypto/hash.h | 3 +-
include/crypto/skcipher.h | 3 +-
include/linux/ccp.h | 36 +-
include/linux/crypto.h | 3 +-
lib/asn1_decoder.c | 3 +
lib/mpi/mpicoder.c | 122 ++--
76 files changed, 3091 insertions(+), 777 deletions(-)
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* [PATCH] crypto: user - no parsing of CRYPTO_MSG_GETALG
From: Stephan Mueller @ 2016-05-16 0:53 UTC (permalink / raw)
To: herbert; +Cc: Steffen Klassert, linux-crypto
The CRYPTO_MSG_GETALG netlink message type provides a buffer to the
kernel to retrieve information from the kernel. The data buffer will not
provide any input and will not be read. Hence the nlmsg_parse is not
applicable to this netlink message type.
This patch fixes the following kernel log message when using this
netlink interface:
netlink: 208 bytes leftover after parsing attributes in process `XXX'.
Patch successfully tested with libkcapi from [1] which uses
CRYPTO_MSG_GETALG to obtain cipher-specific information from the kernel.
[1] http://www.chronox.de/libkcapi.html
Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
crypto/crypto_user.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 43fe85f..f71960d 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -516,10 +516,12 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
return err;
}
- err = nlmsg_parse(nlh, crypto_msg_min[type], attrs, CRYPTOCFGA_MAX,
- crypto_policy);
- if (err < 0)
- return err;
+ if (type != (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE)) {
+ err = nlmsg_parse(nlh, crypto_msg_min[type], attrs,
+ CRYPTOCFGA_MAX, crypto_policy);
+ if (err < 0)
+ return err;
+ }
if (link->doit == NULL)
return -EINVAL;
--
2.5.5
^ permalink raw reply related
* Re: [PATCH] crypto: gcm - Fix rfc4543 decryption crash
From: Ben Hutchings @ 2016-05-15 19:48 UTC (permalink / raw)
To: Herbert Xu
Cc: Greg KH, stable, Linux Crypto Mailing List, Jussi Kivilinna,
patrick.meyer
In-Reply-To: <20160427041744.GA27044@gondor.apana.org.au>
[-- Attachment #1: Type: text/plain, Size: 1006 bytes --]
On Wed, 2016-04-27 at 12:17 +0800, Herbert Xu wrote:
> On Tue, Apr 26, 2016 at 01:42:56PM +0200, Ben Hutchings wrote:
> >
> >
> > It looks like the bug was introduced in 3.10 by:
> >
> > d733ac90f9fe8ac284e523f9920b507555b12f6d
> > Author: Jussi Kivilinna <jussi.kivilinna@iki.fi>
> > Date: Sun Apr 7 16:43:46 2013 +0300
> >
> > crypto: gcm - fix rfc4543 to handle async crypto correctly
> >
> > So 3.2.y and 3.4.y don't need this fix - or should they get both
> > fixes?
> If that patch is not present then my fix can't be applied. However,
> I think this change itself is probably needed in 3.2/3.4 as otherwise
> GCM would be broken if the underlying cipher is async. It's not a
> big deal on x86 because the main async AES provider also provides
> GCM directly, but on other architectures it may be an issue.
I've queued up both of these for 3.2.
Ben.
--
Ben Hutchings
For every action, there is an equal and opposite criticism. - Harrison
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH v6 0/6] crypto: algif - add akcipher
From: Stephan Mueller @ 2016-05-15 11:59 UTC (permalink / raw)
To: Tadeusz Struk
Cc: dhowells, herbert, linux-api, marcel, linux-kernel, keyrings,
linux-crypto, dwmw2, davem
In-Reply-To: <20160515041645.15888.94903.stgit@tstruk-mobl1>
Am Samstag, 14. Mai 2016, 21:16:45 schrieb Tadeusz Struk:
Hi Tadeusz,
> First four patches are a resend of the v3 algif_akcipher from
> Stephan Mueller, with minor changes after rebase on top of 4.6-rc1.
All four patches from me:
Acked-by: Stephan Mueller <smueller@chronox.de>
Ciao
Stephan
^ permalink raw reply
* HWCAP_CRYPTO define for ARMv8?
From: Jeffrey Walton @ 2016-05-15 10:13 UTC (permalink / raw)
To: linux-crypto
Hi Everyone,
It appears defines like HWCAP_CRC32 fall under the purview of the
kernel. Confer, http://www.google.com/search?q="HWCAP_CRC32" (my
apologies if this is not the case).
We use getauxval(AT_HWCAP) and HWCAP_CRC32 for runtime detection of
processor support for CRC. However, I can't find a similar symbol in
the context of the crypto instructions. Confer,
http://www.google.com/search?q="HWCAP_CRYPTO".
My question is, what are the equivalent defines for Crypto features?
Thanks in advance.
*****
Below is from a 64-bit LeMaker HiKey
(http://www.lemaker.org/product-hikey-index.html). It responds to
getauxval(AT_HWCAP) and HWCAP_CRC32.
$ cat /proc/cpuinfo
Processor : AArch64 Processor rev 3 (aarch64)
processor : 0
...
processor : 7
Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
CPU implementer : 0x41
CPU architecture: AArch64
CPU variant : 0x0
CPU part : 0xd03
CPU revision : 3
Hardware : HiKey Development Board
^ permalink raw reply
* [PATCH v6 2/6] crypto: AF_ALG -- add setpubkey setsockopt call
From: Tadeusz Struk @ 2016-05-15 4:16 UTC (permalink / raw)
To: dhowells
Cc: herbert, tadeusz.struk, smueller, linux-api, marcel, linux-kernel,
keyrings, linux-crypto, dwmw2, davem
In-Reply-To: <20160515041645.15888.94903.stgit@tstruk-mobl1>
From: Stephan Mueller <smueller@chronox.de>
For supporting asymmetric ciphers, user space must be able to set the
public key. The patch adds a new setsockopt call for setting the public
key.
Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
crypto/af_alg.c | 18 +++++++++++++-----
include/crypto/if_alg.h | 1 +
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index f5e18c2..24dc082 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -202,13 +202,17 @@ unlock:
}
static int alg_setkey(struct sock *sk, char __user *ukey,
- unsigned int keylen)
+ unsigned int keylen,
+ int (*setkey)(void *private, const u8 *key,
+ unsigned int keylen))
{
struct alg_sock *ask = alg_sk(sk);
- const struct af_alg_type *type = ask->type;
u8 *key;
int err;
+ if (!setkey)
+ return -ENOPROTOOPT;
+
key = sock_kmalloc(sk, keylen, GFP_KERNEL);
if (!key)
return -ENOMEM;
@@ -217,7 +221,7 @@ static int alg_setkey(struct sock *sk, char __user *ukey,
if (copy_from_user(key, ukey, keylen))
goto out;
- err = type->setkey(ask->private, key, keylen);
+ err = setkey(ask->private, key, keylen);
out:
sock_kzfree_s(sk, key, keylen);
@@ -247,10 +251,14 @@ static int alg_setsockopt(struct socket *sock, int level, int optname,
case ALG_SET_KEY:
if (sock->state == SS_CONNECTED)
goto unlock;
- if (!type->setkey)
+
+ err = alg_setkey(sk, optval, optlen, type->setkey);
+ break;
+ case ALG_SET_PUBKEY:
+ if (sock->state == SS_CONNECTED)
goto unlock;
- err = alg_setkey(sk, optval, optlen);
+ err = alg_setkey(sk, optval, optlen, type->setpubkey);
break;
case ALG_SET_AEAD_AUTHSIZE:
if (sock->state == SS_CONNECTED)
diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h
index a2bfd78..6c3e6e7 100644
--- a/include/crypto/if_alg.h
+++ b/include/crypto/if_alg.h
@@ -52,6 +52,7 @@ struct af_alg_type {
void *(*bind)(const char *name, u32 type, u32 mask);
void (*release)(void *private);
int (*setkey)(void *private, const u8 *key, unsigned int keylen);
+ int (*setpubkey)(void *private, const u8 *key, unsigned int keylen);
int (*accept)(void *private, struct sock *sk);
int (*accept_nokey)(void *private, struct sock *sk);
int (*setauthsize)(void *private, unsigned int authsize);
^ permalink raw reply related
* [PATCH v6 4/6] crypto: algif_akcipher - enable compilation
From: Tadeusz Struk @ 2016-05-15 4:17 UTC (permalink / raw)
To: dhowells
Cc: herbert, tadeusz.struk, smueller, linux-api, marcel, linux-kernel,
keyrings, linux-crypto, dwmw2, davem
In-Reply-To: <20160515041645.15888.94903.stgit@tstruk-mobl1>
From: Stephan Mueller <smueller@chronox.de>
Add the Makefile and Kconfig updates to allow algif_akcipher to be
compiled.
Signed-off-by: Stephan Mueller <smueller@chronox.de>
Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
crypto/Kconfig | 9 +++++++++
crypto/Makefile | 1 +
2 files changed, 10 insertions(+)
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 93a1fdc..b932319 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -1626,6 +1626,15 @@ config CRYPTO_USER_API_AEAD
This option enables the user-spaces interface for AEAD
cipher algorithms.
+config CRYPTO_USER_API_AKCIPHER
+ tristate "User-space interface for asymmetric key cipher algorithms"
+ depends on NET
+ select CRYPTO_AKCIPHER2
+ select CRYPTO_USER_API
+ help
+ This option enables the user-spaces interface for asymmetric
+ key cipher algorithms.
+
config CRYPTO_HASH_INFO
bool
diff --git a/crypto/Makefile b/crypto/Makefile
index 4f4ef7e..c51ac16 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -121,6 +121,7 @@ obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o
obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o
obj-$(CONFIG_CRYPTO_USER_API_RNG) += algif_rng.o
obj-$(CONFIG_CRYPTO_USER_API_AEAD) += algif_aead.o
+obj-$(CONFIG_CRYPTO_USER_API_AKCIPHER) += algif_akcipher.o
#
# generic algorithms and the async_tx api
^ permalink raw reply related
* [PATCH v6 6/6] crypto: AF_ALG - add support for key_id
From: Tadeusz Struk @ 2016-05-15 4:17 UTC (permalink / raw)
To: dhowells
Cc: herbert, tadeusz.struk, smueller, linux-api, marcel, linux-kernel,
keyrings, linux-crypto, dwmw2, davem
In-Reply-To: <20160515041645.15888.94903.stgit@tstruk-mobl1>
This patch adds support for asymmetric key type to AF_ALG.
It will work as follows: A new PF_ALG socket options are
added on top of existing ALG_SET_KEY and ALG_SET_PUBKEY, namely
ALG_SET_KEY_ID and ALG_SET_PUBKEY_ID for setting public and
private keys respectively. When these new options will be used
the user, instead of providing the key material, will provide a
key id and the key itself will be obtained from kernel keyring
subsystem. The user will use the standard tools (keyctl tool
or the keyctl syscall) for key instantiation and to obtain the
key id. The key id can also be obtained by reading the
/proc/keys file.
When a key corresponding to the given keyid is found, it is stored
in the socket context and subsequent crypto operation invoked by the
user will use the new asymmetric accessor functions instead of akcipher
api. The asymmetric subtype can internally use akcipher api or
invoke operations defined by a given subtype, depending on the
key type.
Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
crypto/af_alg.c | 10 ++
crypto/algif_akcipher.c | 207 ++++++++++++++++++++++++++++++++++++++++++-
include/crypto/if_alg.h | 1
include/uapi/linux/if_alg.h | 2
4 files changed, 215 insertions(+), 5 deletions(-)
diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index 24dc082..59c8244 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -260,6 +260,16 @@ static int alg_setsockopt(struct socket *sock, int level, int optname,
err = alg_setkey(sk, optval, optlen, type->setpubkey);
break;
+
+ case ALG_SET_KEY_ID:
+ case ALG_SET_PUBKEY_ID:
+ /* ALG_SET_KEY_ID is only for akcipher */
+ if (!strcmp(type->name, "akcipher") ||
+ sock->state == SS_CONNECTED)
+ goto unlock;
+
+ err = alg_setkey(sk, optval, optlen, type->setkeyid);
+ break;
case ALG_SET_AEAD_AUTHSIZE:
if (sock->state == SS_CONNECTED)
goto unlock;
diff --git a/crypto/algif_akcipher.c b/crypto/algif_akcipher.c
index e00793d..6733df1 100644
--- a/crypto/algif_akcipher.c
+++ b/crypto/algif_akcipher.c
@@ -14,6 +14,8 @@
#include <crypto/akcipher.h>
#include <crypto/scatterwalk.h>
#include <crypto/if_alg.h>
+#include <crypto/public_key.h>
+#include <keys/asymmetric-type.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/kernel.h>
@@ -29,6 +31,7 @@ struct akcipher_sg_list {
struct akcipher_tfm {
struct crypto_akcipher *akcipher;
+ char keyid[12];
bool has_key;
};
@@ -37,6 +40,7 @@ struct akcipher_ctx {
struct af_alg_sgl rsgl[ALG_MAX_PAGES];
struct af_alg_completion completion;
+ struct key *key;
unsigned long used;
@@ -322,6 +326,153 @@ unlock:
return err ? err : size;
}
+static int asym_key_encrypt(const struct key *key, struct akcipher_request *req)
+{
+ struct kernel_pkey_params params = {0};
+ char *src = NULL, *dst = NULL, *in, *out;
+ int ret;
+
+ if (!sg_is_last(req->src)) {
+ src = kmalloc(req->src_len, GFP_KERNEL);
+ if (!src)
+ return -ENOMEM;
+ scatterwalk_map_and_copy(src, req->src, 0, req->src_len, 0);
+ in = src;
+ } else {
+ in = sg_virt(req->src);
+ }
+ if (!sg_is_last(req->dst)) {
+ dst = kmalloc(req->dst_len, GFP_KERNEL);
+ if (!dst) {
+ kfree(src);
+ return -ENOMEM;
+ }
+ out = dst;
+ } else {
+ out = sg_virt(req->dst);
+ }
+ params.key = (struct key *)key;
+ params.in_len = req->src_len;
+ params.out_len = req->dst_len;
+ ret = encrypt_blob(¶ms, in, out);
+ if (ret)
+ goto free;
+
+ if (dst)
+ scatterwalk_map_and_copy(dst, req->dst, 0, req->dst_len, 1);
+free:
+ kfree(src);
+ kfree(dst);
+ return ret;
+}
+
+static int asym_key_decrypt(const struct key *key, struct akcipher_request *req)
+{
+ struct kernel_pkey_params params = {0};
+ char *src = NULL, *dst = NULL, *in, *out;
+ int ret;
+
+ if (!sg_is_last(req->src)) {
+ src = kmalloc(req->src_len, GFP_KERNEL);
+ if (!src)
+ return -ENOMEM;
+ scatterwalk_map_and_copy(src, req->src, 0, req->src_len, 0);
+ in = src;
+ } else {
+ in = sg_virt(req->src);
+ }
+ if (!sg_is_last(req->dst)) {
+ dst = kmalloc(req->dst_len, GFP_KERNEL);
+ if (!dst) {
+ kfree(src);
+ return -ENOMEM;
+ }
+ out = dst;
+ } else {
+ out = sg_virt(req->dst);
+ }
+ params.key = (struct key *)key;
+ params.in_len = req->src_len;
+ params.out_len = req->dst_len;
+ ret = decrypt_blob(¶ms, in, out);
+ if (ret)
+ goto free;
+
+ if (dst)
+ scatterwalk_map_and_copy(dst, req->dst, 0, req->dst_len, 1);
+free:
+ kfree(src);
+ kfree(dst);
+ return ret;
+}
+
+static int asym_key_sign(const struct key *key, struct akcipher_request *req)
+{
+ struct kernel_pkey_params params = {0};
+ char *src = NULL, *dst = NULL, *in, *out;
+ int ret;
+
+ if (!sg_is_last(req->src)) {
+ src = kmalloc(req->src_len, GFP_KERNEL);
+ if (!src)
+ return -ENOMEM;
+ scatterwalk_map_and_copy(src, req->src, 0, req->src_len, 0);
+ in = src;
+ } else {
+ in = sg_virt(req->src);
+ }
+ if (!sg_is_last(req->dst)) {
+ dst = kmalloc(req->dst_len, GFP_KERNEL);
+ if (!dst) {
+ kfree(src);
+ return -ENOMEM;
+ }
+ out = dst;
+ } else {
+ out = sg_virt(req->dst);
+ }
+ params.key = (struct key *)key;
+ params.in_len = req->src_len;
+ params.out_len = req->dst_len;
+ ret = create_signature(¶ms, in, out);
+ if (ret)
+ goto free;
+
+ if (dst)
+ scatterwalk_map_and_copy(dst, req->dst, 0, req->dst_len, 1);
+free:
+ kfree(src);
+ kfree(dst);
+ return ret;
+}
+
+static int asym_key_verify(const struct key *key, struct akcipher_request *req)
+{
+ struct public_key_signature sig;
+ char *src = NULL, *in;
+ int ret;
+
+ if (!sg_is_last(req->src)) {
+ src = kmalloc(req->src_len, GFP_KERNEL);
+ if (!src)
+ return -ENOMEM;
+ scatterwalk_map_and_copy(src, req->src, 0, req->src_len, 0);
+ in = src;
+ } else {
+ in = sg_virt(req->src);
+ }
+ sig.pkey_algo = "rsa";
+ sig.encoding = "pkcs1";
+ /* Need to find a way to pass the hash param */
+ sig.hash_algo = "sha1";
+ sig.digest_size = 20;
+ sig.s_size = req->src_len;
+ sig.s = src;
+ ret = verify_signature(key, NULL, &sig);
+ kfree(src);
+ return ret;
+}
+
static int akcipher_recvmsg(struct socket *sock, struct msghdr *msg,
size_t ignored, int flags)
{
@@ -377,16 +528,28 @@ static int akcipher_recvmsg(struct socket *sock, struct msghdr *msg,
usedpages);
switch (ctx->op) {
case ALG_OP_VERIFY:
- err = crypto_akcipher_verify(&ctx->req);
+ if (ctx->key)
+ err = asym_key_verify(ctx->key, &ctx->req);
+ else
+ err = crypto_akcipher_verify(&ctx->req);
break;
case ALG_OP_SIGN:
- err = crypto_akcipher_sign(&ctx->req);
+ if (ctx->key)
+ err = asym_key_sign(ctx->key, &ctx->req);
+ else
+ err = crypto_akcipher_sign(&ctx->req);
break;
case ALG_OP_ENCRYPT:
- err = crypto_akcipher_encrypt(&ctx->req);
+ if (ctx->key)
+ err = asym_key_encrypt(ctx->key, &ctx->req);
+ else
+ err = crypto_akcipher_encrypt(&ctx->req);
break;
case ALG_OP_DECRYPT:
- err = crypto_akcipher_decrypt(&ctx->req);
+ if (ctx->key)
+ err = asym_key_decrypt(ctx->key, &ctx->req);
+ else
+ err = crypto_akcipher_decrypt(&ctx->req);
break;
default:
err = -EFAULT;
@@ -579,6 +742,27 @@ static void akcipher_release(void *private)
kfree(tfm);
}
+static int akcipher_setkeyid(void *private, const u8 *key, unsigned int keylen)
+{
+ struct akcipher_tfm *tfm = private;
+ struct key *akey;
+ u32 keyid = *((u32 *)key);
+ int err = -ENOKEY;
+
+ /* Store the key id and verify that a key with the given id is present.
+ * The actual key will be acquired in the accept_parent function
+ */
+ sprintf(tfm->keyid, "id:%08x", keyid);
+ akey = request_key(&key_type_asymmetric, tfm->keyid, NULL);
+ if (IS_ERR(key))
+ goto out;
+
+ tfm->has_key = true;
+ key_put(akey);
+out:
+ return err;
+}
+
static int akcipher_setprivkey(void *private, const u8 *key,
unsigned int keylen)
{
@@ -610,6 +794,8 @@ static void akcipher_sock_destruct(struct sock *sk)
akcipher_put_sgl(sk);
sock_kfree_s(sk, ctx, ctx->len);
af_alg_release_parent(sk);
+ if (ctx->key)
+ key_put(ctx->key);
}
static int akcipher_accept_parent_nokey(void *private, struct sock *sk)
@@ -618,6 +804,7 @@ static int akcipher_accept_parent_nokey(void *private, struct sock *sk)
struct alg_sock *ask = alg_sk(sk);
struct akcipher_tfm *tfm = private;
struct crypto_akcipher *akcipher = tfm->akcipher;
+ struct key *key;
unsigned int len = sizeof(*ctx) + crypto_akcipher_reqsize(akcipher);
ctx = sock_kmalloc(sk, len, GFP_KERNEL);
@@ -634,11 +821,20 @@ static int akcipher_accept_parent_nokey(void *private, struct sock *sk)
af_alg_init_completion(&ctx->completion);
sg_init_table(ctx->tsgl.sg, ALG_MAX_PAGES);
- ask->private = ctx;
+ if (strlen(tfm->keyid)) {
+ key = request_key(&key_type_asymmetric, tfm->keyid, NULL);
+ if (IS_ERR(key)) {
+ sock_kfree_s(sk, ctx, len);
+ return -ENOKEY;
+ }
+ ctx->key = key;
+ memset(tfm->keyid, '\0', sizeof(tfm->keyid));
+ }
akcipher_request_set_tfm(&ctx->req, akcipher);
akcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
af_alg_complete, &ctx->completion);
+ ask->private = ctx;
sk->sk_destruct = akcipher_sock_destruct;
@@ -660,6 +856,7 @@ static const struct af_alg_type algif_type_akcipher = {
.release = akcipher_release,
.setkey = akcipher_setprivkey,
.setpubkey = akcipher_setpubkey,
+ .setkeyid = akcipher_setkeyid,
.accept = akcipher_accept_parent,
.accept_nokey = akcipher_accept_parent_nokey,
.ops = &algif_akcipher_ops,
diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h
index 6c3e6e7..09c99ab 100644
--- a/include/crypto/if_alg.h
+++ b/include/crypto/if_alg.h
@@ -53,6 +53,7 @@ struct af_alg_type {
void (*release)(void *private);
int (*setkey)(void *private, const u8 *key, unsigned int keylen);
int (*setpubkey)(void *private, const u8 *key, unsigned int keylen);
+ int (*setkeyid)(void *private, const u8 *key, unsigned int keylen);
int (*accept)(void *private, struct sock *sk);
int (*accept_nokey)(void *private, struct sock *sk);
int (*setauthsize)(void *private, unsigned int authsize);
diff --git a/include/uapi/linux/if_alg.h b/include/uapi/linux/if_alg.h
index 02e6162..0379766 100644
--- a/include/uapi/linux/if_alg.h
+++ b/include/uapi/linux/if_alg.h
@@ -35,6 +35,8 @@ struct af_alg_iv {
#define ALG_SET_AEAD_ASSOCLEN 4
#define ALG_SET_AEAD_AUTHSIZE 5
#define ALG_SET_PUBKEY 6
+#define ALG_SET_PUBKEY_ID 7
+#define ALG_SET_KEY_ID 8
/* Operations */
#define ALG_OP_DECRYPT 0
^ permalink raw reply related
* [PATCH v6 5/6] crypto: algif_akcipher - add ops_nokey
From: Tadeusz Struk @ 2016-05-15 4:17 UTC (permalink / raw)
To: dhowells
Cc: herbert, tadeusz.struk, smueller, linux-api, marcel, linux-kernel,
keyrings, linux-crypto, dwmw2, davem
In-Reply-To: <20160515041645.15888.94903.stgit@tstruk-mobl1>
Similar to algif_skcipher and algif_hash, algif_akcipher needs
to prevent user space from using the interface in an improper way.
This patch adds nokey ops handlers, which do just that.
Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
crypto/algif_akcipher.c | 159 +++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 152 insertions(+), 7 deletions(-)
diff --git a/crypto/algif_akcipher.c b/crypto/algif_akcipher.c
index 6342b6e..e00793d 100644
--- a/crypto/algif_akcipher.c
+++ b/crypto/algif_akcipher.c
@@ -27,6 +27,11 @@ struct akcipher_sg_list {
struct scatterlist sg[ALG_MAX_PAGES];
};
+struct akcipher_tfm {
+ struct crypto_akcipher *akcipher;
+ bool has_key;
+};
+
struct akcipher_ctx {
struct akcipher_sg_list tsgl;
struct af_alg_sgl rsgl[ALG_MAX_PAGES];
@@ -450,25 +455,151 @@ static struct proto_ops algif_akcipher_ops = {
.poll = akcipher_poll,
};
+static int akcipher_check_key(struct socket *sock)
+{
+ int err = 0;
+ struct sock *psk;
+ struct alg_sock *pask;
+ struct akcipher_tfm *tfm;
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
+
+ lock_sock(sk);
+ if (ask->refcnt)
+ goto unlock_child;
+
+ psk = ask->parent;
+ pask = alg_sk(ask->parent);
+ tfm = pask->private;
+
+ err = -ENOKEY;
+ lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
+ if (!tfm->has_key)
+ goto unlock;
+
+ if (!pask->refcnt++)
+ sock_hold(psk);
+
+ ask->refcnt = 1;
+ sock_put(psk);
+
+ err = 0;
+
+unlock:
+ release_sock(psk);
+unlock_child:
+ release_sock(sk);
+
+ return err;
+}
+
+static int akcipher_sendmsg_nokey(struct socket *sock, struct msghdr *msg,
+ size_t size)
+{
+ int err;
+
+ err = akcipher_check_key(sock);
+ if (err)
+ return err;
+
+ return akcipher_sendmsg(sock, msg, size);
+}
+
+static ssize_t akcipher_sendpage_nokey(struct socket *sock, struct page *page,
+ int offset, size_t size, int flags)
+{
+ int err;
+
+ err = akcipher_check_key(sock);
+ if (err)
+ return err;
+
+ return akcipher_sendpage(sock, page, offset, size, flags);
+}
+
+static int akcipher_recvmsg_nokey(struct socket *sock, struct msghdr *msg,
+ size_t ignored, int flags)
+{
+ int err;
+
+ err = akcipher_check_key(sock);
+ if (err)
+ return err;
+
+ return akcipher_recvmsg(sock, msg, ignored, flags);
+}
+
+static struct proto_ops algif_akcipher_ops_nokey = {
+ .family = PF_ALG,
+
+ .connect = sock_no_connect,
+ .socketpair = sock_no_socketpair,
+ .getname = sock_no_getname,
+ .ioctl = sock_no_ioctl,
+ .listen = sock_no_listen,
+ .shutdown = sock_no_shutdown,
+ .getsockopt = sock_no_getsockopt,
+ .mmap = sock_no_mmap,
+ .bind = sock_no_bind,
+ .accept = sock_no_accept,
+ .setsockopt = sock_no_setsockopt,
+
+ .release = af_alg_release,
+ .sendmsg = akcipher_sendmsg_nokey,
+ .sendpage = akcipher_sendpage_nokey,
+ .recvmsg = akcipher_recvmsg_nokey,
+ .poll = akcipher_poll,
+};
+
static void *akcipher_bind(const char *name, u32 type, u32 mask)
{
- return crypto_alloc_akcipher(name, type, mask);
+ struct akcipher_tfm *tfm;
+ struct crypto_akcipher *akcipher;
+
+ tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
+ if (!tfm)
+ return ERR_PTR(-ENOMEM);
+
+ akcipher = crypto_alloc_akcipher(name, type, mask);
+ if (IS_ERR(akcipher)) {
+ kfree(tfm);
+ return ERR_CAST(akcipher);
+ }
+
+ tfm->akcipher = akcipher;
+ return tfm;
}
static void akcipher_release(void *private)
{
- crypto_free_akcipher(private);
+ struct akcipher_tfm *tfm = private;
+ struct crypto_akcipher *akcipher = tfm->akcipher;
+
+ crypto_free_akcipher(akcipher);
+ kfree(tfm);
}
static int akcipher_setprivkey(void *private, const u8 *key,
unsigned int keylen)
{
- return crypto_akcipher_set_priv_key(private, key, keylen);
+ struct akcipher_tfm *tfm = private;
+ struct crypto_akcipher *akcipher = tfm->akcipher;
+ int err;
+
+ err = crypto_akcipher_set_priv_key(akcipher, key, keylen);
+ tfm->has_key = !err;
+ return err;
}
static int akcipher_setpubkey(void *private, const u8 *key, unsigned int keylen)
{
- return crypto_akcipher_set_pub_key(private, key, keylen);
+ struct akcipher_tfm *tfm = private;
+ struct crypto_akcipher *akcipher = tfm->akcipher;
+ int err;
+
+ err = crypto_akcipher_set_pub_key(akcipher, key, keylen);
+ tfm->has_key = !err;
+ return err;
}
static void akcipher_sock_destruct(struct sock *sk)
@@ -481,11 +612,13 @@ static void akcipher_sock_destruct(struct sock *sk)
af_alg_release_parent(sk);
}
-static int akcipher_accept_parent(void *private, struct sock *sk)
+static int akcipher_accept_parent_nokey(void *private, struct sock *sk)
{
struct akcipher_ctx *ctx;
struct alg_sock *ask = alg_sk(sk);
- unsigned int len = sizeof(*ctx) + crypto_akcipher_reqsize(private);
+ struct akcipher_tfm *tfm = private;
+ struct crypto_akcipher *akcipher = tfm->akcipher;
+ unsigned int len = sizeof(*ctx) + crypto_akcipher_reqsize(akcipher);
ctx = sock_kmalloc(sk, len, GFP_KERNEL);
if (!ctx)
@@ -503,7 +636,7 @@ static int akcipher_accept_parent(void *private, struct sock *sk)
ask->private = ctx;
- akcipher_request_set_tfm(&ctx->req, private);
+ akcipher_request_set_tfm(&ctx->req, akcipher);
akcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
af_alg_complete, &ctx->completion);
@@ -512,13 +645,25 @@ static int akcipher_accept_parent(void *private, struct sock *sk)
return 0;
}
+static int akcipher_accept_parent(void *private, struct sock *sk)
+{
+ struct akcipher_tfm *tfm = private;
+
+ if (!tfm->has_key)
+ return -ENOKEY;
+
+ return akcipher_accept_parent_nokey(private, sk);
+}
+
static const struct af_alg_type algif_type_akcipher = {
.bind = akcipher_bind,
.release = akcipher_release,
.setkey = akcipher_setprivkey,
.setpubkey = akcipher_setpubkey,
.accept = akcipher_accept_parent,
+ .accept_nokey = akcipher_accept_parent_nokey,
.ops = &algif_akcipher_ops,
+ .ops_nokey = &algif_akcipher_ops_nokey,
.name = "akcipher",
.owner = THIS_MODULE
};
^ permalink raw reply related
* [PATCH v6 3/6] crypto: AF_ALG -- add asymmetric cipher interface
From: Tadeusz Struk @ 2016-05-15 4:17 UTC (permalink / raw)
To: dhowells
Cc: herbert, tadeusz.struk, smueller, linux-api, marcel, linux-kernel,
keyrings, linux-crypto, dwmw2, davem
In-Reply-To: <20160515041645.15888.94903.stgit@tstruk-mobl1>
From: Stephan Mueller <smueller@chronox.de>
This patch adds the user space interface for asymmetric ciphers. The
interface allows the use of sendmsg as well as vmsplice to provide data.
This version has been rebased on top of 4.6 and a few chackpatch issues
have been fixed.
Signed-off-by: Stephan Mueller <smueller@chronox.de>
Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
crypto/algif_akcipher.c | 542 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 542 insertions(+)
create mode 100644 crypto/algif_akcipher.c
diff --git a/crypto/algif_akcipher.c b/crypto/algif_akcipher.c
new file mode 100644
index 0000000..6342b6e
--- /dev/null
+++ b/crypto/algif_akcipher.c
@@ -0,0 +1,542 @@
+/*
+ * algif_akcipher: User-space interface for asymmetric cipher algorithms
+ *
+ * Copyright (C) 2015, Stephan Mueller <smueller@chronox.de>
+ *
+ * This file provides the user-space API for asymmetric ciphers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <crypto/akcipher.h>
+#include <crypto/scatterwalk.h>
+#include <crypto/if_alg.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/net.h>
+#include <net/sock.h>
+
+struct akcipher_sg_list {
+ unsigned int cur;
+ struct scatterlist sg[ALG_MAX_PAGES];
+};
+
+struct akcipher_ctx {
+ struct akcipher_sg_list tsgl;
+ struct af_alg_sgl rsgl[ALG_MAX_PAGES];
+
+ struct af_alg_completion completion;
+
+ unsigned long used;
+
+ unsigned int len;
+ bool more;
+ bool merge;
+ int op;
+
+ struct akcipher_request req;
+};
+
+static inline int akcipher_sndbuf(struct sock *sk)
+{
+ struct alg_sock *ask = alg_sk(sk);
+ struct akcipher_ctx *ctx = ask->private;
+
+ return max_t(int, max_t(int, sk->sk_sndbuf & PAGE_MASK, PAGE_SIZE) -
+ ctx->used, 0);
+}
+
+static inline bool akcipher_writable(struct sock *sk)
+{
+ return akcipher_sndbuf(sk) >= PAGE_SIZE;
+}
+
+static inline int akcipher_calcsize(struct akcipher_ctx *ctx)
+{
+ return crypto_akcipher_maxsize(crypto_akcipher_reqtfm(&ctx->req));
+}
+
+static void akcipher_put_sgl(struct sock *sk)
+{
+ struct alg_sock *ask = alg_sk(sk);
+ struct akcipher_ctx *ctx = ask->private;
+ struct akcipher_sg_list *sgl = &ctx->tsgl;
+ struct scatterlist *sg = sgl->sg;
+ unsigned int i;
+
+ for (i = 0; i < sgl->cur; i++) {
+ if (!sg_page(sg + i))
+ continue;
+
+ put_page(sg_page(sg + i));
+ sg_assign_page(sg + i, NULL);
+ }
+ sg_init_table(sg, ALG_MAX_PAGES);
+ sgl->cur = 0;
+ ctx->used = 0;
+ ctx->more = 0;
+ ctx->merge = 0;
+}
+
+static void akcipher_wmem_wakeup(struct sock *sk)
+{
+ struct socket_wq *wq;
+
+ if (!akcipher_writable(sk))
+ return;
+
+ rcu_read_lock();
+ wq = rcu_dereference(sk->sk_wq);
+ if (wq_has_sleeper(&wq->wait))
+ wake_up_interruptible_sync_poll(&wq->wait, POLLIN |
+ POLLRDNORM |
+ POLLRDBAND);
+ sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
+ rcu_read_unlock();
+}
+
+static int akcipher_wait_for_data(struct sock *sk, unsigned int flags)
+{
+ struct alg_sock *ask = alg_sk(sk);
+ struct akcipher_ctx *ctx = ask->private;
+ long timeout;
+ DEFINE_WAIT(wait);
+ int err = -ERESTARTSYS;
+
+ if (flags & MSG_DONTWAIT)
+ return -EAGAIN;
+
+ set_bit(SOCKWQ_ASYNC_WAITDATA, &sk->sk_socket->flags);
+
+ for (;;) {
+ if (signal_pending(current))
+ break;
+ prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
+ timeout = MAX_SCHEDULE_TIMEOUT;
+ if (sk_wait_event(sk, &timeout, !ctx->more)) {
+ err = 0;
+ break;
+ }
+ }
+ finish_wait(sk_sleep(sk), &wait);
+
+ clear_bit(SOCKWQ_ASYNC_WAITDATA, &sk->sk_socket->flags);
+
+ return err;
+}
+
+static void akcipher_data_wakeup(struct sock *sk)
+{
+ struct alg_sock *ask = alg_sk(sk);
+ struct akcipher_ctx *ctx = ask->private;
+ struct socket_wq *wq;
+
+ if (ctx->more)
+ return;
+ if (!ctx->used)
+ return;
+
+ rcu_read_lock();
+ wq = rcu_dereference(sk->sk_wq);
+ if (wq_has_sleeper(&wq->wait))
+ wake_up_interruptible_sync_poll(&wq->wait, POLLOUT |
+ POLLRDNORM |
+ POLLRDBAND);
+ sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
+ rcu_read_unlock();
+}
+
+static int akcipher_sendmsg(struct socket *sock, struct msghdr *msg,
+ size_t size)
+{
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
+ struct akcipher_ctx *ctx = ask->private;
+ struct akcipher_sg_list *sgl = &ctx->tsgl;
+ struct af_alg_control con = {};
+ long copied = 0;
+ int op = 0;
+ bool init = 0;
+ int err;
+
+ if (msg->msg_controllen) {
+ err = af_alg_cmsg_send(msg, &con);
+ if (err)
+ return err;
+
+ init = 1;
+ switch (con.op) {
+ case ALG_OP_VERIFY:
+ case ALG_OP_SIGN:
+ case ALG_OP_ENCRYPT:
+ case ALG_OP_DECRYPT:
+ op = con.op;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ lock_sock(sk);
+ if (!ctx->more && ctx->used)
+ goto unlock;
+
+ if (init)
+ ctx->op = op;
+
+ while (size) {
+ unsigned long len = size;
+ struct scatterlist *sg = NULL;
+
+ /* use the existing memory in an allocated page */
+ if (ctx->merge) {
+ sg = sgl->sg + sgl->cur - 1;
+ len = min_t(unsigned long, len,
+ PAGE_SIZE - sg->offset - sg->length);
+ err = memcpy_from_msg(page_address(sg_page(sg)) +
+ sg->offset + sg->length,
+ msg, len);
+ if (err)
+ goto unlock;
+
+ sg->length += len;
+ ctx->merge = (sg->offset + sg->length) &
+ (PAGE_SIZE - 1);
+
+ ctx->used += len;
+ copied += len;
+ size -= len;
+ continue;
+ }
+
+ if (!akcipher_writable(sk)) {
+ /* user space sent too much data */
+ akcipher_put_sgl(sk);
+ err = -EMSGSIZE;
+ goto unlock;
+ }
+
+ /* allocate a new page */
+ len = min_t(unsigned long, size, akcipher_sndbuf(sk));
+ while (len) {
+ int plen = 0;
+
+ if (sgl->cur >= ALG_MAX_PAGES) {
+ akcipher_put_sgl(sk);
+ err = -E2BIG;
+ goto unlock;
+ }
+
+ sg = sgl->sg + sgl->cur;
+ plen = min_t(int, len, PAGE_SIZE);
+
+ sg_assign_page(sg, alloc_page(GFP_KERNEL));
+ if (!sg_page(sg)) {
+ err = -ENOMEM;
+ goto unlock;
+ }
+
+ err = memcpy_from_msg(page_address(sg_page(sg)),
+ msg, plen);
+ if (err) {
+ __free_page(sg_page(sg));
+ sg_assign_page(sg, NULL);
+ goto unlock;
+ }
+
+ sg->offset = 0;
+ sg->length = plen;
+ len -= plen;
+ ctx->used += plen;
+ copied += plen;
+ sgl->cur++;
+ size -= plen;
+ ctx->merge = plen & (PAGE_SIZE - 1);
+ }
+ }
+
+ err = 0;
+
+ ctx->more = msg->msg_flags & MSG_MORE;
+
+unlock:
+ akcipher_data_wakeup(sk);
+ release_sock(sk);
+
+ return err ?: copied;
+}
+
+static ssize_t akcipher_sendpage(struct socket *sock, struct page *page,
+ int offset, size_t size, int flags)
+{
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
+ struct akcipher_ctx *ctx = ask->private;
+ struct akcipher_sg_list *sgl = &ctx->tsgl;
+ int err = 0;
+
+ if (flags & MSG_SENDPAGE_NOTLAST)
+ flags |= MSG_MORE;
+
+ if (sgl->cur >= ALG_MAX_PAGES)
+ return -E2BIG;
+
+ lock_sock(sk);
+ if (!ctx->more && ctx->used)
+ goto unlock;
+
+ if (!size)
+ goto done;
+
+ if (!akcipher_writable(sk)) {
+ /* user space sent too much data */
+ akcipher_put_sgl(sk);
+ err = -EMSGSIZE;
+ goto unlock;
+ }
+
+ ctx->merge = 0;
+
+ get_page(page);
+ sg_set_page(sgl->sg + sgl->cur, page, size, offset);
+ sgl->cur++;
+ ctx->used += size;
+
+done:
+ ctx->more = flags & MSG_MORE;
+unlock:
+ akcipher_data_wakeup(sk);
+ release_sock(sk);
+
+ return err ? err : size;
+}
+
+static int akcipher_recvmsg(struct socket *sock, struct msghdr *msg,
+ size_t ignored, int flags)
+{
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
+ struct akcipher_ctx *ctx = ask->private;
+ struct akcipher_sg_list *sgl = &ctx->tsgl;
+ unsigned int i = 0;
+ int err;
+ unsigned long used = 0;
+ size_t usedpages = 0;
+ unsigned int cnt = 0;
+
+ /* Limit number of IOV blocks to be accessed below */
+ if (msg->msg_iter.nr_segs > ALG_MAX_PAGES)
+ return -ENOMSG;
+
+ lock_sock(sk);
+
+ if (ctx->more) {
+ err = akcipher_wait_for_data(sk, flags);
+ if (err)
+ goto unlock;
+ }
+
+ used = ctx->used;
+
+ /* convert iovecs of output buffers into scatterlists */
+ while (iov_iter_count(&msg->msg_iter)) {
+ /* make one iovec available as scatterlist */
+ err = af_alg_make_sg(&ctx->rsgl[cnt], &msg->msg_iter,
+ iov_iter_count(&msg->msg_iter));
+ if (err < 0)
+ goto unlock;
+ usedpages += err;
+ /* chain the new scatterlist with previous one */
+ if (cnt)
+ af_alg_link_sg(&ctx->rsgl[cnt - 1], &ctx->rsgl[cnt]);
+
+ iov_iter_advance(&msg->msg_iter, err);
+ cnt++;
+ }
+
+ /* ensure output buffer is sufficiently large */
+ if (usedpages < akcipher_calcsize(ctx)) {
+ err = -EMSGSIZE;
+ goto unlock;
+ }
+
+ sg_mark_end(sgl->sg + sgl->cur - 1);
+
+ akcipher_request_set_crypt(&ctx->req, sgl->sg, ctx->rsgl[0].sg, used,
+ usedpages);
+ switch (ctx->op) {
+ case ALG_OP_VERIFY:
+ err = crypto_akcipher_verify(&ctx->req);
+ break;
+ case ALG_OP_SIGN:
+ err = crypto_akcipher_sign(&ctx->req);
+ break;
+ case ALG_OP_ENCRYPT:
+ err = crypto_akcipher_encrypt(&ctx->req);
+ break;
+ case ALG_OP_DECRYPT:
+ err = crypto_akcipher_decrypt(&ctx->req);
+ break;
+ default:
+ err = -EFAULT;
+ goto unlock;
+ }
+
+ err = af_alg_wait_for_completion(err, &ctx->completion);
+
+ if (err) {
+ /* EBADMSG implies a valid cipher operation took place */
+ if (err == -EBADMSG)
+ akcipher_put_sgl(sk);
+ goto unlock;
+ }
+
+ akcipher_put_sgl(sk);
+
+unlock:
+ for (i = 0; i < cnt; i++)
+ af_alg_free_sg(&ctx->rsgl[i]);
+
+ akcipher_wmem_wakeup(sk);
+ release_sock(sk);
+
+ return err ? err : ctx->req.dst_len;
+}
+
+static unsigned int akcipher_poll(struct file *file, struct socket *sock,
+ poll_table *wait)
+{
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
+ struct akcipher_ctx *ctx = ask->private;
+ unsigned int mask = 0;
+
+ sock_poll_wait(file, sk_sleep(sk), wait);
+
+ if (!ctx->more)
+ mask |= POLLIN | POLLRDNORM;
+
+ if (akcipher_writable(sk))
+ mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
+
+ return mask;
+}
+
+static struct proto_ops algif_akcipher_ops = {
+ .family = PF_ALG,
+
+ .connect = sock_no_connect,
+ .socketpair = sock_no_socketpair,
+ .getname = sock_no_getname,
+ .ioctl = sock_no_ioctl,
+ .listen = sock_no_listen,
+ .shutdown = sock_no_shutdown,
+ .getsockopt = sock_no_getsockopt,
+ .mmap = sock_no_mmap,
+ .bind = sock_no_bind,
+ .accept = sock_no_accept,
+ .setsockopt = sock_no_setsockopt,
+
+ .release = af_alg_release,
+ .sendmsg = akcipher_sendmsg,
+ .sendpage = akcipher_sendpage,
+ .recvmsg = akcipher_recvmsg,
+ .poll = akcipher_poll,
+};
+
+static void *akcipher_bind(const char *name, u32 type, u32 mask)
+{
+ return crypto_alloc_akcipher(name, type, mask);
+}
+
+static void akcipher_release(void *private)
+{
+ crypto_free_akcipher(private);
+}
+
+static int akcipher_setprivkey(void *private, const u8 *key,
+ unsigned int keylen)
+{
+ return crypto_akcipher_set_priv_key(private, key, keylen);
+}
+
+static int akcipher_setpubkey(void *private, const u8 *key, unsigned int keylen)
+{
+ return crypto_akcipher_set_pub_key(private, key, keylen);
+}
+
+static void akcipher_sock_destruct(struct sock *sk)
+{
+ struct alg_sock *ask = alg_sk(sk);
+ struct akcipher_ctx *ctx = ask->private;
+
+ akcipher_put_sgl(sk);
+ sock_kfree_s(sk, ctx, ctx->len);
+ af_alg_release_parent(sk);
+}
+
+static int akcipher_accept_parent(void *private, struct sock *sk)
+{
+ struct akcipher_ctx *ctx;
+ struct alg_sock *ask = alg_sk(sk);
+ unsigned int len = sizeof(*ctx) + crypto_akcipher_reqsize(private);
+
+ ctx = sock_kmalloc(sk, len, GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+ memset(ctx, 0, len);
+
+ ctx->len = len;
+ ctx->used = 0;
+ ctx->more = 0;
+ ctx->merge = 0;
+ ctx->op = 0;
+ ctx->tsgl.cur = 0;
+ af_alg_init_completion(&ctx->completion);
+ sg_init_table(ctx->tsgl.sg, ALG_MAX_PAGES);
+
+ ask->private = ctx;
+
+ akcipher_request_set_tfm(&ctx->req, private);
+ akcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ af_alg_complete, &ctx->completion);
+
+ sk->sk_destruct = akcipher_sock_destruct;
+
+ return 0;
+}
+
+static const struct af_alg_type algif_type_akcipher = {
+ .bind = akcipher_bind,
+ .release = akcipher_release,
+ .setkey = akcipher_setprivkey,
+ .setpubkey = akcipher_setpubkey,
+ .accept = akcipher_accept_parent,
+ .ops = &algif_akcipher_ops,
+ .name = "akcipher",
+ .owner = THIS_MODULE
+};
+
+static int __init algif_akcipher_init(void)
+{
+ return af_alg_register_type(&algif_type_akcipher);
+}
+
+static void __exit algif_akcipher_exit(void)
+{
+ int err = af_alg_unregister_type(&algif_type_akcipher);
+
+ WARN_ON(err);
+}
+
+module_init(algif_akcipher_init);
+module_exit(algif_akcipher_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>");
+MODULE_DESCRIPTION("Asymmetric kernel crypto API user space interface");
^ permalink raw reply related
* [PATCH v6 1/6] crypto: AF_ALG -- add sign/verify API
From: Tadeusz Struk @ 2016-05-15 4:16 UTC (permalink / raw)
To: dhowells
Cc: herbert, tadeusz.struk, smueller, linux-api, marcel, linux-kernel,
keyrings, linux-crypto, dwmw2, davem
In-Reply-To: <20160515041645.15888.94903.stgit@tstruk-mobl1>
From: Stephan Mueller <smueller@chronox.de>
Add the flags for handling signature generation and signature
verification.
Also, the patch adds the interface for setting a public key.
Signed-off-by: Stephan Mueller <smueller@chronox.de>
Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
include/uapi/linux/if_alg.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/include/uapi/linux/if_alg.h b/include/uapi/linux/if_alg.h
index f2acd2f..02e6162 100644
--- a/include/uapi/linux/if_alg.h
+++ b/include/uapi/linux/if_alg.h
@@ -34,9 +34,12 @@ struct af_alg_iv {
#define ALG_SET_OP 3
#define ALG_SET_AEAD_ASSOCLEN 4
#define ALG_SET_AEAD_AUTHSIZE 5
+#define ALG_SET_PUBKEY 6
/* Operations */
#define ALG_OP_DECRYPT 0
#define ALG_OP_ENCRYPT 1
+#define ALG_OP_SIGN 2
+#define ALG_OP_VERIFY 3
#endif /* _LINUX_IF_ALG_H */
^ permalink raw reply related
* [PATCH v6 0/6] crypto: algif - add akcipher
From: Tadeusz Struk @ 2016-05-15 4:16 UTC (permalink / raw)
To: dhowells-H+wXaHxf7aLQT0dZR+AlfA
Cc: herbert-lOAM2aK0SrRLBo1qDEOMRrpzq4S04n8Q,
tadeusz.struk-ral2JQCrhuEAvxtiuMwx3w,
smueller-T9tCv8IpfcWELgA04lAiVw, linux-api-u79uwXL29TY76Z2rM5mHXA,
marcel-kz+m5ild9QBg9hUCZPvPmw,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
keyrings-u79uwXL29TY76Z2rM5mHXA,
linux-crypto-u79uwXL29TY76Z2rM5mHXA, dwmw2-wEGCiKHe2LqWVfeAwA7xHQ,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <5123.1462976721-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
First four patches are a resend of the v3 algif_akcipher from
Stephan Mueller, with minor changes after rebase on top of 4.6-rc1.
The next three patches add support for keys stored in system
keyring subsystem.
First patch adds algif_akcipher nokey hadlers.
Second patch adds generic sign, verify, encrypt, decrypt accessors
functions to the asymmetric key type. These will be defined by
asymmetric subtypes, similarly to how public_key currently defines
the verify_signature function.
Third patch adds support for ALG_SET_KEY_ID and ALG_SET_PUBKEY_ID
commands to AF_ALG and setkeyid operation to the af_alg_type struct.
If the keyid is used then the afalg layer acquires the key for the
keyring subsystem and uses the new asymmetric accessor functions
instead of akcipher api. The asymmetric subtypes can use akcipher
api internally.
This is the same v5 version as before rebased on top of
http://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=keys-asym-keyctl
v6 changes:
- update to reflect changes in kernel_pkey_params struct
v5 changes:
- drop public key changes and use new version provided by David
v4 changes:
- don't use internal public_key struct in af_alg.
- add generic accessor functions to asymmetric key type, which take
the generic struct key type and resolve the specific subtype internally
v3 changes:
- include Stephan's patches (rebased on 4.6-rc1)
- add algif_akcipher nokey hadlers
- add public_key info struct to public_key and helper query functions
- add a check if a key is a software accessible key on af_alg, and
return -ENOKEY if it isn't
v2 changes:
- pass the original skcipher request in ablkcipher.base.data instead of
casting it back from the ablkcipher request.
- rename _req to base_req
- dropped 3/3
---
Stephan Mueller (4):
crypto: AF_ALG -- add sign/verify API
crypto: AF_ALG -- add setpubkey setsockopt call
crypto: AF_ALG -- add asymmetric cipher interface
crypto: algif_akcipher - enable compilation
Tadeusz Struk (2):
crypto: algif_akcipher - add ops_nokey
crypto: AF_ALG - add support for key_id
crypto/Kconfig | 9
crypto/Makefile | 1
crypto/af_alg.c | 28 +
crypto/algif_akcipher.c | 884 +++++++++++++++++++++++++++++++++++++++++++
include/crypto/if_alg.h | 2
include/uapi/linux/if_alg.h | 5
6 files changed, 924 insertions(+), 5 deletions(-)
create mode 100644 crypto/algif_akcipher.c
--
TS
^ permalink raw reply
* (unknown),
From: membership @ 2016-05-15 3:15 UTC (permalink / raw)
To: linux-crypto
[-- Attachment #1: EMAIL_990863_linux-crypto.zip --]
[-- Type: application/zip, Size: 2094 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox