Re: [PATCH] X.509: unpack RSA signatureValue field from BIT STRING

2018-03-07 Thread David Howells
Maciej S. Szmigiero  wrote:

> + if (!strcmp(ctx->cert->sig->pkey_algo, "rsa")) {

I'm going to change this to '== 0' rather than '!'.

David


[RFC PATCH] KEYS: Use individual pages in big_key for crypto buffers [ver #3]

2018-02-16 Thread David Howells
kmalloc() can't always allocate large enough buffers for big_key to use for
crypto (1MB + some metadata) so we cannot use that to allocate the buffer.
Further, vmalloc'd pages can't be passed to sg_init_one() and the aead
crypto accessors cannot be called progressively and must be passed all the
data in one go (which means we can't pass the data in one block at a time).

Fix this by allocating the buffer pages individually and passing them
through a multientry scatterlist to the crypto layer.  This has the bonus
advantage that we don't have to allocate a contiguous series of pages.

We then vmap() the page list and pass that through to the VFS read/write
routines.

This can trigger a warning:

WARNING: CPU: 0 PID: 60912 at mm/page_alloc.c:3883 
__alloc_pages_nodemask+0xb7c/0x15f8
([<002acbb6>] __alloc_pages_nodemask+0x1ee/0x15f8)
 [<002dd356>] kmalloc_order+0x46/0x90
 [<002dd3e0>] kmalloc_order_trace+0x40/0x1f8
 [<00326a10>] __kmalloc+0x430/0x4c0
 [<004343e4>] big_key_preparse+0x7c/0x210
 [<0042c040>] key_create_or_update+0x128/0x420
 [<0042e52c>] SyS_add_key+0x124/0x220
 [<007bba2c>] system_call+0xc4/0x2b0

from the keyctl/padd/useradd test of the keyutils testsuite on s390x.

Note that it might be better to shovel data through in page-sized lumps
instead as there's no particular need to use a monolithic buffer unless the
kernel itself wants to access the data.

Fixes: 13100a72f40f ("Security: Keys: Big keys stored encrypted")
Reported-by: Paul Bunyan <pbun...@redhat.com>
Signed-off-by: David Howells <dhowe...@redhat.com>
cc: Kirill Marinushkin <k.marinush...@gmail.com>
---

 security/keys/big_key.c |  110 +--
 1 file changed, 87 insertions(+), 23 deletions(-)

diff --git a/security/keys/big_key.c b/security/keys/big_key.c
index 929e14978c42..4e99e8ba8612 100644
--- a/security/keys/big_key.c
+++ b/security/keys/big_key.c
@@ -22,6 +22,13 @@
 #include 
 #include 
 
+struct big_key_buf {
+   unsigned intnr_pages;
+   void*virt;
+   struct scatterlist  *sg;
+   struct page *pages[];
+};
+
 /*
  * Layout of key payload words.
  */
@@ -91,10 +98,9 @@ static DEFINE_MUTEX(big_key_aead_lock);
 /*
  * Encrypt/decrypt big_key data
  */
-static int big_key_crypt(enum big_key_op op, u8 *data, size_t datalen, u8 *key)
+static int big_key_crypt(enum big_key_op op, struct big_key_buf *buf, size_t 
datalen, u8 *key)
 {
int ret;
-   struct scatterlist sgio;
struct aead_request *aead_req;
/* We always use a zero nonce. The reason we can get away with this is
 * because we're using a different randomly generated key for every
@@ -109,8 +115,7 @@ static int big_key_crypt(enum big_key_op op, u8 *data, 
size_t datalen, u8 *key)
return -ENOMEM;
 
memset(zero_nonce, 0, sizeof(zero_nonce));
-   sg_init_one(, data, datalen + (op == BIG_KEY_ENC ? 
ENC_AUTHTAG_SIZE : 0));
-   aead_request_set_crypt(aead_req, , , datalen, zero_nonce);
+   aead_request_set_crypt(aead_req, buf->sg, buf->sg, datalen, zero_nonce);
aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, 
NULL);
aead_request_set_ad(aead_req, 0);
 
@@ -130,21 +135,81 @@ static int big_key_crypt(enum big_key_op op, u8 *data, 
size_t datalen, u8 *key)
 }
 
 /*
+ * Free up the buffer.
+ */
+static void big_key_free_buffer(struct big_key_buf *buf)
+{
+   unsigned int i;
+
+   if (buf->virt) {
+   memset(buf->virt, 0, buf->nr_pages * PAGE_SIZE);
+   vunmap(buf->virt);
+   }
+
+   for (i = 0; i < buf->nr_pages; i++)
+   if (buf->pages[i])
+   __free_page(buf->pages[i]);
+
+   kfree(buf);
+}
+
+/*
+ * Allocate a buffer consisting of a set of pages with a virtual mapping
+ * applied over them.
+ */
+static void *big_key_alloc_buffer(size_t len)
+{
+   struct big_key_buf *buf;
+   unsigned int npg = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
+   unsigned int i, l;
+
+   buf = kzalloc(sizeof(struct big_key_buf) +
+ sizeof(struct page) * npg +
+ sizeof(struct scatterlist) * npg,
+ GFP_KERNEL);
+   if (!buf)
+   return NULL;
+
+   buf->nr_pages = npg;
+   buf->sg = (void *)(buf->pages + npg);
+   sg_init_table(buf->sg, npg);
+
+   for (i = 0; i < buf->nr_pages; i++) {
+   buf->pages[i] = alloc_page(GFP_KERNEL);
+   if (!buf->pages[i])
+   goto nomem;
+
+   l = min(len, PAGE_SIZE);
+   sg_set_page(>sg[i], buf->pages[i], l, 0);
+   len -= l;
+   }
+
+   

Re: [RFC PATCH] KEYS: Use individual pages in big_key for crypto buffers [ver #2]

2018-02-16 Thread David Howells
Eric Biggers  wrote:

> memset() after vunmap(), and also when buf->virt can be NULL?  I had 
> suggested:
> 
> if (buf->virt) {
> memset(buf->virt, 0, buf->nr_pages * PAGE_SIZE);
> vunmap(buf->virt);
> }

Sorry, yes.  I don't know why the change I made doesn't oops.

David


[RFC PATCH] KEYS: Use individual pages in big_key for crypto buffers [ver #2]

2018-02-15 Thread David Howells
kmalloc() can't always allocate large enough buffers for big_key to use for
crypto (1MB + some metadata) so we cannot use that to allocate the buffer.
Further, vmalloc'd pages can't be passed to sg_init_one() and the aead
crypto accessors cannot be called progressively and must be passed all the
data in one go (which means we can't pass the data in one block at a time).

Fix this by allocating the buffer pages individually and passing them
through a multientry scatterlist to the crypto layer.  This has the bonus
advantage that we don't have to allocate a contiguous series of pages.

We then vmap() the page list and pass that through to the VFS read/write
routines.

This can trigger a warning:

WARNING: CPU: 0 PID: 60912 at mm/page_alloc.c:3883 
__alloc_pages_nodemask+0xb7c/0x15f8
([<002acbb6>] __alloc_pages_nodemask+0x1ee/0x15f8)
 [<002dd356>] kmalloc_order+0x46/0x90
 [<002dd3e0>] kmalloc_order_trace+0x40/0x1f8
 [<00326a10>] __kmalloc+0x430/0x4c0
 [<004343e4>] big_key_preparse+0x7c/0x210
 [<0042c040>] key_create_or_update+0x128/0x420
 [<0042e52c>] SyS_add_key+0x124/0x220
 [<007bba2c>] system_call+0xc4/0x2b0

from the keyctl/padd/useradd test of the keyutils testsuite on s390x.

Note that it might be better to shovel data through in page-sized lumps
instead as there's no particular need to use a monolithic buffer unless the
kernel itself wants to access the data.

Fixes: 13100a72f40f ("Security: Keys: Big keys stored encrypted")
Reported-by: Paul Bunyan <pbun...@redhat.com>
Signed-off-by: David Howells <dhowe...@redhat.com>
cc: Kirill Marinushkin <k.marinush...@gmail.com>
---

 security/keys/big_key.c |  107 +--
 1 file changed, 84 insertions(+), 23 deletions(-)

diff --git a/security/keys/big_key.c b/security/keys/big_key.c
index 929e14978c42..4deb7df56ec8 100644
--- a/security/keys/big_key.c
+++ b/security/keys/big_key.c
@@ -22,6 +22,13 @@
 #include 
 #include 
 
+struct big_key_buf {
+   unsigned intnr_pages;
+   void*virt;
+   struct scatterlist  *sg;
+   struct page *pages[];
+};
+
 /*
  * Layout of key payload words.
  */
@@ -91,10 +98,9 @@ static DEFINE_MUTEX(big_key_aead_lock);
 /*
  * Encrypt/decrypt big_key data
  */
-static int big_key_crypt(enum big_key_op op, u8 *data, size_t datalen, u8 *key)
+static int big_key_crypt(enum big_key_op op, struct big_key_buf *buf, size_t 
datalen, u8 *key)
 {
int ret;
-   struct scatterlist sgio;
struct aead_request *aead_req;
/* We always use a zero nonce. The reason we can get away with this is
 * because we're using a different randomly generated key for every
@@ -109,8 +115,7 @@ static int big_key_crypt(enum big_key_op op, u8 *data, 
size_t datalen, u8 *key)
return -ENOMEM;
 
memset(zero_nonce, 0, sizeof(zero_nonce));
-   sg_init_one(, data, datalen + (op == BIG_KEY_ENC ? 
ENC_AUTHTAG_SIZE : 0));
-   aead_request_set_crypt(aead_req, , , datalen, zero_nonce);
+   aead_request_set_crypt(aead_req, buf->sg, buf->sg, datalen, zero_nonce);
aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, 
NULL);
aead_request_set_ad(aead_req, 0);
 
@@ -130,21 +135,78 @@ static int big_key_crypt(enum big_key_op op, u8 *data, 
size_t datalen, u8 *key)
 }
 
 /*
+ * Free up the buffer.
+ */
+static void big_key_free_buffer(struct big_key_buf *buf)
+{
+   unsigned int i;
+
+   vunmap(buf->virt);
+   for (i = 0; i < buf->nr_pages; i++)
+   if (buf->pages[i])
+   __free_page(buf->pages[i]);
+
+   memset(buf->virt, 0, buf->nr_pages * PAGE_SIZE);
+   kfree(buf);
+}
+
+/*
+ * Allocate a buffer consisting of a set of pages with a virtual mapping
+ * applied over them.
+ */
+static void *big_key_alloc_buffer(size_t len)
+{
+   struct big_key_buf *buf;
+   unsigned int npg = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
+   unsigned int i, l;
+
+   buf = kzalloc(sizeof(struct big_key_buf) +
+ sizeof(struct page) * npg +
+ sizeof(struct scatterlist) * npg,
+ GFP_KERNEL);
+   if (!buf)
+   return NULL;
+
+   buf->nr_pages = npg;
+   buf->sg = (void *)(buf->pages + npg);
+   sg_init_table(buf->sg, npg);
+
+   for (i = 0; i < buf->nr_pages; i++) {
+   buf->pages[i] = alloc_page(GFP_KERNEL);
+   if (!buf->pages[i])
+   goto nomem;
+
+   l = min(len, PAGE_SIZE);
+   sg_set_page(>sg[i], buf->pages[i], l, 0);
+   len -= l;
+   }
+
+   buf->virt = vmap(buf->pages, buf->

Re: [RFC PATCH] KEYS: Use individual pages in big_key for crypto buffers

2018-02-15 Thread David Howells
Eric Biggers  wrote:

> If big_key_alloc_buffer() fails to allocate one of the pages then some of
> the pages may still be NULL here, causing __free_page() to crash.  You need
> to check for NULL first.

Ah, yes.  I incorrectly used free_page() first - and that does check for a
NULL pointer.  Applied your other changes also.

David


[RFC PATCH] KEYS: Use individual pages in big_key for crypto buffers

2018-02-15 Thread David Howells
kmalloc() can't always allocate large enough buffers for big_key to use for
crypto (1MB + some metadata) so we cannot use that to allocate the buffer.
Further, vmalloc'd pages can't be passed to sg_init_one() and the aead
crypto accessors cannot be called progressively and must be passed all the
data in one go (which means we can't pass the data in one block at a time).

Fix this by allocating the buffer pages individually and passing them
through a multientry scatterlist to the crypto layer.  This has the bonus
advantage that we don't have to allocate a contiguous series of pages.

We then vmap() the page list and pass that through to the VFS read/write
routines.

This can trigger a warning:

WARNING: CPU: 0 PID: 60912 at mm/page_alloc.c:3883 
__alloc_pages_nodemask+0xb7c/0x15f8
([<002acbb6>] __alloc_pages_nodemask+0x1ee/0x15f8)
 [<002dd356>] kmalloc_order+0x46/0x90
 [<002dd3e0>] kmalloc_order_trace+0x40/0x1f8
 [<00326a10>] __kmalloc+0x430/0x4c0
 [<004343e4>] big_key_preparse+0x7c/0x210
 [<0042c040>] key_create_or_update+0x128/0x420
 [<0042e52c>] SyS_add_key+0x124/0x220
 [<007bba2c>] system_call+0xc4/0x2b0

from the keyctl/padd/useradd test of the keyutils testsuite on s390x.

Note that it might be better to shovel data through in page-sized lumps
instead as there's no particular need to use a monolithic buffer unless the
kernel itself wants to access the data.

Fixes: 13100a72f40f ("Security: Keys: Big keys stored encrypted")
Reported-by: Paul Bunyan <pbun...@redhat.com>
Signed-off-by: David Howells <dhowe...@redhat.com>
cc: Kirill Marinushkin <k.marinush...@gmail.com>
---

 security/keys/big_key.c |  108 +--
 1 file changed, 85 insertions(+), 23 deletions(-)

diff --git a/security/keys/big_key.c b/security/keys/big_key.c
index 929e14978c42..0ffea9601619 100644
--- a/security/keys/big_key.c
+++ b/security/keys/big_key.c
@@ -22,6 +22,13 @@
 #include 
 #include 
 
+struct big_key_buf {
+   int nr_pages;
+   void*virt;
+   struct scatterlist  *sg;
+   struct page *pages[];
+};
+
 /*
  * Layout of key payload words.
  */
@@ -91,10 +98,9 @@ static DEFINE_MUTEX(big_key_aead_lock);
 /*
  * Encrypt/decrypt big_key data
  */
-static int big_key_crypt(enum big_key_op op, u8 *data, size_t datalen, u8 *key)
+static int big_key_crypt(enum big_key_op op, struct big_key_buf *buf, size_t 
datalen, u8 *key)
 {
int ret;
-   struct scatterlist sgio;
struct aead_request *aead_req;
/* We always use a zero nonce. The reason we can get away with this is
 * because we're using a different randomly generated key for every
@@ -109,8 +115,7 @@ static int big_key_crypt(enum big_key_op op, u8 *data, 
size_t datalen, u8 *key)
return -ENOMEM;
 
memset(zero_nonce, 0, sizeof(zero_nonce));
-   sg_init_one(, data, datalen + (op == BIG_KEY_ENC ? 
ENC_AUTHTAG_SIZE : 0));
-   aead_request_set_crypt(aead_req, , , datalen, zero_nonce);
+   aead_request_set_crypt(aead_req, buf->sg, buf->sg, datalen, zero_nonce);
aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, 
NULL);
aead_request_set_ad(aead_req, 0);
 
@@ -130,21 +135,76 @@ static int big_key_crypt(enum big_key_op op, u8 *data, 
size_t datalen, u8 *key)
 }
 
 /*
+ * Free up the buffer.
+ */
+static void big_key_free_buffer(struct big_key_buf *buf)
+{
+   unsigned int i;
+
+   vunmap(buf->virt);
+   for (i = 0; i < buf->nr_pages; i++)
+   __free_page(buf->pages[i]);
+
+   kfree(buf);
+}
+
+/*
+ * Allocate a buffer consisting of a set of pages with a virtual mapping
+ * applied over them.
+ */
+static void *big_key_alloc_buffer(size_t len)
+{
+   struct big_key_buf *buf;
+   unsigned int npg = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
+   unsigned int i, l;
+
+   buf = kzalloc(sizeof(struct big_key_buf) +
+ sizeof(struct page) * npg +
+ sizeof(struct scatterlist) * npg,
+ GFP_KERNEL);
+   if (!buf)
+   return NULL;
+
+   buf->nr_pages = npg;
+   buf->sg = (void *)(buf->pages + npg);
+   sg_init_table(buf->sg, npg);
+
+   for (i = 0; i < buf->nr_pages; i++) {
+   buf->pages[i] = alloc_page(GFP_KERNEL);
+   if (!buf->pages[i])
+   goto nomem;
+
+   l = min(len, PAGE_SIZE);
+   sg_set_page(>sg[i], buf->pages[i], l, 0);
+   len -= l;
+   }
+
+   buf->virt = vmap(buf->pages, buf->nr_pages, VM_MAP, PAGE_KERNEL);
+   if (!buf->virt)
+   goto nomem;
+
+   

Re: [PATCH 8/9] X.509: remove dead code that set ->unsupported_sig

2018-02-08 Thread David Howells
Eric Biggers  wrote:

> The X.509 parser is guaranteed to set cert->sig->pkey_algo and
> cert->sig->hash_algo, since x509_note_pkey_algo() is a mandatory action
> in the X.509 ASN.1 grammar, and it returns an error code if an
> unrecognized AlgorithmIdentifier is given rather than leaving the
> algorithms as NULL.

I'm leaning towards ENOPKG production here being deferred so that X.509 certs
that we can't verify can still be built into the kernel or loaded from
'trusted' sources.

Let me think about this a bit more.

David



Re: [PATCH 6/9] PKCS#7: remove unnecessary check for NULL sinfo->sig->hash_algo

2018-02-08 Thread David Howells
Eric Biggers  wrote:

> The PKCS#7 parser is guaranteed to set ->sig->hash_algo for every
> SignerInfo, since pkcs7_sig_note_digest_algo() is a mandatory action in
> the PKCS#7 ASN.1 grammar, and it returns an error code if an
> unrecognized DigestAlgorithmIdentifier is given rather than leaving the
> algorithm as NULL.  Therefore, remove the unnecessary NULL check.

Actually, we might be better off deferring ENOPKG generation as we might have
multiple signatures, at least one of which does have a digest algorithm that
we can handle.

David


Re: [PATCH 4/9] X.509: fix BUG_ON() when hash algorithm is unsupported

2018-02-08 Thread David Howells
Eric Biggers  wrote:

> The X.509 parser mishandles the case where the certificate's signature's
> hash algorithm is not available in the crypto API.  In this case,
> x509_get_sig_params() doesn't allocate the cert->sig->digest buffer; this
> part seems to be intentional.

Well, yes, that would be intentional: we can't digest the digestibles without
access to a hash algorithm to do so and we can't allocate a digest buffer
without knowing how big it should be.

> Fix this by making public_key_verify_signature() return -ENOPKG if the
> hash buffer has not been allocated.

Hmmm...  I'm not sure that this is the right place to do this, since it
obscures a potential invalid argument within the kernel.

I'm more inclined that the users of X.509 certs should check
x509->unsupported_sig (pkcs7_verify_sig_chain() does this already partially).

David


Re: [PATCH 0/9] PKCS#7 / X.509 fixes and cleanups

2018-02-08 Thread David Howells
I presume you don't have this in a git tree somewhere that I can pull?

David


Re: kernel failure while loading X.509 certificate

2018-01-17 Thread David Howells
If this happened during boot, it could be that you have an X.509 cert for
which the digest algorithm isn't built into the kernel.

David


Re: [PATCH] KEYS: reject NULL restriction string when type is specified

2017-12-08 Thread David Howells
Mat Martineau  wrote:

> Since this fixes the bug for the asymmetric key type and ensures that other
> key types won't make the same mistake, I agree this is the way to fix it. I
> did not find any issues in the patch.

Can I put that down as a Reviewed-by?

David


Re: [PATCH] X.509: fix printing uninitialized stack memory when OID is empty

2017-11-28 Thread David Howells
I wonder if all -EBADMSG returns here should just print "(badoid)" into the
buffer.

David


Re: [PATCH] X.509: fix comparisons of ->pkey_algo

2017-11-28 Thread David Howells
Eric Biggers  wrote:

> if (strcmp(x509->pub->pkey_algo, sinfo->sig->pkey_algo))

Can you make this strcmp(...) != 0?  I know it may seem picky, but checking
strcmp() in this way kind of inverts the true/false thing.

Thanks,
David


Re: [PATCH] crypto: rsa - fix buffer overread when stripping leading zeroes

2017-11-28 Thread David Howells
Eric Biggers <ebigge...@gmail.com> wrote:

> In rsa_get_n(), if the buffer contained all 0's and "FIPS mode" is
> enabled, we would read one byte past the end of the buffer while
> scanning the leading zeroes.  Fix it by checking 'n_sz' before '!*ptr'.

Reviewed-by: David Howells <dhowe...@redhat.com>


Re: [PATCH] crypto: rsa - fix buffer overread when stripping leading zeroes

2017-11-28 Thread David Howells
Hi Herbert,

Are you going to take this?

David


Re: [PATCH v2] lib/mpi: call cond_resched() from mpi_powm() loop

2017-11-08 Thread David Howells
Eric Biggers  wrote:

> This probably should be grouped with my series "crypto: dh - input validation
> fixes", as this is also a fix for Diffie-Hellman.  I was actually expecting
> Herbert Xu to take these patches, as Diffie-Hellman is now part of the crypto
> API (crypto/dh.c); none of the patches actually touch security/keys/.

Fine by me.

> If you'd like to maintain the Diffie-Hellman implementation(s) you should
> get yourself added to MAINTAINERS for the relevant files.

It touches the MPI lib, though, so it also potentially affects RSA and stuff,
which is why I introduced it to the kernel originally.

David


Re: [PATCH v2] lib/mpi: call cond_resched() from mpi_powm() loop

2017-11-08 Thread David Howells
Eric Biggers  wrote:

> On a non-preemptible kernel, if KEYCTL_DH_COMPUTE is called with the
> largest permitted inputs (16384 bits), the kernel spends 10+ seconds
> doing modular exponentiation in mpi_powm() without rescheduling.  If all
> threads do it, it locks up the system.  Moreover, it can cause
> rcu_sched-stall warnings.

Do you want this to go in immediately, or I should I push it to James for the
next merge window?

David


Re: general protection fault in asn1_ber_decoder

2017-11-07 Thread David Howells
Eric Biggers  wrote:

> Hi David, you just beat me to it, but I don't think this is the best way to
> fix the problem.  The length check just needs to be rewritten to not
> overflow.  Also it seems there is another broken length check later in the
> function.  How about this:

Okay, fair enough.  Do you mind if I trim your register dump a bit?

David


Re: general protection fault in asn1_ber_decoder

2017-11-06 Thread David Howells
syzbot <bot+04b92812698232d15d78c1e4d3bbf6fcc21ee...@syzkaller.appspotmail.com> 
wrote:

> syzkaller hit the following crash on 5a3517e009e979f21977d362212b7729c5165d92
> git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/master
> compiler: gcc (GCC) 7.1.1 20170620
> .config is attached
> Raw console output is attached.
> C reproducer is attached
> syzkaller reproducer is attached. See https://goo.gl/kgGztJ
> for information about syzkaller reproducers

Does the attached patch fix it for you?

David
---
commit 41f31a32d918a97dba2ec589d24b52527c8f35b6
Author: David Howells <dhowe...@redhat.com>
Date:   Mon Nov 6 21:44:00 2017 +

asn1: Fix handling of zero-length ASN.1 messages

The ASN.1 parser doesn't correctly handle zero-length ASN.1 data.  There
are at least a couple of ways this can be handled.  The simplest is just to
reject zero-length messages upfront on the basis that we don't currently
have a grammar that permits such; a more complex way is to expand all the
state variables to 32-bit signed so that the:

if (unlikely(dp >= datalen - 1))

check on line 231 correctly detects underflow when datalen is 0.

For the moment, just choose the simplest option and indicate EBADMSG for a
zero-length message, with a comment indicating what needs to be done if the
check is removed

The bug can be reproduced by:

echo -n | keyctl padd pkcs7_test "" @t

The oops resulting from the bug looks like:

BUG: unable to handle kernel NULL pointer dereference at (null)
IP: asn1_ber_decoder+0xe7/0x5fa
...
RIP: 0010:asn1_ber_decoder+0xe7/0x5fa
...
Call Trace:
 ? pkcs7_parse_message+0x11/0x181
 ? rcu_read_lock_sched_held+0x5f/0x67
 ? kmem_cache_alloc_trace+0x275/0x2b1
 ? pkcs7_parse_message+0x9a/0x181
 pkcs7_parse_message+0xd9/0x181
 ? pkcs7_preparse+0x48/0x48
 verify_pkcs7_signature+0x2c/0x107
 pkcs7_preparse+0x44/0x48
 ? pkcs7_preparse+0x48/0x48
 key_create_or_update+0x160/0x3d5
 SyS_add_key+0x123/0x186
 do_syscall_64+0x8a/0x190
 entry_SYSCALL64_slow_path+0x25/0x25
...

with the bug falling on line 233 of asn1_decoder.c:

tag = data[dp++];

Fixes: 42d5ec27f873 ("X.509: Add an ASN.1 decoder")
Reported-by: syzkal...@googlegroups.com
Signed-off-by: David Howells <dhowe...@redhat.com>

diff --git a/lib/asn1_decoder.c b/lib/asn1_decoder.c
index fef5d2e114be..048de2c20ae9 100644
--- a/lib/asn1_decoder.c
+++ b/lib/asn1_decoder.c
@@ -201,6 +201,13 @@ int asn1_ber_decoder(const struct asn1_decoder *decoder,
if (datalen > 65535)
return -EMSGSIZE;
 
+   /* We don't currently support 0-length messages - the underrun checks
+* will fail if datalen is 0 because we check against datalen - 1 with
+* unsigned arithmetic.
+*/
+   if (datalen == 0)
+   return -EBADMSG;
+
 next_op:
pr_debug("next_op: pc=\e[32m%zu\e[m/%zu dp=\e[33m%zu\e[m/%zu C=%d 
J=%d\n",
 pc, machlen, dp, datalen, csp, jsp);


Re: [PATCH 1/3] crypto: dh_helper - return unsigned int for dh_data_size()

2017-10-03 Thread David Howells
Tudor Ambarus  wrote:

> -static inline int dh_data_size(const struct dh *p)
> +static inline unsigned int dh_data_size(const struct dh *p)
>  {
>   return p->key_size + p->p_size + p->g_size;
>  }

If this is a problem, do you need to do range checking?

David


[GIT PULL] KEYS: Fixes and crypto fixes

2017-09-27 Thread David Howells
Hi James,

Can you pull these and pass them on to Linus.  There are two sets of
patches here:

 (1) A bunch of core keyrings bug fixes from Eric Biggers.

 (2) Fixing big_key to use safe crypto from Jason A. Donenfeld.

There are more patches to come from Eric, but I haven't reviewed at them
yet, so I haven't included them here.  Thanks to Eric for reviewing the
keyrings code.

David
---
The following changes since commit ebb2c2437d8008d46796902ff390653822af6cc4:

  Merge tag 'mmc-v4.14-2' of 
git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc (2017-09-18 08:44:51 
-0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git 
tags/keys-fixes-20170927

for you to fetch changes up to 428490e38b2e352812e0b765d8bceafab0ec441d:

  security/keys: rewrite all of big_key crypto (2017-09-25 23:31:58 +0100)


Keyrings fixes


Eric Biggers (10):
  KEYS: fix cred refcount leak in request_key_auth_new()
  KEYS: don't revoke uninstantiated key in request_key_auth_new()
  KEYS: fix key refcount leak in keyctl_assume_authority()
  KEYS: fix key refcount leak in keyctl_read_key()
  KEYS: fix writing past end of user-supplied buffer in keyring_read()
  KEYS: prevent creating a different user's keyrings
  KEYS: prevent KEYCTL_READ on negative key
  KEYS: reset parent each time before searching key_user_tree
  KEYS: restrict /proc/keys by credentials at open time
  KEYS: use kmemdup() in request_key_auth_new()

Jason A. Donenfeld (2):
  security/keys: properly zero out sensitive key material in big_key
  security/keys: rewrite all of big_key crypto

 include/linux/key.h  |   2 +
 security/keys/Kconfig|   4 +-
 security/keys/big_key.c  | 139 ++-
 security/keys/internal.h |   2 +-
 security/keys/key.c  |   6 +-
 security/keys/keyctl.c   |  13 ++--
 security/keys/keyring.c  |  37 ++-
 security/keys/proc.c |   8 +--
 security/keys/process_keys.c |   6 +-
 security/keys/request_key_auth.c |  74 ++---
 10 files changed, 139 insertions(+), 152 deletions(-)


Re: [PATCH v2] X.509: Fix error code in x509_cert_parse()

2017-06-10 Thread David Howells
Herbert Xu  wrote:

> Patch applied.  Thanks.

Note that I've passed this on to James to pass on to Linus along with a bunch
of other patches.

David


Re: [PATCH v3 05/13] security/keys: ensure RNG is seeded before use

2017-06-06 Thread David Howells
Jason A. Donenfeld  wrote:

> + key->serial = get_random_u32() >> 1;

If this may sleep, it must be interruptible.

David


Re: [PATCH v2 10/11] crypto: KEYS: check err on akcipher maxsize

2017-05-24 Thread David Howells
Tudor Ambarus <tudor.amba...@microchip.com> wrote:

> crypto_akcipher_maxsize() returns minimum length for output buffer
> or error code if key hasn't been set.
> 
> Signed-off-by: Tudor Ambarus <tudor.amba...@microchip.com>

Reviewed-by: David Howells <dhowe...@redhat.com>


Re: [PATCH] X.509: Fix error code in x509_cert_parse()

2017-05-23 Thread David Howells
Dan Carpenter  wrote:

>   cert->pub->key = kmemdup(ctx->key, ctx->key_size, GFP_KERNEL);
> - if (!cert->pub->key)
> + if (!cert->pub->key) {
> + ret = -ENOMEM;
>   goto error_decode;
> + }

Put the "ret = -ENOMEM" line before the kmemdup line maybe?

David


Re: [PATCH 0/5] KEYS: fixes for new keyctl_dh_compute() KDF extension

2017-04-28 Thread David Howells
Stephan,

Eric Biggers  wrote:

> This patch series fixes several bugs in the KDF extension to
> keyctl_dh_compute() currently sitting in keys-next: a way userspace could
> cause an infinite loop, two ways userspace could cause the use of
> uninitialized memory, a misalignment, and missing __user annotations.

Do you want to ack these or do they need fixing?

David


Re: [PATCH 3/5] KEYS: DH: don't feed uninitialized result memory into KDF

2017-04-27 Thread David Howells
Eric Biggers  wrote:

> > > By the way: do we really need this in the kernel at all, given that it's
> > > just doing some math on data which userspace has access to?
> > 
> > It is the question about how we want the keys subsystem to operate. The DH
> > shared secret shall not be used as a key. But the DH operation is part of
> > the key subsystem. If there is never a case where the result of the DH
> > operation is used in the kernel, then the KDF can be removed and my
> > patches could be reverted. However, in this case, the entire DH business
> > could be questioned as this can easily be done in user space as well.
> > 
> 
> Well, who exactly is asking for Diffie-Hellman in the kernel at all?  If it
> can be done in userspace then it should be done there.  Having it in the
> kernel means having yet another API that's callable by unprivileged users
> and needs to be audited for security vulnerabilities.  Just because the
> kernel can support doing hashes or has an arbitrary-precision arithmetic
> library or whatever doesn't mean it's the right place to do random crypto
> stuff.

I understood that there is the possibility of offloading this to hardware.

David


Re: [PATCH 5/6] MODSIGN: Export module signature definitions.

2017-04-20 Thread David Howells
Mimi Zohar  wrote:

> On Tue, 2017-04-18 at 17:17 -0300, Thiago Jung Bauermann wrote:
> > IMA will use the module_signature format for append signatures, so export
> > the relevant definitions and factor out the code which verifies that the
> > appended signature trailer is valid.
> > 
> > Also, create a CONFIG_MODULE_SIG_FORMAT option so that IMA can select it
> > and be able to use validate_module_signature without having to depend on
> > CONFIG_MODULE_SIG.
> 
> Basically we want to generalize the concept of an appended signature.
>  Referring to it as a "module signature format" seems a bit confusing.
> 
> David, would you have a problem with changing the appended string from
> "~Module signature appended~\n" to something more generic?

Conceptually, no.  Is it possible that doing so could break someone's module
that they load on multiple versions of the kernel?  Say a module that only
exports things and doesn't use anything from the core or any other module.

Also, it needs to reasonably long and distinct enough to prevent a false
positive match.

David


Re: [PATCH v6] DH support: add KDF handling support

2017-04-04 Thread David Howells
Pulled.


Re: [PATCH v5] KEYS: add SP800-56A KDF support for DH

2017-04-03 Thread David Howells
Pulled.


Re: [PATCH v5] DH support: add KDF handling support

2017-04-03 Thread David Howells
Stephan Mueller  wrote:

> this patch changes the documentation, the naming of the variables
> and the test case to refer to the variable name of a hashname
> instead of kdfname to match the current kernel implementation.

It's also needs an update to man1/keyctl.1.

David


Re: [PATCH v5] DH support: add KDF handling support

2017-04-03 Thread David Howells
Stephan Mueller  wrote:

> + struct keyctl_dh_params params = { .private = private,

That doesn't compile.  I think you meant ".priv".

David


Re: [PATCH -next] crypto: asymmetric_keys - Fix error return code on failure

2017-02-09 Thread David Howells
Wei Yongjun  wrote:

> --- a/crypto/asymmetric_keys/public_key.c
> +++ b/crypto/asymmetric_keys/public_key.c
> @@ -184,8 +184,10 @@ static int software_key_eds_op(struct kernel_pkey_params 
> *params,
>   return PTR_ERR(tfm);
>  
>   req = akcipher_request_alloc(tfm, GFP_KERNEL);
> - if (!req)
> + if (!req) {
> + ret = -ENOMEM;

Ummm...  What should I apply your patch to?

>   goto error_free_tfm;
> + }
>  
>   if (pkey->key_is_private)
>   ret = crypto_akcipher_set_priv_key(tfm,
> @@ -268,8 +270,10 @@ int public_key_verify_signature(const struct public_key 
> *pkey,
>   return PTR_ERR(tfm);
>  
>   req = akcipher_request_alloc(tfm, GFP_KERNEL);
> - if (!req)
> + if (!req) {
> + ret = -ENOMEM;
>   goto error_free_tfm;

This shouldn't be necessary.  ret should already be -ENOMEM from
initialisation of the variable at the top of the function.

David


Re: [PATCH v2] keys/encrypted: Fix two crypto-on-the-stack bugs

2016-12-14 Thread David Howells
Andy Lutomirski  wrote:

> David, are these encrypted keys ever exported anywhere?  If not, could
> the code use a mode that doesn't need padding?

ecryptfs uses them, I think.

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] keys/encrypted: Fix two crypto-on-the-stack bugs

2016-12-14 Thread David Howells
Andy Lutomirski  wrote:

> > -   sg_set_buf(_out[1], pad, sizeof pad);
> > +   sg_set_buf(_out[1], empty_zero_page, 16);
> 
> My fix here is obviously bogus (I meant to use ZERO_PAGE(0)), but what
> exactly is the code trying to do?  The old code makes no sense.  It's
> setting the *output* buffer to zeroed padding.

Padding goes into the encrypt function and is going to come out of the decrypt
function.  Possibly derived_key_decrypt() should be checking that the padding
that comes out is actually a bunch of zeros.  Maybe we don't actually need to
get the padding out, but I'm not sure whether the crypto layer will
malfunction if we don't give it a buffer for the padding.

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] keys/encrypted: Fix two crypto-on-the-stack bugs

2016-12-13 Thread David Howells
Andy Lutomirski  wrote:

> I don't know whether you're right, but that sounds a bit silly to me.
> This is a *tiny* amount of memory.

Assuming a 1MiB kernel image in 4K pages, that gets you back a couple of pages
I think - useful if you've only got a few MiB of RAM.

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] keys/encrypted: Fix two crypto-on-the-stack bugs

2016-12-13 Thread David Howells
Andy Lutomirski  wrote:

> After all, rodata is ordinary memory, is backed by struct page, etc.

Is that actually true?  I thought some arches excluded the kernel image from
the page struct array to make the array consume less memory.

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] sign-file: Fix inplace signing when src and dst names are both specified

2016-12-13 Thread David Howells
From: Alex Yashchenko <alexhoppus...@gmail.com>

When src and dst both are specified and they point to the same file
the sign-file utility will write only signature to the dst file and
the module (.ko file) body will not be written.
That happens because we open the same file with "rb" and "wb" flags,
from fopen man:

 w  Truncate file to zero length or create text file for writing.
The stream is positioned at the beginning of the file.
...
bm = BIO_new_file(module_name, "rb");
...
bd = BIO_new_file(dest_name, "wb");
...
while ((n = BIO_read(bm, buf, sizeof(buf))),
   n > 0) {
ERR(BIO_write(bd, buf, n) < 0, "%s", dest_name);
}
...

Signed-off-by: Alex Yashchenko <alexhoppus...@gmail.com>
Signed-off-by: David Howells <dhowe...@redhat.com>
---

 scripts/sign-file.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/sign-file.c b/scripts/sign-file.c
index 53af6dc3e6c1..19ec468b1168 100755
--- a/scripts/sign-file.c
+++ b/scripts/sign-file.c
@@ -267,7 +267,7 @@ int main(int argc, char **argv)
}
x509_name = argv[2];
module_name = argv[3];
-   if (argc == 5) {
+   if (argc == 5 && strcmp(argv[3], argv[4]) != 0) {
dest_name = argv[4];
replace_orig = false;
} else {

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] crypto: asymmetric_keys: set error code on failure

2016-12-13 Thread David Howells
From: Pan Bian <bianpan2...@163.com>

In function public_key_verify_signature(), returns variable ret on
error paths. When the call to kmalloc() fails, the value of ret is 0,
and it is not set to an errno before returning. This patch fixes the
bug.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=188891

Signed-off-by: Pan Bian <bianpan2...@163.com>
Signed-off-by: David Howells <dhowe...@redhat.com>
---

 crypto/asymmetric_keys/public_key.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index fd76b5fc3b3a..d3a989e718f5 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -121,6 +121,7 @@ int public_key_verify_signature(const struct public_key 
*pkey,
if (ret)
goto error_free_req;
 
+   ret = -ENOMEM;
outlen = crypto_akcipher_maxsize(tfm);
output = kmalloc(outlen, GFP_KERNEL);
if (!output)

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] keys/encrypted: Fix two crypto-on-the-stack bugs

2016-12-12 Thread David Howells
Andy Lutomirski  wrote:

> +static const char zero_pad[16] = {0};

Isn't there a global page of zeros or something that we can share?  Also, you
shouldn't explicitly initialise it so that it stays in .bss.

> - sg_set_buf(_out[1], pad, sizeof pad);
> + sg_set_buf(_out[1], zero_pad, sizeof zero_pad);

Can you put brackets on the sizeof?

Thanks,
David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/1] crypto: asymmetric_keys: set error code on failure

2016-12-12 Thread David Howells
Pan Bian  wrote:

>   outlen = crypto_akcipher_maxsize(tfm);
>   output = kmalloc(outlen, GFP_KERNEL);
> - if (!output)
> + if (!output) {
> + ret = -ENOMEM;
>   goto error_free_req;
> + }

This is preferred:

+   ret = -ENOMEM;
outlen = crypto_akcipher_maxsize(tfm);
output = kmalloc(outlen, GFP_KERNEL);
if (!output)
goto error_free_req;

I'll alter your patch.

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/2] KEYS: Fixes [ver #3]

2016-11-24 Thread David Howells

Hi James,

Can you pull these patches please and pass them on to Linus?  They include
the following:

 (1) Fix mpi_powm()'s handling of a number with a zero exponent [CVE-2016-8650].

 (2) Fix double free in X.509 error handling.

Ver #3:

 - Integrate my and Andrey's patches for mpi_powm() and use mpi_resize()
   instead of RESIZE_IF_NEEDED() - the latter adds a duplicate check into
   the execution path of a trivial case we don't normally expect to be
   taken.

Ver #2:

 - Use RESIZE_IF_NEEDED() to conditionally resize the result rather than
   manually doing this.

The patches can be found here also:


http://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=keys-fixes

Tagged thusly:

git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git
keys-fixes-20161124-3

David
---
Andrey Ryabinin (2):
  X.509: Fix double free in x509_cert_parse()
  mpi: Fix NULL ptr dereference in mpi_powm()


 crypto/asymmetric_keys/x509_cert_parser.c |1 -
 lib/mpi/mpi-pow.c |7 ++-
 2 files changed, 6 insertions(+), 2 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] mpi: Fix NULL ptr dereference in mpi_powm() [ver #3]

2016-11-24 Thread David Howells
From: Andrey Ryabinin <aryabi...@virtuozzo.com>

This fixes CVE-2016-8650.

If mpi_powm() is given a zero exponent, it wants to immediately return
either 1 or 0, depending on the modulus.  However, if the result was
initalised with zero limb space, no limbs space is allocated and a
NULL-pointer exception ensues.

Fix this by allocating a minimal amount of limb space for the result when
the 0-exponent case when the result is 1 and not touching the limb space
when the result is 0.

This affects the use of RSA keys and X.509 certificates that carry them.

BUG: unable to handle kernel NULL pointer dereference at   (null)
IP: [] mpi_powm+0x32/0x7e6
PGD 0
Oops: 0002 [#1] SMP
Modules linked in:
CPU: 3 PID: 3014 Comm: keyctl Not tainted 4.9.0-rc6-fscache+ #278
Hardware name: ASUS All Series/H97-PLUS, BIOS 2306 10/09/2014
task: 8804011944c0 task.stack: 880401294000
RIP: 0010:[]  [] mpi_powm+0x32/0x7e6
RSP: 0018:880401297ad8  EFLAGS: 00010212
RAX:  RBX: 88040868bec0 RCX: 88040868bba0
RDX: 88040868b260 RSI: 88040868bec0 RDI: 88040868bee0
RBP: 880401297ba8 R08:  R09: 
R10: 0047 R11: 8183b210 R12: 
R13: 8804087c7600 R14: 001f R15: 880401297c50
FS:  7f7a7918c700() GS:88041fb8() knlGS:
CS:  0010 DS:  ES:  CR0: 80050033
CR2:  CR3: 00040125 CR4: 001406e0
Stack:
 88040868bec0 0020 880401297b00 81376cd4
 0100 880401297b10 81376d12 880401297b30
 81376f37 0100  880401297ba8
Call Trace:
 [] ? __sg_page_iter_next+0x43/0x66
 [] ? sg_miter_get_next_page+0x1b/0x5d
 [] ? sg_miter_next+0x17/0xbd
 [] ? mpi_read_raw_from_sgl+0xf2/0x146
 [] rsa_verify+0x9d/0xee
 [] ? pkcs1pad_sg_set_buf+0x2e/0xbb
 [] pkcs1pad_verify+0xc0/0xe1
 [] public_key_verify_signature+0x1b0/0x228
 [] x509_check_for_self_signed+0xa1/0xc4
 [] x509_cert_parse+0x167/0x1a1
 [] x509_key_preparse+0x21/0x1a1
 [] asymmetric_key_preparse+0x34/0x61
 [] key_create_or_update+0x145/0x399
 [] SyS_add_key+0x154/0x19e
 [] do_syscall_64+0x80/0x191
 [] entry_SYSCALL64_slow_path+0x25/0x25
Code: 56 41 55 41 54 53 48 81 ec a8 00 00 00 44 8b 71 04 8b 42 04 4c 8b 67 18 
45 85 f6 89 45 80 0f 84 b4 06 00 00 85 c0 75 2f 41 ff ce <49> c7 04 24 01 00 00 
00 b0 01 75 0b 48 8b 41 18 48 83 38 01 0f
RIP  [] mpi_powm+0x32/0x7e6
 RSP 
CR2: 
---[ end trace d82015255d4a5d8d ]---

Basically, this is a backport of a libgcrypt patch:


http://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=patch;h=6e1adb05d290aeeb1c230c763970695f4a538526

Fixes: cdec9cb5167a ("crypto: GnuPG based MPI lib - source files (part 1)")
Signed-off-by: Andrey Ryabinin <aryabi...@virtuozzo.com>
Signed-off-by: David Howells <dhowe...@redhat.com>
cc: Dmitry Kasatkin <dmitry.kasat...@gmail.com>
cc: linux-ima-de...@lists.sourceforge.net
cc: sta...@vger.kernel.org
---

 lib/mpi/mpi-pow.c |7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/lib/mpi/mpi-pow.c b/lib/mpi/mpi-pow.c
index 5464c8744ea9..e24388a863a7 100644
--- a/lib/mpi/mpi-pow.c
+++ b/lib/mpi/mpi-pow.c
@@ -64,8 +64,13 @@ int mpi_powm(MPI res, MPI base, MPI exp, MPI mod)
if (!esize) {
/* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0
 * depending on if MOD equals 1.  */
-   rp[0] = 1;
res->nlimbs = (msize == 1 && mod->d[0] == 1) ? 0 : 1;
+   if (res->nlimbs) {
+   if (mpi_resize(res, 1) < 0)
+   goto enomem;
+   rp = res->d;
+   rp[0] = 1;
+   }
res->sign = 0;
goto leave;
}

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] X.509: Fix double free in x509_cert_parse() [ver #3]

2016-11-24 Thread David Howells
From: Andrey Ryabinin <aryabi...@virtuozzo.com>

We shouldn't free cert->pub->key in x509_cert_parse() because
x509_free_certificate() also does this:
BUG: Double free or freeing an invalid pointer
...
Call Trace:
 [] dump_stack+0x63/0x83
 [] kasan_object_err+0x21/0x70
 [] kasan_report_double_free+0x49/0x60
 [] kasan_slab_free+0x9d/0xc0
 [] kfree+0x8a/0x1a0
 [] public_key_free+0x1f/0x30
 [] x509_free_certificate+0x24/0x90
 [] x509_cert_parse+0x2bc/0x300
 [] x509_key_preparse+0x3e/0x330
 [] asymmetric_key_preparse+0x6f/0x100
 [] key_create_or_update+0x260/0x5f0
 [] SyS_add_key+0x199/0x2a0
 [] entry_SYSCALL_64_fastpath+0x1e/0xad
Object at 880110bd1900, in cache kmalloc-512 size: 512

Freed:
PID = 2579
[] save_stack_trace+0x1b/0x20
[] save_stack+0x46/0xd0
[] kasan_slab_free+0x73/0xc0
[] kfree+0x8a/0x1a0
[] x509_cert_parse+0x2a3/0x300
[] x509_key_preparse+0x3e/0x330
[] asymmetric_key_preparse+0x6f/0x100
[] key_create_or_update+0x260/0x5f0
[] SyS_add_key+0x199/0x2a0
[] entry_SYSCALL_64_fastpath+0x1e/0xad

Fixes: db6c43bd2132 ("crypto: KEYS: convert public key and digsig asym to the 
akcipher api")
Signed-off-by: Andrey Ryabinin <aryabi...@virtuozzo.com>
Cc: <sta...@vger.kernel.org>
Signed-off-by: David Howells <dhowe...@redhat.com>
---

 crypto/asymmetric_keys/x509_cert_parser.c |1 -
 1 file changed, 1 deletion(-)

diff --git a/crypto/asymmetric_keys/x509_cert_parser.c 
b/crypto/asymmetric_keys/x509_cert_parser.c
index 865f46ea724f..c80765b211cf 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -133,7 +133,6 @@ struct x509_certificate *x509_cert_parse(const void *data, 
size_t datalen)
return cert;
 
 error_decode:
-   kfree(cert->pub->key);
kfree(ctx);
 error_no_ctx:
x509_free_certificate(cert);

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


How best to {en,de}crypt between sk_buff and iov_iter?

2016-08-10 Thread David Howells
Is there a good way to encrypt data held in an iov_iter directly into an
sk_buff and decrypt data held in an sk_buff back into an iov_iter?

What I would like to avoid is:

 (a) Invoking skb_cow_data() to potentially take an unnecessary copy of the
 data I shouldn't need to change, but I need to do this to decrypt in
 place.

 (b) Having to copy the unencrypted data between the sk_buff and the iov_iter
 when the crypto process ought to get me a free copy.

One problem, though, is that I might not be able to do drain/fill a complete
sk_buff in a single operation because the iov_iter might not give me sufficient
bufferage/data to do that, so it may take multiple operations.  However, since
I'm using an skcipher, I think it should be fine to call
crypto_skcipher_encrypt() multiple times on the same skcipher.

I can see a couple of alternatives:

 (1) Duplicate skb_copy_datagram_iter(), give it an initialised
 skcipher_request and let it set the crypto parameters for each block it
 transfers.  copy_to_iter() would then need to be replaced with something
 that sets up an sglist each time from the iov.

 Something similar would need doing for skb_copy_datagram_from_iter().

 (2) Create an sglist for the skb and one for the iov_iter and encrypt/decrypt
 between them.  Unfortunately, if the iov_iter is a userspace reference
 then this would mean pinning userspace pages.

 (3) Add an {en,de}crypt-to-iov_iter capability to the crypto layer.  I'm not
 sure how well this would work for hardware support, though.  I think we'd
 come back to pinning userspace pages.

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] DH support: add KDF handling support

2016-07-27 Thread David Howells
Mat Martineau  wrote:

> > Though, shall I stuff the wrapper code back into the existing dh_compute
> > functions or can I leave them as separate functions?
> 
> I'm not sure. In the existing code there's one keyctl wrapper per keyctl
> command. A combined wrapper would need some extra logic to decide whether
> kdfparams is passed in or not, which is different from existing code.

You shouldn't change the existing keyctl wrappers.  Feel free to add another
one with extra arguments.

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] KEYS: Fix for erroneous trust of incorrectly signed X.509 certs

2016-07-17 Thread David Howells
From: Mat Martineau <mathew.j.martin...@linux.intel.com>

Arbitrary X.509 certificates without authority key identifiers (AKIs)
can be added to "trusted" keyrings, including IMA or EVM certs loaded
from the filesystem. Signature verification is currently bypassed for
certs without AKIs.

Trusted keys were recently refactored, and this bug is not present in
4.6.

restrict_link_by_signature should return -ENOKEY (no matching parent
certificate found) if the certificate being evaluated has no AKIs,
instead of bypassing signature checks and returning 0 (new certificate
accepted).

Reported-by: Petko Manolov <pet...@mip-labs.com>
Signed-off-by: Mat Martineau <mathew.j.martin...@linux.intel.com>
Signed-off-by: David Howells <dhowe...@redhat.com>
---

 crypto/asymmetric_keys/restrict.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/crypto/asymmetric_keys/restrict.c 
b/crypto/asymmetric_keys/restrict.c
index ac4bddf669de..19d1afb9890f 100644
--- a/crypto/asymmetric_keys/restrict.c
+++ b/crypto/asymmetric_keys/restrict.c
@@ -87,7 +87,7 @@ int restrict_link_by_signature(struct key *trust_keyring,
 
sig = payload->data[asym_auth];
if (!sig->auth_ids[0] && !sig->auth_ids[1])
-   return 0;
+   return -ENOKEY;
 
if (ca_keyid && !asymmetric_key_id_partial(sig->auth_ids[1], ca_keyid))
return -EPERM;

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/3] PKCS#7: Fix panic when referring to the empty AKID when DEBUG defined

2016-07-17 Thread David Howells
From: Lans Zhang <jia.zh...@windriver.com>

This fix resolves the following kernel panic if an empty or missing
AuthorityKeyIdentifier is encountered and DEBUG is defined in
pkcs7_verify.c.

[  459.041989] PKEY: <==public_key_verify_signature() = 0
[  459.041993] PKCS7: Verified signature 1
[  459.041995] PKCS7: ==> pkcs7_verify_sig_chain()
[  459.041999] PKCS7: verify Sample DB Certificate for SCP: 01
[  459.042002] PKCS7: - issuer Sample KEK Certificate for SCP
[  459.042014] BUG: unable to handle kernel NULL pointer dereference at 
  (null)
[  459.042135] IP: [] pkcs7_verify+0x72c/0x7f0
[  459.042217] PGD 739e6067 PUD 77719067 PMD 0
[  459.042286] Oops:  [#1] PREEMPT SMP
[  459.042328] Modules linked in:
[  459.042368] CPU: 0 PID: 474 Comm: kexec Not tainted 
4.7.0-rc7-WR8.0.0.0_standard+ #18
[  459.042462] Hardware name: To be filled by O.E.M. To be filled by 
O.E.M./Aptio CRB, BIOS 5.6.5 10/09/2014
[  459.042586] task: 880073a5 ti: 8800738e8000 task.ti: 
8800738e8000
[  459.042675] RIP: 0010:[]  [] 
pkcs7_verify+0x72c/0x7f0
[  459.042784] RSP: 0018:8800738ebd58  EFLAGS: 00010246
[  459.042845] RAX:  RBX: 880076b7da80 RCX: 0006
[  459.042929] RDX: 0001 RSI: 81c85001 RDI: 81ca00a9
[  459.043014] RBP: 8800738ebd98 R08: 0400 R09: 8800788a304c
[  459.043098] R10:  R11: 60ca R12: 8800769a2bc0
[  459.043182] R13: 880077358300 R14:  R15: 8800769a2dc0
[  459.043268] FS:  7f24cc741700() GS:880074e0() 
knlGS:
[  459.043365] CS:  0010 DS:  ES:  CR0: 80050033
[  459.043431] CR2:  CR3: 73a36000 CR4: 001006f0
[  459.043514] Stack:
[  459.043530]   ffbf0020 31ff813e68b0 
0002
[  459.043644]  8800769a2bc0  007197b8 
0002
[  459.043756]  8800738ebdd8 81153fb1  

[  459.043869] Call Trace:
[  459.043898]  [] verify_pkcs7_signature+0x61/0x140
[  459.043974]  [] verify_pefile_signature+0x2cb/0x830
[  459.044052]  [] ? verify_pefile_signature+0x830/0x830
[  459.044134]  [] bzImage64_verify_sig+0x15/0x20
[  459.046332]  [] arch_kexec_kernel_verify_sig+0x29/0x40
[  459.048552]  [] SyS_kexec_file_load+0x1f4/0x6c0
[  459.050768]  [] ? __do_page_fault+0x1b6/0x550
[  459.052996]  [] entry_SYSCALL_64_fastpath+0x17/0x93
[  459.055242] Code: e8 0a d6 ff ff 85 c0 0f 88 7a fb ff ff 4d 39 fd 4d 89 7d 
08 74 45 4d 89 fd e9 14 fe ff ff 4d 8b 76 08 31 c0 48 c7 c7 a9 00 ca 81 <41> 0f 
b7 36 49 8d 56 02 e8 d0 91 d6 ff 4d 8b 3c 24 4d 85 ff 0f
[  459.060535] RIP  [] pkcs7_verify+0x72c/0x7f0
[  459.063040]  RSP 
[  459.065456] CR2: 
[  459.075998] ---[ end trace c15f0e897cda28dc ]---

Signed-off-by: Lans Zhang <jia.zh...@windriver.com>
Signed-off-by: David Howells <dhowe...@redhat.com>
Cc: Dave Young <dyo...@redhat.com>
Cc: Baoquan He <b...@redhat.com>
Cc: Vivek Goyal <vgo...@redhat.com>
cc: linux-crypto@vger.kernel.org
cc: ke...@lists.infradead.org
---

 crypto/asymmetric_keys/pkcs7_verify.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/crypto/asymmetric_keys/pkcs7_verify.c 
b/crypto/asymmetric_keys/pkcs7_verify.c
index 44b746e9df1b..2ffd69769466 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -227,7 +227,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message 
*pkcs7,
if (asymmetric_key_id_same(p->id, auth))
goto found_issuer_check_skid;
}
-   } else {
+   } else if (sig->auth_ids[1]) {
auth = sig->auth_ids[1];
pr_debug("- want %*phN\n", auth->len, auth->data);
for (p = pkcs7->certs; p; p = p->next) {

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] pefile: Fix the failure of calculation for digest

2016-07-17 Thread David Howells
From: Lans Zhang <jia.zh...@windriver.com>

Commit e68503bd68 forgot to set digest_len and thus cause the following
error reported by kexec when launching a crash kernel:

kexec_file_load failed: Bad message

Fixes: e68503bd68 (KEYS: Generalise system_verify_data() to provide access to 
internal content)
Signed-off-by: Lans Zhang <jia.zh...@windriver.com>
Tested-by: Dave Young <dyo...@redhat.com>
Signed-off-by: David Howells <dhowe...@redhat.com>
Cc: Baoquan He <b...@redhat.com>
Cc: Vivek Goyal <vgo...@redhat.com>
cc: ke...@lists.infradead.org
cc: linux-crypto@vger.kernel.org
---

 crypto/asymmetric_keys/mscode_parser.c |7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/crypto/asymmetric_keys/mscode_parser.c 
b/crypto/asymmetric_keys/mscode_parser.c
index 6a76d5c70ef6..9492e1c22d38 100644
--- a/crypto/asymmetric_keys/mscode_parser.c
+++ b/crypto/asymmetric_keys/mscode_parser.c
@@ -124,5 +124,10 @@ int mscode_note_digest(void *context, size_t hdrlen,
struct pefile_context *ctx = context;
 
ctx->digest = kmemdup(value, vlen, GFP_KERNEL);
-   return ctx->digest ? 0 : -ENOMEM;
+   if (!ctx->digest)
+   return -ENOMEM;
+
+   ctx->digest_len = vlen;
+
+   return 0;
 }

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/3] KEYS: Miscellaneous fixes

2016-07-17 Thread David Howells

Hi James,

Here are three miscellaneous fixes:

 (1) Fix a panic in some debugging code in PKCS#7.  This can only happen by
 explicitly inserting a #define DEBUG into the code.

 (2) Fix the calculation of the digest length in the PE file parser.  This
 causes a failure where there should be a success.

 (3) Fix the case where an X.509 cert can be added as an asymmetric key to
 a trusted keyring with no trust restriction if no AKID is supplied.

Bugs (1) and (2) aren't particularly problematic, but (3) allows a security
check to be bypassed.  Bug (3) is added since the 4.6 kernel.

The patches can be found here also:


http://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=keys-fixes

at tag:

keys-fixes-20160718

David
---
Lans Zhang (2):
  PKCS#7: Fix panic when referring to the empty AKID when DEBUG defined
  pefile: Fix the failure of calculation for digest

Mat Martineau (1):
  KEYS: Fix for erroneous trust of incorrectly signed X.509 certs


 crypto/asymmetric_keys/mscode_parser.c |7 ++-
 crypto/asymmetric_keys/pkcs7_verify.c  |2 +-
 crypto/asymmetric_keys/restrict.c  |2 +-
 3 files changed, 8 insertions(+), 3 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [V2][PATCH 1/2] PKCS#7: Fix kernel panic when referring to the empty AuthorityKeyIdentifier

2016-07-17 Thread David Howells
Lans Zhang  wrote:

> Let me know if I need to add this comment to commit header.

I've done that.

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [V2][PATCH 1/2] PKCS#7: Fix kernel panic when referring to the empty AuthorityKeyIdentifier

2016-07-15 Thread David Howells
Lans Zhang  wrote:

> This fix resolves the following kernel panic if the empty
> AuthorityKeyIdentifier employed.

It should be noted that this is only an issue if DEBUG is #defined at the top
of pkcs7_verify.c as the crash happens in a pr_debug() statement.

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 5/8] KEYS: Provide software public key query function [ver #2]

2016-06-27 Thread David Howells
Herbert Xu  wrote:

> > The problem is that if I'm to produce consistency with, say, the TPM
> > interface, then I have to deal in wrapped/padded data - leastways as far
> > as I can tell from reading the docs.
> 
> So the TPM device is accessed through the same interface? Where is
> the code for it?

I have some patches I need to finish revamping.  I had it kind of working
(though with a slightly different user interface) - then TPMv2 support was
added to the TPM driver before I finished and I need to redo the patches.

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 5/8] KEYS: Provide software public key query function [ver #2]

2016-06-24 Thread David Howells
Herbert Xu  wrote:

> IOW exporting the raw RSA might make sense because the key may
> not be visible to user-space, or that the RSA might be implemented
> in hardware offload, but there is no sane reason to export pkcs1pad.

The problem is that if I'm to produce consistency with, say, the TPM
interface, then I have to deal in wrapped/padded data - leastways as far as I
can tell from reading the docs.

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 5/8] KEYS: Provide software public key query function [ver #2]

2016-06-23 Thread David Howells
Provide a query function for the software public key implementation.  This
permits information about such a key to be obtained using
query_asymmetric_key() or KEYCTL_PKEY_QUERY.

Signed-off-by: David Howells <dhowe...@redhat.com>
---

 crypto/asymmetric_keys/public_key.c |   96 ++-
 1 file changed, 82 insertions(+), 14 deletions(-)

diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index fd76b5fc3b3a..a48a47a1dff0 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -57,6 +57,81 @@ static void public_key_destroy(void *payload0, void 
*payload3)
public_key_signature_free(payload3);
 }
 
+/*
+ * Determine the crypto algorithm name.
+ */
+static
+int software_key_determine_akcipher(const char *encoding,
+   const char *hash_algo,
+   const struct public_key *pkey,
+   char alg_name[CRYPTO_MAX_ALG_NAME])
+{
+   int n;
+
+   if (strcmp(encoding, "pkcs1") == 0) {
+   /* The data wangled by the RSA algorithm is typically padded
+* and encoded in some manner, such as EMSA-PKCS1-1_5 [RFC3447
+* sec 8.2].
+*/
+   if (!hash_algo)
+   n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
+"pkcs1pad(%s)",
+pkey->pkey_algo);
+   else
+   n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
+"pkcs1pad(%s,%s)",
+pkey->pkey_algo, hash_algo);
+   return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0;
+   }
+
+   if (strcmp(encoding, "raw") == 0) {
+   strcpy(alg_name, pkey->pkey_algo);
+   return 0;
+   }
+
+   return -ENOPKG;
+}
+
+/*
+ * Query information about a key.
+ */
+static int software_key_query(const struct kernel_pkey_params *params,
+ struct kernel_pkey_query *info)
+{
+   struct crypto_akcipher *tfm;
+   struct public_key *pkey = params->key->payload.data[asym_crypto];
+   char alg_name[CRYPTO_MAX_ALG_NAME];
+   int ret, len;
+
+   ret = software_key_determine_akcipher(params->encoding,
+ params->hash_algo,
+ pkey, alg_name);
+   if (ret < 0)
+   return ret;
+
+   tfm = crypto_alloc_akcipher(alg_name, 0, 0);
+   if (IS_ERR(tfm))
+   return PTR_ERR(tfm);
+
+   ret = crypto_akcipher_set_pub_key(tfm, pkey->key, pkey->keylen);
+   if (ret < 0)
+   goto error_free_tfm;
+
+   len = crypto_akcipher_maxsize(tfm);
+   info->key_size = len * 8;
+   info->max_data_size = len;
+   info->max_sig_size = len;
+   info->max_enc_size = len;
+   info->max_dec_size = len;
+   info->supported_ops = KEYCTL_SUPPORTS_VERIFY;
+   ret = 0;
+
+error_free_tfm:
+   crypto_free_akcipher(tfm);
+   pr_devel("<==%s() = %d\n", __func__, ret);
+   return ret;
+}
+
 struct public_key_completion {
struct completion completion;
int err;
@@ -83,8 +158,7 @@ int public_key_verify_signature(const struct public_key 
*pkey,
struct crypto_akcipher *tfm;
struct akcipher_request *req;
struct scatterlist sig_sg, digest_sg;
-   const char *alg_name;
-   char alg_name_buf[CRYPTO_MAX_ALG_NAME];
+   char alg_name[CRYPTO_MAX_ALG_NAME];
void *output;
unsigned int outlen;
int ret = -ENOMEM;
@@ -96,18 +170,11 @@ int public_key_verify_signature(const struct public_key 
*pkey,
BUG_ON(!sig->digest);
BUG_ON(!sig->s);
 
-   alg_name = sig->pkey_algo;
-   if (strcmp(sig->pkey_algo, "rsa") == 0) {
-   /* The data wangled by the RSA algorithm is typically padded
-* and encoded in some manner, such as EMSA-PKCS1-1_5 [RFC3447
-* sec 8.2].
-*/
-   if (snprintf(alg_name_buf, CRYPTO_MAX_ALG_NAME,
-"pkcs1pad(rsa,%s)", sig->hash_algo
-) >= CRYPTO_MAX_ALG_NAME)
-   return -EINVAL;
-   alg_name = alg_name_buf;
-   }
+   ret = software_key_determine_akcipher(sig->encoding,
+ sig->hash_algo,
+ pkey, alg_name);
+   if (ret < 0)
+   return ret;
 
tfm = crypto_alloc_akcipher(alg_name, 0, 0);
if (IS_ERR(tfm))
@@ -179,6 +246,7 @@ struct asymmetric_key_subtype public_key_subtype = {
.name_len  

[PATCH 4/8] KEYS: Make the X.509 and PKCS7 parsers supply the sig encoding type [ver #2]

2016-06-23 Thread David Howells
Make the X.509 and PKCS7 parsers fill in the signature encoding type field
recently added to the public_key_signature struct.

Signed-off-by: David Howells <dhowe...@redhat.com>
---

 crypto/asymmetric_keys/pkcs7_parser.c |1 +
 crypto/asymmetric_keys/x509_cert_parser.c |   21 +
 2 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/crypto/asymmetric_keys/pkcs7_parser.c 
b/crypto/asymmetric_keys/pkcs7_parser.c
index af4cd8649117..5f0c6755a55b 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.c
+++ b/crypto/asymmetric_keys/pkcs7_parser.c
@@ -261,6 +261,7 @@ int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen,
switch (ctx->last_oid) {
case OID_rsaEncryption:
ctx->sinfo->sig->pkey_algo = "rsa";
+   ctx->sinfo->sig->encoding = "pkcs1";
break;
default:
printk("Unsupported pkey algo: %u\n", ctx->last_oid);
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c 
b/crypto/asymmetric_keys/x509_cert_parser.c
index 865f46ea724f..1f1899d5ab43 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -199,35 +199,32 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,
 
case OID_md4WithRSAEncryption:
ctx->cert->sig->hash_algo = "md4";
-   ctx->cert->sig->pkey_algo = "rsa";
-   break;
+   goto rsa_pkcs1;
 
case OID_sha1WithRSAEncryption:
ctx->cert->sig->hash_algo = "sha1";
-   ctx->cert->sig->pkey_algo = "rsa";
-   break;
+   goto rsa_pkcs1;
 
case OID_sha256WithRSAEncryption:
ctx->cert->sig->hash_algo = "sha256";
-   ctx->cert->sig->pkey_algo = "rsa";
-   break;
+   goto rsa_pkcs1;
 
case OID_sha384WithRSAEncryption:
ctx->cert->sig->hash_algo = "sha384";
-   ctx->cert->sig->pkey_algo = "rsa";
-   break;
+   goto rsa_pkcs1;
 
case OID_sha512WithRSAEncryption:
ctx->cert->sig->hash_algo = "sha512";
-   ctx->cert->sig->pkey_algo = "rsa";
-   break;
+   goto rsa_pkcs1;
 
case OID_sha224WithRSAEncryption:
ctx->cert->sig->hash_algo = "sha224";
-   ctx->cert->sig->pkey_algo = "rsa";
-   break;
+   goto rsa_pkcs1;
}
 
+rsa_pkcs1:
+   ctx->cert->sig->pkey_algo = "rsa";
+   ctx->cert->sig->encoding = "pkcs1";
ctx->algo_oid = ctx->last_oid;
return 0;
 }

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/8] KEYS: keyctl operations for asymmetric keys [ver #2]

2016-06-23 Thread David Howells

Here's a set of patches that provides keyctl access for asymmetric keys,
including a query function, and functions to do encryption, decryption,
signature creation and signature verification.

I've added a PKCS#8 asymmetric key parser so that you can load an RSA private
key into the kernel.  Currently only DER-encoded and unencrypted PKCS#8 is
supported.  Encryption and verification can use a public key from an X.509
cert, but signing and decryption require a private key, though encryption and
verification can use that too.

Example usage:

j=`openssl pkcs8 -in private_key.pem -topk8 -nocrypt -outform DER | \
keyctl padd asymmetric foo @s`
echo -n abcdefghijklmnopqrst >/tmp/data
keyctl pkey_encrypt $j /tmp/data enc=pkcs1 >/tmp/enc
keyctl pkey_decrypt $j /tmp/enc enc=pkcs1 >/tmp/dec
cmp /tmp/data /tmp/dec
keyctl pkey_sign $j /tmp/data enc=pkcs1 hash=sha1 >/tmp/sig
keyctl pkey_verify $j /tmp/data /tmp/sig enc=pkcs1 hash=sha1

Changes:

 (*) I've taken out the password parameters for the moment as there isn't
 yet a subtype that uses them.  I have, however, left space in the
 keyctl UAPI to add them back later.

The kernel patches can be found here also:


http://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=keys-asym-keyctl

The keyutils changes needed can be found here:


http://git.kernel.org/cgit/linux/kernel/git/dhowells/keyutils.git/log/?h=pkey

David
---
David Howells (8):
  KEYS: Provide key type operations for asymmetric key ops
  KEYS: Provide keyctls to drive the new key type ops for asymmetric keys
  KEYS: Provide missing asymmetric key subops for new key type ops
  KEYS: Make the X.509 and PKCS7 parsers supply the sig encoding type
  KEYS: Provide software public key query function
  KEYS: Allow the public_key struct to hold a private key
  KEYS: Implement encrypt, decrypt and sign for software asymmetric key
  KEYS: Implement PKCS#8 RSA Private Key parser


 Documentation/crypto/asymmetric-keys.txt  |   26 ++
 Documentation/security/keys.txt   |  217 +++
 crypto/asymmetric_keys/Kconfig|   10 +
 crypto/asymmetric_keys/Makefile   |   13 +
 crypto/asymmetric_keys/asymmetric_keys.h  |3 
 crypto/asymmetric_keys/asymmetric_type.c  |   59 +
 crypto/asymmetric_keys/pkcs7_parser.c |1 
 crypto/asymmetric_keys/pkcs8.asn1 |   24 ++
 crypto/asymmetric_keys/pkcs8_parser.c |  184 +
 crypto/asymmetric_keys/public_key.c   |  195 --
 crypto/asymmetric_keys/signature.c|   95 +
 crypto/asymmetric_keys/x509_cert_parser.c |   21 +-
 include/crypto/public_key.h   |   14 +
 include/keys/asymmetric-subtype.h |9 +
 include/linux/key-type.h  |   11 +
 include/linux/keyctl.h|   46 
 include/uapi/linux/keyctl.h   |   30 +++
 security/keys/Makefile|1 
 security/keys/compat.c|   18 ++
 security/keys/internal.h  |   39 
 security/keys/keyctl.c|   24 ++
 security/keys/keyctl_pkey.c   |  323 +
 22 files changed, 1319 insertions(+), 44 deletions(-)
 create mode 100644 crypto/asymmetric_keys/pkcs8.asn1
 create mode 100644 crypto/asymmetric_keys/pkcs8_parser.c
 create mode 100644 include/linux/keyctl.h
 create mode 100644 security/keys/keyctl_pkey.c

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/8] KEYS: Provide missing asymmetric key subops for new key type ops [ver #2]

2016-06-23 Thread David Howells
Provide the missing asymmetric key subops for new key type ops.  This
include query, encrypt, decrypt and create signature.  Verify signature
already exists.  Also provided are accessor functions for this:

int query_asymmetric_key(const struct key *key,
 struct kernel_pkey_query *info);

int encrypt_blob(struct kernel_pkey_params *params,
 const void *data, void *enc);
int decrypt_blob(struct kernel_pkey_params *params,
 const void *enc, void *data);
int create_signature(struct kernel_pkey_params *params,
 const void *data, void *enc);

The public_key_signature struct gains an encoding field to carry the
encoding for verify_signature().

Signed-off-by: David Howells <dhowe...@redhat.com>
---

 Documentation/crypto/asymmetric-keys.txt |   24 ++--
 crypto/asymmetric_keys/asymmetric_keys.h |3 +
 crypto/asymmetric_keys/asymmetric_type.c |   59 ---
 crypto/asymmetric_keys/signature.c   |   95 ++
 include/crypto/public_key.h  |   13 +++-
 include/keys/asymmetric-subtype.h|9 +++
 6 files changed, 188 insertions(+), 15 deletions(-)

diff --git a/Documentation/crypto/asymmetric-keys.txt 
b/Documentation/crypto/asymmetric-keys.txt
index 8c07e0ea6bc0..cdf2aca41b2c 100644
--- a/Documentation/crypto/asymmetric-keys.txt
+++ b/Documentation/crypto/asymmetric-keys.txt
@@ -182,6 +182,10 @@ and looks like the following:
 
void (*describe)(const struct key *key, struct seq_file *m);
void (*destroy)(void *payload);
+   int (*query)(const struct kernel_pkey_params *params,
+struct kernel_pkey_query *info);
+   int (*eds_op)(struct kernel_pkey_params *params,
+ const void *in, void *out);
int (*verify_signature)(const struct key *key,
const struct public_key_signature *sig);
};
@@ -206,12 +210,22 @@ There are a number of operations defined by the subtype:
  asymmetric key will look after freeing the fingerprint and releasing the
  reference on the subtype module.
 
- (3) verify_signature().
+ (3) query().
 
- Optional.  These are the entry points for the key usage operations.
- Currently there is only the one defined.  If not set, the caller will be
- given -ENOTSUPP.  The subtype may do anything it likes to implement an
- operation, including offloading to hardware.
+ Mandatory.  This is a function for querying the capabilities of a key.
+
+ (4) eds_op().
+
+ Optional.  This is the entry point for the encryption, decryption and
+ signature creation operations (which are distinguished by the operation ID
+ in the parameter struct).  The subtype may do anything it likes to
+ implement an operation, including offloading to hardware.
+
+ (5) verify_signature().
+
+ Optional.  This is the entry point for signature verification.  The
+ subtype may do anything it likes to implement an operation, including
+ offloading to hardware.
 
 
 ==
diff --git a/crypto/asymmetric_keys/asymmetric_keys.h 
b/crypto/asymmetric_keys/asymmetric_keys.h
index ca8e9ac34ce6..7be1ccf4fa9f 100644
--- a/crypto/asymmetric_keys/asymmetric_keys.h
+++ b/crypto/asymmetric_keys/asymmetric_keys.h
@@ -16,3 +16,6 @@ extern struct asymmetric_key_id 
*asymmetric_key_hex_to_key_id(const char *id);
 extern int __asymmetric_key_hex_to_key_id(const char *id,
  struct asymmetric_key_id *match_id,
  size_t hexlen);
+
+extern int asymmetric_key_eds_op(struct kernel_pkey_params *params,
+const void *in, void *out);
diff --git a/crypto/asymmetric_keys/asymmetric_type.c 
b/crypto/asymmetric_keys/asymmetric_type.c
index 6600181d5d01..77aa44abd7a6 100644
--- a/crypto/asymmetric_keys/asymmetric_type.c
+++ b/crypto/asymmetric_keys/asymmetric_type.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "asymmetric_keys.h"
 
 MODULE_LICENSE("GPL");
@@ -451,15 +452,57 @@ static void asymmetric_key_destroy(struct key *key)
asymmetric_key_free_kids(kids);
 }
 
+int asymmetric_key_eds_op(struct kernel_pkey_params *params,
+ const void *in, void *out)
+{
+   const struct asymmetric_key_subtype *subtype;
+   struct key *key = params->key;
+   int ret;
+
+   pr_devel("==>%s()\n", __func__);
+
+   if (key->type != _type_asymmetric)
+   return -EINVAL;
+   subtype = asymmetric_key_subtype(key);
+   if (!subtype ||
+   !key->payload.data[0])
+   return -EINVAL;
+   if (!subtype->eds_op)
+   return -ENOTSUPP;
+
+   ret = subtype->eds_o

[PATCH 2/8] KEYS: Provide keyctls to drive the new key type ops for asymmetric keys [ver #2]

2016-06-23 Thread David Howells
Provide five keyctl functions that permit userspace to make use of the new
key type ops for accessing and driving asymmetric keys.

 (*) Query an asymmetric key.

long keyctl(KEYCTL_PKEY_QUERY,
key_serial_t key, unsigned long reserved,
struct keyctl_pkey_query *info);

 Get information about an asymmetric key.  The information is returned
 in the keyctl_pkey_query struct:

__u32   supported_ops;

 A bit mask of flags indicating which ops are supported.  This is
 constructed from a bitwise-OR of:

KEYCTL_SUPPORTS_{ENCRYPT,DECRYPT,SIGN,VERIFY}

__u32   key_size;

 The size in bits of the key.

__u16   max_data_size;
__u16   max_sig_size;
__u16   max_enc_size;
__u16   max_dec_size;

 The maximum sizes in bytes of a blob of data to be signed, a signature
 blob, a blob to be encrypted and a blob to be decrypted.

 reserved must be set to 0.  This is intended for future use to hand
 over one or more passphrases needed unlock a key.

 If successful, 0 is returned.  If the key is not an asymmetric key,
 EOPNOTSUPP is returned.


 (*) Encrypt, decrypt, sign or verify a blob using an asymmetric key.

long keyctl(KEYCTL_PKEY_ENCRYPT,
const struct keyctl_pkey_params *params,
const char *info,
const void *in,
void *out);

long keyctl(KEYCTL_PKEY_DECRYPT,
const struct keyctl_pkey_params *params,
const char *info,
const void *in,
void *out);

long keyctl(KEYCTL_PKEY_SIGN,
const struct keyctl_pkey_params *params,
const char *info,
const void *in,
void *out);

long keyctl(KEYCTL_PKEY_VERIFY,
const struct keyctl_pkey_params *params,
const char *info,
const void *in,
const void *in2);

 Use an asymmetric key to perform a public-key cryptographic operation
 a blob of data.

 The parameter block pointed to by params contains a number of integer
 values:

__s32   key_id;
__u32   in_len;
__u32   out_len;
__u32   in2_len;

 For a given operation, the in and out buffers are used as follows:

Operation IDin,in_len   out,out_len in2,in2_len
=== === === ===
KEYCTL_PKEY_ENCRYPT Raw dataEncrypted data  -
KEYCTL_PKEY_DECRYPT Encrypted data  Raw data-
KEYCTL_PKEY_SIGNRaw dataSignature   -
KEYCTL_PKEY_VERIFY  Raw data-   Signature

 info is a string of key=value pairs that supply supplementary
 information.

 The __spare space in the parameter block must be set to 0.  This is
 intended, amongst other things, to allow the passing of passphrases
 required to unlock a key.

 If successful, encrypt, decrypt and sign all return the amount of data
 written into the output buffer.  Verification returns 0 on success.

Signed-off-by: David Howells <dhowe...@redhat.com>
---

 Documentation/security/keys.txt |  111 +
 include/uapi/linux/keyctl.h |   25 +++
 security/keys/Makefile  |1 
 security/keys/compat.c  |   18 ++
 security/keys/internal.h|   39 +
 security/keys/keyctl.c  |   24 +++
 security/keys/keyctl_pkey.c |  323 +++
 7 files changed, 541 insertions(+)
 create mode 100644 security/keys/keyctl_pkey.c

diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt
index 286b4cab7e68..6844dcbba1ba 100644
--- a/Documentation/security/keys.txt
+++ b/Documentation/security/keys.txt
@@ -857,6 +857,117 @@ The keyctl syscall functions are:
  supported, error ENOKEY if the key could not be found, or error
  EACCES if the key is not readable by the caller.
 
+
+ (*) Query an asymmetric key.
+
+   long keyctl(KEYCTL_PKEY_QUERY,
+   key_serial_t key_id, unsigned long reserved,
+   struct keyctl_pkey_query *info);
+
+ Get information about an asymmetric key.  The information is returned in
+ the keyctl_pkey_query struct:
+
+   __u32   supported_ops;
+
+ A bit mask of flags indicating which ops are supported.  This is
+ constructed from a bitwise-OR of:
+
+   KEYCTL_SUPPORTS_{ENCRYPT,DECRYPT,SIGN,VERIFY}
+
+   __u32   key_size;
+
+ The size in bits of the key.
+
+   __u16   max_data_size;
+   __u16   max_sig_size;
+   __u16   max_enc_size;
+   __u16   max_dec_size;
+
+ The maximum sizes in bytes of a blob of data to be signed, a signature
+ blob, 

[PATCH 6/8] KEYS: Allow the public_key struct to hold a private key [ver #2]

2016-06-23 Thread David Howells
Put a flag in the public_key struct to indicate if the structure is holding
a private key.  The private key must be held ASN.1 encoded in the format
specified in RFC 3447 A.1.2.  This is the form required by crypto/rsa.c.

The software encryption subtype's verification and query functions then
need to select the appropriate crypto function to set the key.

Signed-off-by: David Howells <dhowe...@redhat.com>
---

 crypto/asymmetric_keys/public_key.c |   14 --
 include/crypto/public_key.h |1 +
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index a48a47a1dff0..a29ca01a41a0 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -113,7 +113,12 @@ static int software_key_query(const struct 
kernel_pkey_params *params,
if (IS_ERR(tfm))
return PTR_ERR(tfm);
 
-   ret = crypto_akcipher_set_pub_key(tfm, pkey->key, pkey->keylen);
+   if (pkey->key_is_private)
+   ret = crypto_akcipher_set_priv_key(tfm,
+  pkey->key, pkey->keylen);
+   else
+   ret = crypto_akcipher_set_pub_key(tfm,
+ pkey->key, pkey->keylen);
if (ret < 0)
goto error_free_tfm;
 
@@ -184,7 +189,12 @@ int public_key_verify_signature(const struct public_key 
*pkey,
if (!req)
goto error_free_tfm;
 
-   ret = crypto_akcipher_set_pub_key(tfm, pkey->key, pkey->keylen);
+   if (pkey->key_is_private)
+   ret = crypto_akcipher_set_priv_key(tfm,
+  pkey->key, pkey->keylen);
+   else
+   ret = crypto_akcipher_set_pub_key(tfm,
+ pkey->key, pkey->keylen);
if (ret)
goto error_free_req;
 
diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
index c46140d3729c..c5e569b2a73e 100644
--- a/include/crypto/public_key.h
+++ b/include/crypto/public_key.h
@@ -25,6 +25,7 @@
 struct public_key {
void *key;
u32 keylen;
+   bool key_is_private;
const char *id_type;
const char *pkey_algo;
 };

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 8/8] KEYS: Implement PKCS#8 RSA Private Key parser [ver #2]

2016-06-23 Thread David Howells
Implement PKCS#8 RSA Private Key format [RFC 5208] parser for the
asymmetric key type.  For the moment, this will only support unencrypted
DER blobs.  PEM and decryption can be added later.

PKCS#8 keys can be loaded like this:

openssl pkcs8 -in private_key.pem -topk8 -nocrypt -outform DER | \
  keyctl padd asymmetric foo @s

Signed-off-by: David Howells <dhowe...@redhat.com>
---

 Documentation/crypto/asymmetric-keys.txt |2 
 crypto/asymmetric_keys/Kconfig   |   10 ++
 crypto/asymmetric_keys/Makefile  |   13 ++
 crypto/asymmetric_keys/pkcs8.asn1|   24 
 crypto/asymmetric_keys/pkcs8_parser.c|  184 ++
 5 files changed, 233 insertions(+)
 create mode 100644 crypto/asymmetric_keys/pkcs8.asn1
 create mode 100644 crypto/asymmetric_keys/pkcs8_parser.c

diff --git a/Documentation/crypto/asymmetric-keys.txt 
b/Documentation/crypto/asymmetric-keys.txt
index cdf2aca41b2c..80d45b5776b0 100644
--- a/Documentation/crypto/asymmetric-keys.txt
+++ b/Documentation/crypto/asymmetric-keys.txt
@@ -247,6 +247,8 @@ Examples of blob formats for which parsers could be 
implemented include:
  - X.509 ASN.1 stream.
  - Pointer to TPM key.
  - Pointer to UEFI key.
+ - PKCS#8 private key [RFC 5208].
+ - PKCS#5 encrypted private key [RFC 2898].
 
 During key instantiation each parser in the list is tried until one doesn't
 return -EBADMSG.
diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
index 331f6baf2df8..338fbed30a32 100644
--- a/crypto/asymmetric_keys/Kconfig
+++ b/crypto/asymmetric_keys/Kconfig
@@ -30,6 +30,16 @@ config X509_CERTIFICATE_PARSER
  data and provides the ability to instantiate a crypto key from a
  public key packet found inside the certificate.
 
+config PKCS8_PRIVATE_KEY_PARSER
+   tristate "PKCS#8 private key parser"
+   depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE
+   select ASN1
+   select OID_REGISTRY
+   help
+ This option provides support for parsing PKCS#8 format blobs for
+ private key data and provides the ability to instantiate a crypto key
+ from that data.
+
 config PKCS7_MESSAGE_PARSER
tristate "PKCS#7 message parser"
depends on X509_CERTIFICATE_PARSER
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
index 6516855bec18..ac877577d677 100644
--- a/crypto/asymmetric_keys/Makefile
+++ b/crypto/asymmetric_keys/Makefile
@@ -32,6 +32,19 @@ clean-files  += x509-asn1.c x509-asn1.h
 clean-files+= x509_akid-asn1.c x509_akid-asn1.h
 
 #
+# PKCS#8 private key handling
+#
+obj-$(CONFIG_PKCS8_PRIVATE_KEY_PARSER) += pkcs8_key_parser.o
+pkcs8_key_parser-y := \
+   pkcs8-asn1.o \
+   pkcs8_parser.o
+
+$(obj)/pkcs8_parser.o: $(obj)/pkcs8-asn1.h
+$(obj)/pkcs8-asn1.o: $(obj)/pkcs8-asn1.c $(obj)/pkcs8-asn1.h
+
+clean-files+= pkcs8-asn1.c pkcs8-asn1.h
+
+#
 # PKCS#7 message handling
 #
 obj-$(CONFIG_PKCS7_MESSAGE_PARSER) += pkcs7_message.o
diff --git a/crypto/asymmetric_keys/pkcs8.asn1 
b/crypto/asymmetric_keys/pkcs8.asn1
new file mode 100644
index ..702c41a3c713
--- /dev/null
+++ b/crypto/asymmetric_keys/pkcs8.asn1
@@ -0,0 +1,24 @@
+--
+-- This is the unencrypted variant
+--
+PrivateKeyInfo ::= SEQUENCE {
+   version Version,
+   privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
+   privateKey  PrivateKey,
+   attributes  [0] IMPLICIT Attributes OPTIONAL
+}
+
+Version ::= INTEGER  ({ pkcs8_note_version })
+
+PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier ({ pkcs8_note_algo })
+
+PrivateKey ::= OCTET STRING ({ pkcs8_note_key })
+
+Attributes ::= SET OF Attribute
+
+Attribute ::= ANY
+
+AlgorithmIdentifier ::= SEQUENCE {
+   algorithm   OBJECT IDENTIFIER ({ pkcs8_note_OID }),
+   parameters  ANY OPTIONAL
+}
diff --git a/crypto/asymmetric_keys/pkcs8_parser.c 
b/crypto/asymmetric_keys/pkcs8_parser.c
new file mode 100644
index ..26a73c0b7eef
--- /dev/null
+++ b/crypto/asymmetric_keys/pkcs8_parser.c
@@ -0,0 +1,184 @@
+/* PKCS#8 Private Key parser [RFC 5208].
+ *
+ * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowe...@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define pr_fmt(fmt) "PKCS8: "fmt
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "pkcs8-asn1.h"
+
+struct pkcs8_parse_context {
+   struct public_key *pub;
+   unsigned long   data;   /* Start of data */
+   enum OIDlast_oid;   /* Last OID encountered */
+   enum OIDalgo_oid;   /* Algorithm OID */
+ 

[PATCH 7/8] KEYS: Implement encrypt, decrypt and sign for software asymmetric key [ver #2]

2016-06-23 Thread David Howells
Implement the encrypt, decrypt and sign operations for the software
asymmetric key subtype.  This mostly involves offloading the call to the
crypto layer.

Note that the decrypt and sign operations require a private key to be
supplied.  Encrypt (and also verify) will work with either a public or a
private key.  A public key can be supplied with an X.509 certificate and a
private key can be supplied using a PKCS#8 blob:

# j=`openssl pkcs8 -in ~/pkcs7/firmwarekey2.priv -topk8 -nocrypt 
-outform DER | keyctl padd asymmetric foo @s`
# keyctl pkey_query $j - enc=pkcs1
key_size=4096
max_data_size=512
max_sig_size=512
max_enc_size=512
max_dec_size=512
encrypt=y
decrypt=y
sign=y
verify=y
# keyctl pkey_encrypt $j 0 data enc=pkcs1 >/tmp/enc
# keyctl pkey_decrypt $j 0 /tmp/enc enc=pkcs1 >/tmp/dec
# cmp data /tmp/dec
# keyctl pkey_sign $j 0 data enc=pkcs1 hash=sha1 >/tmp/sig
# keyctl pkey_verify $j 0 data /tmp/sig enc=pkcs1 hash=sha1
#

Signed-off-by: David Howells <dhowe...@redhat.com>
---

 crypto/asymmetric_keys/public_key.c |   89 ++-
 1 file changed, 86 insertions(+), 3 deletions(-)

diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index a29ca01a41a0..8be2586028b6 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -128,7 +128,11 @@ static int software_key_query(const struct 
kernel_pkey_params *params,
info->max_sig_size = len;
info->max_enc_size = len;
info->max_dec_size = len;
-   info->supported_ops = KEYCTL_SUPPORTS_VERIFY;
+   info->supported_ops = (KEYCTL_SUPPORTS_ENCRYPT |
+  KEYCTL_SUPPORTS_VERIFY);
+   if (pkey->key_is_private)
+   info->supported_ops |= (KEYCTL_SUPPORTS_DECRYPT |
+   KEYCTL_SUPPORTS_SIGN);
ret = 0;
 
 error_free_tfm:
@@ -142,7 +146,7 @@ struct public_key_completion {
int err;
 };
 
-static void public_key_verify_done(struct crypto_async_request *req, int err)
+static void public_key_crypto_done(struct crypto_async_request *req, int err)
 {
struct public_key_completion *compl = req->data;
 
@@ -154,6 +158,84 @@ static void public_key_verify_done(struct 
crypto_async_request *req, int err)
 }
 
 /*
+ * Do encryption, decryption and signing ops.
+ */
+static int software_key_eds_op(struct kernel_pkey_params *params,
+  const void *in, void *out)
+{
+   struct public_key_completion compl;
+   const struct public_key *pkey = params->key->payload.data[asym_crypto];
+   struct akcipher_request *req;
+   struct crypto_akcipher *tfm;
+   struct scatterlist in_sg, out_sg;
+   char alg_name[CRYPTO_MAX_ALG_NAME];
+   int ret;
+
+   pr_devel("==>%s()\n", __func__);
+
+   ret = software_key_determine_akcipher(params->encoding,
+ params->hash_algo,
+ pkey, alg_name);
+   if (ret < 0)
+   return ret;
+
+   tfm = crypto_alloc_akcipher(alg_name, 0, 0);
+   if (IS_ERR(tfm))
+   return PTR_ERR(tfm);
+
+   req = akcipher_request_alloc(tfm, GFP_KERNEL);
+   if (!req)
+   goto error_free_tfm;
+
+   if (pkey->key_is_private)
+   ret = crypto_akcipher_set_priv_key(tfm,
+  pkey->key, pkey->keylen);
+   else
+   ret = crypto_akcipher_set_pub_key(tfm,
+ pkey->key, pkey->keylen);
+   if (ret)
+   goto error_free_req;
+
+   sg_init_one(_sg, in, params->in_len);
+   sg_init_one(_sg, out, params->out_len);
+   akcipher_request_set_crypt(req, _sg, _sg, params->in_len,
+  params->out_len);
+   init_completion();
+   akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
+ CRYPTO_TFM_REQ_MAY_SLEEP,
+ public_key_crypto_done, );
+
+   /* Perform the encryption calculation. */
+   switch (params->op) {
+   case kernel_pkey_encrypt:
+   ret = crypto_akcipher_encrypt(req);
+   break;
+   case kernel_pkey_decrypt:
+   ret = crypto_akcipher_decrypt(req);
+   break;
+   case kernel_pkey_sign:
+   ret = crypto_akcipher_sign(req);
+   break;
+   default:
+   BUG();
+   }
+   if (ret == -EINPROGRESS) {
+   wait_for_completion();
+   ret = compl.err;
+   }
+
+   if (ret == 0)
+   ret = req->dst_len;
+
+e

[PATCH 0/8] KEYS: keyctl operations for asymmetric keys

2016-06-23 Thread David Howells

Here's a set of patches that provides keyctl access for asymmetric keys,
including a query function, and functions to do encryption, decryption,
signature creation and signature verification.

I've added a PKCS#8 asymmetric key parser so that you can load an RSA private
key into the kernel.  Currently only DER-encoded and unencrypted PKCS#8 is
supported.  Encryption and verification can use a public key from an X.509
cert, but signing and decryption require a private key, though encryption and
verification can use that too.

Example usage:

j=`openssl pkcs8 -in private_key.pem -topk8 -nocrypt -outform DER | \
keyctl padd asymmetric foo @s`
echo -n abcdefghijklmnopqrst >/tmp/data
keyctl pkey_encrypt $j /tmp/data enc=pkcs1 >/tmp/enc
keyctl pkey_decrypt $j /tmp/enc enc=pkcs1 >/tmp/dec
cmp /tmp/data /tmp/dec
keyctl pkey_sign $j /tmp/data enc=pkcs1 hash=sha1 >/tmp/sig
keyctl pkey_verify $j /tmp/data /tmp/sig enc=pkcs1 hash=sha1

Changes:

 (*) I've taken out the password parameters for the moment as there isn't
 yet a subtype that uses them.  I have, however, left space in the
 keyctl UAPI to add them back later.

The kernel patches can be found here also:


http://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=keys-asym-keyctl

The keyutils changes needed can be found here:


http://git.kernel.org/cgit/linux/kernel/git/dhowells/keyutils.git/log/?h=pkey

David
---
David Howells (8):
  KEYS: Provide key type operations for asymmetric key ops
  KEYS: Provide keyctls to drive the new key type ops for asymmetric keys
  KEYS: Provide missing asymmetric key subops for new key type ops
  KEYS: Make the X.509 and PKCS7 parsers supply the sig encoding type
  KEYS: Provide software public key query function
  KEYS: Allow the public_key struct to hold a private key
  KEYS: Implement encrypt, decrypt and sign for software asymmetric key
  KEYS: Implement PKCS#8 RSA Private Key parser


 Documentation/crypto/asymmetric-keys.txt  |   26 ++
 Documentation/security/keys.txt   |  217 +++
 crypto/asymmetric_keys/Kconfig|   10 +
 crypto/asymmetric_keys/Makefile   |   13 +
 crypto/asymmetric_keys/asymmetric_keys.h  |3 
 crypto/asymmetric_keys/asymmetric_type.c  |   59 +
 crypto/asymmetric_keys/pkcs7_parser.c |1 
 crypto/asymmetric_keys/pkcs8.asn1 |   24 ++
 crypto/asymmetric_keys/pkcs8_parser.c |  184 +
 crypto/asymmetric_keys/public_key.c   |  195 --
 crypto/asymmetric_keys/signature.c|   95 +
 crypto/asymmetric_keys/x509_cert_parser.c |   21 +-
 include/crypto/public_key.h   |   14 +
 include/keys/asymmetric-subtype.h |9 +
 include/linux/key-type.h  |   11 +
 include/linux/keyctl.h|   46 
 include/uapi/linux/keyctl.h   |   30 +++
 security/keys/Makefile|1 
 security/keys/compat.c|   18 ++
 security/keys/internal.h  |   39 
 security/keys/keyctl.c|   24 ++
 security/keys/keyctl_pkey.c   |  323 +
 22 files changed, 1319 insertions(+), 44 deletions(-)
 create mode 100644 crypto/asymmetric_keys/pkcs8.asn1
 create mode 100644 crypto/asymmetric_keys/pkcs8_parser.c
 create mode 100644 include/linux/keyctl.h
 create mode 100644 security/keys/keyctl_pkey.c

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: KEYS: Use skcipher for big keys

2016-06-22 Thread David Howells
Herbert Xu <herb...@gondor.apana.org.au> wrote:

> I'm in the process of removing blkcipher/ablkcipher which have
> been replaced with skcipher.  It would be nice if we stop adding
> new users of these two interfaces :)
> 
> Anyway, if you guys are OK with this patch I'd like to push it
> through cryptodev so I can carry on with the removal of blkcipher.

As long as it only touches the big_key code inside keyrings, I think that's
fine.

Acked-by: David Howells <dhowe...@redhat.com>
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] KEYS: Add placeholder for KDF usage with DH

2016-05-31 Thread David Howells
Hi James,

> Could you pass this along to Linus as soon as possible, please?  This
> alters a new keyctl function added in the current merge window to allow for
> a future extension planned for the next merge window.

Is this likely to go to Linus before -rc2?  If not, we'll need to do things
differently.

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] KEYS: Add placeholder for KDF usage with DH

2016-05-26 Thread David Howells
Hi James,

Could you pass this along to Linus as soon as possible, please?  This
alters a new keyctl function added in the current merge window to allow for
a future extension planned for the next merge window.

Thanks,
David
---
From: Stephan Mueller <smuel...@chronox.de>
Date: Thu May 26 23:38:12 2016 +0200

KEYS: Add placeholder for KDF usage with DH

The values computed during Diffie-Hellman key exchange are often used
in combination with key derivation functions to create cryptographic
keys.  Add a placeholder for a later implementation to configure a
key derivation function that will transform the Diffie-Hellman
result returned by the KEYCTL_DH_COMPUTE command.

[This patch was stripped down from a patch produced by Mat Martineau that
 had a bug in the compat code - so for the moment Stephan's patch simply
 requires that the placeholder argument must be NULL]

Original-signed-off-by: Mat Martineau <mathew.j.martin...@linux.intel.com>
Signed-off-by: Stephan Mueller <smuel...@chronox.de>
Signed-off-by: David Howells <dhowe...@redhat.com>
---
 Documentation/security/keys.txt |5 -
 security/keys/compat.c  |2 +-
 security/keys/dh.c  |8 +++-
 security/keys/internal.h|5 +++--
 security/keys/keyctl.c  |4 ++--
 5 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt
index 20d05719bceb..3849814bfe6d 100644
--- a/Documentation/security/keys.txt
+++ b/Documentation/security/keys.txt
@@ -826,7 +826,8 @@ The keyctl syscall functions are:
  (*) Compute a Diffie-Hellman shared secret or public key
 
long keyctl(KEYCTL_DH_COMPUTE, struct keyctl_dh_params *params,
-  char *buffer, size_t buflen);
+  char *buffer, size_t buflen,
+  void *reserved);
 
  The params struct contains serial numbers for three keys:
 
@@ -843,6 +844,8 @@ The keyctl syscall functions are:
  public key.  If the base is the remote public key, the result is
  the shared secret.
 
+ The reserved argument must be set to NULL.
+
  The buffer length must be at least the length of the prime, or zero.
 
  If the buffer length is nonzero, the length of the result is
diff --git a/security/keys/compat.c b/security/keys/compat.c
index c8783b3b628c..36c80bf5b89c 100644
--- a/security/keys/compat.c
+++ b/security/keys/compat.c
@@ -134,7 +134,7 @@ COMPAT_SYSCALL_DEFINE5(keyctl, u32, option,
 
case KEYCTL_DH_COMPUTE:
return keyctl_dh_compute(compat_ptr(arg2), compat_ptr(arg3),
-arg4);
+arg4, compat_ptr(arg5));
 
default:
return -EOPNOTSUPP;
diff --git a/security/keys/dh.c b/security/keys/dh.c
index 880505a4b9f1..531ed2ec132f 100644
--- a/security/keys/dh.c
+++ b/security/keys/dh.c
@@ -78,7 +78,8 @@ error:
 }
 
 long keyctl_dh_compute(struct keyctl_dh_params __user *params,
-  char __user *buffer, size_t buflen)
+  char __user *buffer, size_t buflen,
+  void __user *reserved)
 {
long ret;
MPI base, private, prime, result;
@@ -97,6 +98,11 @@ long keyctl_dh_compute(struct keyctl_dh_params __user 
*params,
goto out;
}
 
+   if (reserved) {
+   ret = -EINVAL;
+   goto out;
+   }
+
keylen = mpi_from_key(pcopy.prime, buflen, );
if (keylen < 0 || !prime) {
/* buflen == 0 may be used to query the required buffer size,
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 8ec7a528365d..a705a7d92ad7 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -260,10 +260,11 @@ static inline long keyctl_get_persistent(uid_t uid, 
key_serial_t destring)
 
 #ifdef CONFIG_KEY_DH_OPERATIONS
 extern long keyctl_dh_compute(struct keyctl_dh_params __user *, char __user *,
- size_t);
+ size_t, void __user *);
 #else
 static inline long keyctl_dh_compute(struct keyctl_dh_params __user *params,
-char __user *buffer, size_t buflen)
+char __user *buffer, size_t buflen,
+void __user *reserved)
 {
return -EOPNOTSUPP;
 }
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 3b135a0af344..d580ad06b792 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -1688,8 +1688,8 @@ SYSCALL_DEFINE5(keyctl, int, option, unsigned long, arg2, 
unsigned long, arg3,
 
case KEYCTL_DH_COMPUTE:
return keyctl_dh_compute((struct keyctl_dh_params __user *) 
arg2,
-(char __user *) arg3,
-(size_t) arg4);
+(char __

Re: [PATCH] KEYS: Add optional key derivation parameters for DH

2016-05-26 Thread David Howells
Mat Martineau  wrote:

> +struct keyctl_kdf_params {
> + char *name;
> + __u8 reserved[32]; /* Reserved for future use, must be 0 */
> +};
> +
>  #endif /*  _LINUX_KEYCTL_H */
> diff --git a/security/keys/compat.c b/security/keys/compat.c
> index c8783b3..36c80bf 100644
> --- a/security/keys/compat.c
> +++ b/security/keys/compat.c
> @@ -134,7 +134,7 @@ COMPAT_SYSCALL_DEFINE5(keyctl, u32, option,
>  
>   case KEYCTL_DH_COMPUTE:
>   return keyctl_dh_compute(compat_ptr(arg2), compat_ptr(arg3),
> -  arg4);
> +  arg4, compat_ptr(arg5));

Given the new structure above, this won't work.  The problem is that on a
64-bit system the kernel expects 'name' to be a 64-bit pointer, but if we're
in the compat handler, we have a 32-bit userspace's idea of the struct - in
which 'name' is a 31-bit (s390x) or a 32-bit pointer without any padding.

So in compat code you can't just pass the user pointer direct through to
keyctl_dh_compute().  You need to supply a compat_keyctl_kdf_params struct and
translator code.

What I would recommend you do at the moment is to mark the syscall argument as
"reserved, must be 0" and deal with the implementation in the next merge
window.

David

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: key retention service: DH support

2016-05-25 Thread David Howells
Mat Martineau  wrote:

> Since the KDF patches are not yet merged, I'm not sure of the best way to
> accomodate the future feature. We could future-proof KEYCTL_DH_COMPUTE by
> adding a 5th arg, an optional pointer to KDF configuration (NAME and
> LABEL).

If we want to do this, it needs to be done before the merge window closes,
maybe by -rc2.  Just requiring the extra argument to be 0 for now and/or
extending struct keyctl_dh_params to include some must-be-zeroed spare space
would do for now.

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: key retention service: DH support

2016-05-24 Thread David Howells
Stephan Mueller  wrote:

> With the new DH support for the key retention service, support for DH derived 
> keys pops up.
> 
> The implementation in security/keys/dh.c returns the DH shared secret 
> straight 
> to the user space caller.
> 
> I implemented a KDF with that exact scenario already in mind: [1].
> 
> I am wondering whether the shared secret should be processed by a KDF before 
> returning the data to user space?
> 
> [1] http://www.chronox.de/kdf.html

Adding Mat to the cc list.  If we want to modify the new DH keyctl, we have a
very short time window in which to do so.

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 8/8] KEYS: Implement PKCS#8 RSA Private Key parser [ver 3]

2016-05-12 Thread David Howells
Mat Martineau  wrote:

> > # PKCS#7 message handling
> 
> Update to PKCS#8

I guess I've typed PKCS#7 too many times :-)

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 5/8] KEYS: Provide software public key query function [ver 3]

2016-05-12 Thread David Howells
Mat Martineau  wrote:

> > +   len = crypto_akcipher_maxsize(tfm);
> > +   info->key_size = len * 8;
> > +   info->max_data_size = len;
> > +   info->max_sig_size = len;
> > +   info->max_enc_size = len;
> > +   info->max_dec_size = len;
> 
> If len > UINT16_MAX, should UINT16_MAX be reported as the max size? Similar
> question for len*8 and key_size.

key_size is 32 bits, but the other sizes are all 16 bits, so you would need a
524288-bit key to exceed their capacity.  I'm not sure that's likely anytime
soon, but should I just make all the sizes 32-bit anyway?

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RESEND v5 0/6] crypto: algif - add akcipher

2016-05-11 Thread David Howells
Tadeusz Struk  wrote:

> 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

I've just reposted this.  The interface you're using should be the same, I
think, but the details underneath have changed.

Also, you can now supply private keys to the kernel if they're PKCS#8 encoded
and keyctls are supplied that do encryption, decryption, signing and
verifying, e.g.:

j=`openssl pkcs8 -in ~/pkcs7/firmwarekey2.priv -topk8 -nocrypt -outform 
DER | \
keyctl padd asymmetric foo @s`
echo -n abcdefghijklmnopqrst >/tmp/data
keyctl pkey_encrypt $j 0 /tmp/data enc=pkcs1 >/tmp/enc
keyctl pkey_decrypt $j 0 /tmp/enc enc=pkcs1 >/tmp/dec
cmp /tmp/data /tmp/dec
keyctl pkey_sign $j 0 /tmp/data enc=pkcs1 hash=sha1 >/tmp/sig
keyctl pkey_verify $j 0 /tmp/data /tmp/sig enc=pkcs1 hash=sha1

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH 2/8] KEYS: Provide keyctls to drive the new key type ops for asymmetric keys [ver 3]

2016-05-11 Thread David Howells
Provide five keyctl functions that permit userspace to make use of the new
key type ops for accessing and driving asymmetric keys.

 (*) Query an asymmetric key.

long keyctl(KEYCTL_PKEY_QUERY,
key_serial_t key, key_serial_t password,
struct keyctl_pkey_query *info);

 Get information about an asymmetric key.  The information is returned
 in the keyctl_pkey_query struct:

__u32   supported_ops;

 A bit mask of flags indicating which ops are supported.  This is
 constructed from a bitwise-OR of:

KEYCTL_SUPPORTS_{ENCRYPT,DECRYPT,SIGN,VERIFY}

__u32   key_size;

 The size in bits of the key.

__u16   max_data_size;
__u16   max_sig_size;
__u16   max_enc_size;
__u16   max_dec_size;

 The maximum sizes in bytes of a blob of data to be signed, a signature
 blob, a blob to be encrypted and a blob to be decypted.

 If the key needs to be unlocked with a password, a logon-type key that
 holds the password may be given as the password argument

 If successful, 0 is returned.  If the key is not an asymmetric key,
 EOPNOTSUPP is returned.


 (*) Encrypt, decrypt, sign or verify a blob using an asymmetric key.

long keyctl(KEYCTL_PKEY_ENCRYPT,
const struct keyctl_pkey_params *params,
const char *info,
const void *in,
void *out);

long keyctl(KEYCTL_PKEY_DECRYPT,
const struct keyctl_pkey_params *params,
const char *info,
const void *in,
void *out);

long keyctl(KEYCTL_PKEY_SIGN,
const struct keyctl_pkey_params *params,
const char *info,
const void *in,
void *out);

long keyctl(KEYCTL_PKEY_VERIFY,
const struct keyctl_pkey_params *params,
const char *info,
const void *in,
const void *in2);

 Use an asymmetric key to perform a public-key cryptographic operation
 a blob of data.

 The parameter block pointed to by params contains a number of integer
 values:

__s32   key_id;
__s32   password_id;
__u32   in_len;
__u32   out_len;
__u32   in2_len;

 For a given operation, the in and out buffers are used as follows:

Operation IDin,in_len   out,out_len in2,in2_len
=== === === ===
KEYCTL_PKEY_ENCRYPT Raw dataEncrypted data  -
KEYCTL_PKEY_DECRYPT Encrypted data  Raw data-
KEYCTL_PKEY_SIGNRaw dataSignature   -
KEYCTL_PKEY_VERIFY  Raw data-   Signature

 If the key must be unlocked with a password before it can be used,
 password_id should point to a logon-type key that holds this.

 info is a string of key=value pairs that supply supplementary
 information.

 If successful, encrypt, decrypt and sign all return the amount of data
 written into the output buffer.  Verification returns 0 on success.

Signed-off-by: David Howells <dhowe...@redhat.com>
---

 Documentation/security/keys.txt |  111 +
 include/uapi/linux/keyctl.h |   26 +++
 security/keys/Makefile  |1 
 security/keys/compat.c  |   15 ++
 security/keys/internal.h|   39 +
 security/keys/keyctl.c  |   23 +++
 security/keys/keyctl_pkey.c |  335 +++
 7 files changed, 550 insertions(+)
 create mode 100644 security/keys/keyctl_pkey.c

diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt
index ca72b70a24b9..01c2ae28a8c0 100644
--- a/Documentation/security/keys.txt
+++ b/Documentation/security/keys.txt
@@ -854,6 +854,117 @@ The keyctl syscall functions are:
  supported, error ENOKEY if the key could not be found, or error
  EACCES if the key is not readable by the caller.
 
+
+ (*) Query an asymmetric key.
+
+   long keyctl(KEYCTL_PKEY_QUERY,
+   key_serial_t key, key_serial_t password,
+   struct keyctl_pkey_query *info);
+
+ Get information about an asymmetric key.  The information is returned in
+ the keyctl_pkey_query struct:
+
+   __u32   supported_ops;
+
+ A bit mask of flags indicating which ops are supported.  This is
+ constructed from a bitwise-OR of:
+
+   KEYCTL_SUPPORTS_{ENCRYPT,DECRYPT,SIGN,VERIFY}
+
+   __u32   key_size;
+
+ The size in bits of the key.
+
+   __u16   max_data_size;
+   __u16   max_sig_size;
+   __u16   max_enc_size;
+   __u16   max_dec_size;
+
+ The maximum sizes in bytes of a blob of data to be signed, a signature
+ blob, 

[RFC PATCH 4/8] KEYS: Make the X.509 and PKCS7 parsers supply the sig encoding type [ver 3]

2016-05-11 Thread David Howells
Make the X.509 and PKCS7 parsers fill in the signature encoding type field
recently added to the public_key_signature struct.

Signed-off-by: David Howells <dhowe...@redhat.com>
---

 crypto/asymmetric_keys/pkcs7_parser.c |1 +
 crypto/asymmetric_keys/x509_cert_parser.c |   21 +
 2 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/crypto/asymmetric_keys/pkcs7_parser.c 
b/crypto/asymmetric_keys/pkcs7_parser.c
index af4cd8649117..5f0c6755a55b 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.c
+++ b/crypto/asymmetric_keys/pkcs7_parser.c
@@ -261,6 +261,7 @@ int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen,
switch (ctx->last_oid) {
case OID_rsaEncryption:
ctx->sinfo->sig->pkey_algo = "rsa";
+   ctx->sinfo->sig->encoding = "pkcs1";
break;
default:
printk("Unsupported pkey algo: %u\n", ctx->last_oid);
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c 
b/crypto/asymmetric_keys/x509_cert_parser.c
index 865f46ea724f..1f1899d5ab43 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -199,35 +199,32 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,
 
case OID_md4WithRSAEncryption:
ctx->cert->sig->hash_algo = "md4";
-   ctx->cert->sig->pkey_algo = "rsa";
-   break;
+   goto rsa_pkcs1;
 
case OID_sha1WithRSAEncryption:
ctx->cert->sig->hash_algo = "sha1";
-   ctx->cert->sig->pkey_algo = "rsa";
-   break;
+   goto rsa_pkcs1;
 
case OID_sha256WithRSAEncryption:
ctx->cert->sig->hash_algo = "sha256";
-   ctx->cert->sig->pkey_algo = "rsa";
-   break;
+   goto rsa_pkcs1;
 
case OID_sha384WithRSAEncryption:
ctx->cert->sig->hash_algo = "sha384";
-   ctx->cert->sig->pkey_algo = "rsa";
-   break;
+   goto rsa_pkcs1;
 
case OID_sha512WithRSAEncryption:
ctx->cert->sig->hash_algo = "sha512";
-   ctx->cert->sig->pkey_algo = "rsa";
-   break;
+   goto rsa_pkcs1;
 
case OID_sha224WithRSAEncryption:
ctx->cert->sig->hash_algo = "sha224";
-   ctx->cert->sig->pkey_algo = "rsa";
-   break;
+   goto rsa_pkcs1;
}
 
+rsa_pkcs1:
+   ctx->cert->sig->pkey_algo = "rsa";
+   ctx->cert->sig->encoding = "pkcs1";
ctx->algo_oid = ctx->last_oid;
return 0;
 }

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH 1/8] KEYS: Provide key type operations for asymmetric key ops [ver 3]

2016-05-11 Thread David Howells
Provide five new operations in the key_type struct that can be used to
provide access to asymmetric key operations.  These will be implemented for
the asymmetric key type in a later patch and may refer to a key retained in
RAM by the kernel or a key retained in crypto hardware.

 int (*asym_query)(const struct key *key, const struct key *password,
   struct kernel_pkey_query *info);
 int (*asym_eds_op)(struct kernel_pkey_params *params,
const void *in, void *out);
 int (*asym_verify_signature)(struct kernel_pkey_params *params,
  const void *in, const void *in2);

Since encrypt, decrypt and sign are identical in their interfaces, they're
rolled together in the asym_eds_op() operation and there's an operation ID
in the params argument to distinguish them.

Verify is different in that we supply the data and the signature instead
and get an error value (or 0) as the only result on the expectation that
this may well be how a hardware crypto device may work.

Signed-off-by: David Howells <dhowe...@redhat.com>
---

 Documentation/security/keys.txt |  113 +++
 include/linux/key-type.h|   11 
 include/linux/keyctl.h  |   47 
 include/uapi/linux/keyctl.h |5 ++
 4 files changed, 176 insertions(+)
 create mode 100644 include/linux/keyctl.h

diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt
index 20d05719bceb..ca72b70a24b9 100644
--- a/Documentation/security/keys.txt
+++ b/Documentation/security/keys.txt
@@ -1429,6 +1429,119 @@ The structure has a number of fields, some of which are 
mandatory:
 The authorisation key.
 
 
+ (*) int (*asym_eds_op)(struct kernel_pkey_params *params,
+   const void *in, void *out);
+ int (*asym_verify_signature)(struct kernel_pkey_params *params,
+ const void *in, const void *in2);
+
+ These methods are optional.  If provided the first allows a key to be
+ used to encrypt, decrypt or sign a blob of data, and the second allows a
+ key to verify a signature.
+
+ In all cases, the following information is provided in the params block:
+
+   struct kernel_pkey_params {
+   struct key  *key;
+   struct key  *password;
+   const char  *encoding;
+   const char  *hash_algo;
+   char*info;
+   __u32   in_len;
+   union {
+   __u32   out_len;
+   __u32   in2_len;
+   };
+   enum kernel_pkey_operation op : 8;
+   };
+
+ This includes the key to be used; an optional second key that can be used
+ to provide a password (and must be of logon type); an optional string
+ indicating the encoding to use (for instance, "pkcs1" may be used with an
+ RSA key to indicate RSASSA-PKCS1-v1.5 or RSAES-PKCS1-v1.5 encoding); the
+ name of the hash algorithm used to generate the data for a signature (if
+ appropriate); the sizes of the input and output (or second input) buffers;
+ and the ID of the operation to be performed.
+
+ For a given operation ID, the input and output buffers are used as
+ follows:
+
+   Operation IDin,in_len   out,out_len in2,in2_len
+   === === === ===
+   kernel_pkey_encrypt Raw dataEncrypted data  -
+   kernel_pkey_decrypt Encrypted data  Raw data-
+   kernel_pkey_signRaw dataSignature   -
+   kernel_pkey_verify  Raw data-   Signature
+
+ asym_eds_op() deals with encryption, decryption and signature creation as
+ specified by params->op.  Note that params->op is also set for
+ asym_verify_signature().
+
+ Encrypting and signature creation both take raw data in the input buffer
+ and return the encrypted result in the output buffer.  Padding may have
+ been added if an encoding was set.  In the case of signature creation,
+ depending on the encoding, the padding created may need to indicate the
+ digest algorithm - the name of which should be supplied in hash_algo.
+
+ Decryption takes encrypted data in the input buffer and returns the raw
+ data in the output buffer.  Padding will get checked and stripped off if
+ an encoding was set.
+
+ Verification takes raw data in the input buffer and the signature in the
+ second input buffer and checks that the one matches the other.  Padding
+ will be validated.  Depending on the encoding, the digest algorithm used
+ to generate the raw data may need to be indicated in hash_algo.
+
+ If successful, asym_eds_op() should return the number of bytes written
+ into the output buffer.  asym_verify_signa

[RFC PATCH 3/8] KEYS: Provide missing asymmetric key subops for new key type ops [ver 3]

2016-05-11 Thread David Howells
Provide the missing asymmetric key subops for new key type ops.  This
include query, encrypt, decrypt and create signature.  Verify signature
already exists.  Also provided are accessor functions for this:

int query_asymmetric_key(const struct key *key,
 const struct key *password,
 struct kernel_pkey_query *info);

int encrypt_blob(struct kernel_pkey_params *params,
 const void *data, void *enc);
int decrypt_blob(struct kernel_pkey_params *params,
 const void *enc, void *data);
int create_signature(struct kernel_pkey_params *params,
 const void *data, void *enc);

The public_key_signature struct gains an encoding field to carry the
encoding for verify_signature() and that function gains an extra key
pointer that can be used to pass a pointer to a logon key carrying a
password to unlock the key.

Signed-off-by: David Howells <dhowe...@redhat.com>
---

 Documentation/crypto/asymmetric-keys.txt |   31 +++-
 crypto/asymmetric_keys/asymmetric_keys.h |3 +
 crypto/asymmetric_keys/asymmetric_type.c |   60 ++--
 crypto/asymmetric_keys/pkcs7_trust.c |2 -
 crypto/asymmetric_keys/public_key.c  |1 
 crypto/asymmetric_keys/restrict.c|2 -
 crypto/asymmetric_keys/signature.c   |  112 +-
 include/crypto/public_key.h  |   13 +++
 include/keys/asymmetric-subtype.h|   10 +++
 security/integrity/digsig_asymmetric.c   |2 -
 10 files changed, 216 insertions(+), 20 deletions(-)

diff --git a/Documentation/crypto/asymmetric-keys.txt 
b/Documentation/crypto/asymmetric-keys.txt
index 8c07e0ea6bc0..93a071714de7 100644
--- a/Documentation/crypto/asymmetric-keys.txt
+++ b/Documentation/crypto/asymmetric-keys.txt
@@ -123,6 +123,7 @@ An operation is provided to perform cryptographic signature 
verification, using
 an asymmetric key to provide or to provide access to the public key.
 
int verify_signature(const struct key *key,
+const struct key *password,
 const struct public_key_signature *sig);
 
 The caller must have already obtained the key from some source and can then use
@@ -148,6 +149,9 @@ In addition, the data must have been digested by the caller 
and the resulting
 hash must be pointed to by sig->digest and the size of the hash be placed in
 sig->digest_size.
 
+If the key needs to be unlocked with a passphrase, this can be passed in a
+logon key as the password argument.
+
 The function will return 0 upon success or -EKEYREJECTED if the signature
 doesn't match.
 
@@ -182,6 +186,10 @@ and looks like the following:
 
void (*describe)(const struct key *key, struct seq_file *m);
void (*destroy)(void *payload);
+   int (*query)(const struct kernel_pkey_params *params,
+struct kernel_pkey_query *info);
+   int (*eds_op)(struct kernel_pkey_params *params,
+ const void *in, void *out);
int (*verify_signature)(const struct key *key,
const struct public_key_signature *sig);
};
@@ -206,12 +214,25 @@ There are a number of operations defined by the subtype:
  asymmetric key will look after freeing the fingerprint and releasing the
  reference on the subtype module.
 
- (3) verify_signature().
+ (3) query().
+
+ Mandatory.  This is a function for querying the capabilities of a key.  A
+ password can be provided if the key needs unlocking.
+
+ (4) eds_op().
+
+ Optional.  This is the entry point for the encryption, decryption and
+ signature creation operations (which are distinguished by the operation ID
+ in the parameter struct).  The subtype may do anything it likes to
+ implement an operation, including offloading to hardware.  A password can
+ be provided if the key needs unlocking.
+
+ (5) verify_signature().
 
- Optional.  These are the entry points for the key usage operations.
- Currently there is only the one defined.  If not set, the caller will be
- given -ENOTSUPP.  The subtype may do anything it likes to implement an
- operation, including offloading to hardware.
+ Optional.  This is the entry point for signature verification.  The
+ subtype may do anything it likes to implement an operation, including
+ offloading to hardware.  A password can be provided if the key needs
+ unlocking.
 
 
 ==
diff --git a/crypto/asymmetric_keys/asymmetric_keys.h 
b/crypto/asymmetric_keys/asymmetric_keys.h
index ca8e9ac34ce6..7be1ccf4fa9f 100644
--- a/crypto/asymmetric_keys/asymmetric_keys.h
+++ b/crypto/asymmetric_keys/asymmetric_keys.h
@@ -16,3 +16,6 @@ extern struct asymmetric_key_id 
*asymmetric_key_hex_to_key_id(const char *

[RFC PATCH 5/8] KEYS: Provide software public key query function [ver 3]

2016-05-11 Thread David Howells
Provide a query function for the software public key implementation.  This
permits information about such a key to be obtained using
query_asymmetric_key() or KEYCTL_PKEY_QUERY.

Signed-off-by: David Howells <dhowe...@redhat.com>
---

 crypto/asymmetric_keys/public_key.c |   96 ++-
 1 file changed, 82 insertions(+), 14 deletions(-)

diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index 96983906d2a2..e9967e5a2c25 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -57,6 +57,81 @@ static void public_key_destroy(void *payload0, void 
*payload3)
public_key_signature_free(payload3);
 }
 
+/*
+ * Determine the crypto algorithm name.
+ */
+static
+int software_key_determine_akcipher(const char *encoding,
+   const char *hash_algo,
+   const struct public_key *pkey,
+   char alg_name[CRYPTO_MAX_ALG_NAME])
+{
+   int n;
+
+   if (strcmp(encoding, "pkcs1") == 0) {
+   /* The data wangled by the RSA algorithm is typically padded
+* and encoded in some manner, such as EMSA-PKCS1-1_5 [RFC3447
+* sec 8.2].
+*/
+   if (!hash_algo)
+   n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
+"pkcs1pad(%s)",
+pkey->pkey_algo);
+   else
+   n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
+"pkcs1pad(%s,%s)",
+pkey->pkey_algo, hash_algo);
+   return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0;
+   }
+
+   if (strcmp(encoding, "raw") == 0) {
+   strcpy(alg_name, pkey->pkey_algo);
+   return 0;
+   }
+
+   return -ENOPKG;
+}
+
+/*
+ * Query information about a key.
+ */
+static int software_key_query(const struct kernel_pkey_params *params,
+ struct kernel_pkey_query *info)
+{
+   struct crypto_akcipher *tfm;
+   struct public_key *pkey = params->key->payload.data[asym_crypto];
+   char alg_name[CRYPTO_MAX_ALG_NAME];
+   int ret, len;
+
+   ret = software_key_determine_akcipher(params->encoding,
+ params->hash_algo,
+ pkey, alg_name);
+   if (ret < 0)
+   return ret;
+
+   tfm = crypto_alloc_akcipher(alg_name, 0, 0);
+   if (IS_ERR(tfm))
+   return PTR_ERR(tfm);
+
+   ret = crypto_akcipher_set_pub_key(tfm, pkey->key, pkey->keylen);
+   if (ret < 0)
+   goto error_free_tfm;
+
+   len = crypto_akcipher_maxsize(tfm);
+   info->key_size = len * 8;
+   info->max_data_size = len;
+   info->max_sig_size = len;
+   info->max_enc_size = len;
+   info->max_dec_size = len;
+   info->supported_ops = KEYCTL_SUPPORTS_VERIFY;
+   ret = 0;
+
+error_free_tfm:
+   crypto_free_akcipher(tfm);
+   pr_devel("<==%s() = %d\n", __func__, ret);
+   return ret;
+}
+
 struct public_key_completion {
struct completion completion;
int err;
@@ -83,8 +158,7 @@ int public_key_verify_signature(const struct public_key 
*pkey,
struct crypto_akcipher *tfm;
struct akcipher_request *req;
struct scatterlist sig_sg, digest_sg;
-   const char *alg_name;
-   char alg_name_buf[CRYPTO_MAX_ALG_NAME];
+   char alg_name[CRYPTO_MAX_ALG_NAME];
void *output;
unsigned int outlen;
int ret = -ENOMEM;
@@ -96,18 +170,11 @@ int public_key_verify_signature(const struct public_key 
*pkey,
BUG_ON(!sig->digest);
BUG_ON(!sig->s);
 
-   alg_name = sig->pkey_algo;
-   if (strcmp(sig->pkey_algo, "rsa") == 0) {
-   /* The data wangled by the RSA algorithm is typically padded
-* and encoded in some manner, such as EMSA-PKCS1-1_5 [RFC3447
-* sec 8.2].
-*/
-   if (snprintf(alg_name_buf, CRYPTO_MAX_ALG_NAME,
-"pkcs1pad(rsa,%s)", sig->hash_algo
-) >= CRYPTO_MAX_ALG_NAME)
-   return -EINVAL;
-   alg_name = alg_name_buf;
-   }
+   ret = software_key_determine_akcipher(sig->encoding,
+ sig->hash_algo,
+ pkey, alg_name);
+   if (ret < 0)
+   return ret;
 
tfm = crypto_alloc_akcipher(alg_name, 0, 0);
if (IS_ERR(tfm))
@@ -180,6 +247,7 @@ struct asymmetric_key_subtype public_key_subtype = {
.name_len  

[RFC PATCH 6/8] KEYS: Allow the public_key struct to hold a private key [ver 3]

2016-05-11 Thread David Howells
Put a flag in the public_key struct to indicate if the structure is holding
a private key.  The private key must be held ASN.1 encoded in the format
specified in RFC 3447 A.1.2.  This is the form required by crypto/rsa.c.

The software encryption subtype's verification and query functions then
need to select the appropriate crypto function to set the key.

Signed-off-by: David Howells <dhowe...@redhat.com>
---

 crypto/asymmetric_keys/public_key.c |   14 --
 include/crypto/public_key.h |1 +
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index e9967e5a2c25..92997d4e8173 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -113,7 +113,12 @@ static int software_key_query(const struct 
kernel_pkey_params *params,
if (IS_ERR(tfm))
return PTR_ERR(tfm);
 
-   ret = crypto_akcipher_set_pub_key(tfm, pkey->key, pkey->keylen);
+   if (pkey->key_is_private)
+   ret = crypto_akcipher_set_priv_key(tfm,
+  pkey->key, pkey->keylen);
+   else
+   ret = crypto_akcipher_set_pub_key(tfm,
+ pkey->key, pkey->keylen);
if (ret < 0)
goto error_free_tfm;
 
@@ -184,7 +189,12 @@ int public_key_verify_signature(const struct public_key 
*pkey,
if (!req)
goto error_free_tfm;
 
-   ret = crypto_akcipher_set_pub_key(tfm, pkey->key, pkey->keylen);
+   if (pkey->key_is_private)
+   ret = crypto_akcipher_set_priv_key(tfm,
+  pkey->key, pkey->keylen);
+   else
+   ret = crypto_akcipher_set_pub_key(tfm,
+ pkey->key, pkey->keylen);
if (ret)
goto error_free_req;
 
diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
index 1db6f1933dbd..a5096e72de5c 100644
--- a/include/crypto/public_key.h
+++ b/include/crypto/public_key.h
@@ -25,6 +25,7 @@
 struct public_key {
void *key;
u32 keylen;
+   bool key_is_private;
const char *id_type;
const char *pkey_algo;
 };

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH 8/8] KEYS: Implement PKCS#8 RSA Private Key parser [ver 3]

2016-05-11 Thread David Howells
Implement PKCS#8 RSA Private Key format [RFC 5208] parser for the
asymmetric key type.  For the moment, this will only support unencrypted
DER blobs.  PEM and decryption can be added later.

PKCS#8 keys can be loaded like this:

openssl pkcs8 -in private_key.pem -topk8 -nocrypt -outform DER | \
  keyctl padd asymmetric foo @s

Signed-off-by: David Howells <dhowe...@redhat.com>
---

 Documentation/crypto/asymmetric-keys.txt |2 
 crypto/asymmetric_keys/Kconfig   |   10 ++
 crypto/asymmetric_keys/Makefile  |   13 ++
 crypto/asymmetric_keys/pkcs8.asn1|   24 
 crypto/asymmetric_keys/pkcs8_parser.c|  184 ++
 5 files changed, 233 insertions(+)
 create mode 100644 crypto/asymmetric_keys/pkcs8.asn1
 create mode 100644 crypto/asymmetric_keys/pkcs8_parser.c

diff --git a/Documentation/crypto/asymmetric-keys.txt 
b/Documentation/crypto/asymmetric-keys.txt
index 93a071714de7..45e50c5695bf 100644
--- a/Documentation/crypto/asymmetric-keys.txt
+++ b/Documentation/crypto/asymmetric-keys.txt
@@ -254,6 +254,8 @@ Examples of blob formats for which parsers could be 
implemented include:
  - X.509 ASN.1 stream.
  - Pointer to TPM key.
  - Pointer to UEFI key.
+ - PKCS#8 private key [RFC 5208].
+ - PKCS#5 encrypted private key [RFC 2898].
 
 During key instantiation each parser in the list is tried until one doesn't
 return -EBADMSG.
diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
index e28e912000a7..c145bdf88381 100644
--- a/crypto/asymmetric_keys/Kconfig
+++ b/crypto/asymmetric_keys/Kconfig
@@ -29,6 +29,16 @@ config X509_CERTIFICATE_PARSER
  data and provides the ability to instantiate a crypto key from a
  public key packet found inside the certificate.
 
+config PKCS8_PRIVATE_KEY_PARSER
+   tristate "PKCS#8 private key parser"
+   depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE
+   select ASN1
+   select OID_REGISTRY
+   help
+ This option provides support for parsing PKCS#8 format blobs for
+ private key data and provides the ability to instantiate a crypto key
+ from that data.
+
 config PKCS7_MESSAGE_PARSER
tristate "PKCS#7 message parser"
depends on X509_CERTIFICATE_PARSER
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
index 6516855bec18..417035a53e98 100644
--- a/crypto/asymmetric_keys/Makefile
+++ b/crypto/asymmetric_keys/Makefile
@@ -34,6 +34,19 @@ clean-files  += x509_akid-asn1.c x509_akid-asn1.h
 #
 # PKCS#7 message handling
 #
+obj-$(CONFIG_PKCS8_PRIVATE_KEY_PARSER) += pkcs8_key_parser.o
+pkcs8_key_parser-y := \
+   pkcs8-asn1.o \
+   pkcs8_parser.o
+
+$(obj)/pkcs8_parser.o: $(obj)/pkcs8-asn1.h
+$(obj)/pkcs8-asn1.o: $(obj)/pkcs8-asn1.c $(obj)/pkcs8-asn1.h
+
+clean-files+= pkcs8-asn1.c pkcs8-asn1.h
+
+#
+# PKCS#7 message handling
+#
 obj-$(CONFIG_PKCS7_MESSAGE_PARSER) += pkcs7_message.o
 pkcs7_message-y := \
pkcs7-asn1.o \
diff --git a/crypto/asymmetric_keys/pkcs8.asn1 
b/crypto/asymmetric_keys/pkcs8.asn1
new file mode 100644
index ..702c41a3c713
--- /dev/null
+++ b/crypto/asymmetric_keys/pkcs8.asn1
@@ -0,0 +1,24 @@
+--
+-- This is the unencrypted variant
+--
+PrivateKeyInfo ::= SEQUENCE {
+   version Version,
+   privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
+   privateKey  PrivateKey,
+   attributes  [0] IMPLICIT Attributes OPTIONAL
+}
+
+Version ::= INTEGER  ({ pkcs8_note_version })
+
+PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier ({ pkcs8_note_algo })
+
+PrivateKey ::= OCTET STRING ({ pkcs8_note_key })
+
+Attributes ::= SET OF Attribute
+
+Attribute ::= ANY
+
+AlgorithmIdentifier ::= SEQUENCE {
+   algorithm   OBJECT IDENTIFIER ({ pkcs8_note_OID }),
+   parameters  ANY OPTIONAL
+}
diff --git a/crypto/asymmetric_keys/pkcs8_parser.c 
b/crypto/asymmetric_keys/pkcs8_parser.c
new file mode 100644
index ..26a73c0b7eef
--- /dev/null
+++ b/crypto/asymmetric_keys/pkcs8_parser.c
@@ -0,0 +1,184 @@
+/* PKCS#8 Private Key parser [RFC 5208].
+ *
+ * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowe...@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define pr_fmt(fmt) "PKCS8: "fmt
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "pkcs8-asn1.h"
+
+struct pkcs8_parse_context {
+   struct public_key *pub;
+   unsigned long   data;   /* Start of data */
+   enum OIDlast_oid;   /* Last OID encountered */
+   enum OIDalgo_oid;   /* Algorithm OID */
+ 

[RFC PATCH 7/8] KEYS: Implement encrypt, decrypt and sign for software asymmetric key [ver 3]

2016-05-11 Thread David Howells
Implement the encrypt, decrypt and sign operations for the software
asymmetric key subtype.  This mostly involves offloading the call to the
crypto layer.

Note that the decrypt and sign operations require a private key to be
supplied.  Encrypt (and also verify) will work with either a public or a
private key.  A public key can be supplied with an X.509 certificate and a
private key can be supplied using a PKCS#8 blob:

# j=`openssl pkcs8 -in ~/pkcs7/firmwarekey2.priv -topk8 -nocrypt 
-outform DER | keyctl padd asymmetric foo @s`
# keyctl pkey_query $j - enc=pkcs1
key_size=4096
max_data_size=512
max_sig_size=512
max_enc_size=512
max_dec_size=512
encrypt=y
decrypt=y
sign=y
verify=y
# keyctl pkey_encrypt $j 0 data enc=pkcs1 >/tmp/enc
# keyctl pkey_decrypt $j 0 /tmp/enc enc=pkcs1 >/tmp/dec
# cmp data /tmp/dec
# keyctl pkey_sign $j 0 data enc=pkcs1 hash=sha1 >/tmp/sig
# keyctl pkey_verify $j 0 data /tmp/sig enc=pkcs1 hash=sha1
#

Signed-off-by: David Howells <dhowe...@redhat.com>
---

 crypto/asymmetric_keys/public_key.c |   89 ++-
 1 file changed, 86 insertions(+), 3 deletions(-)

diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index 92997d4e8173..2bdb673cf074 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -128,7 +128,11 @@ static int software_key_query(const struct 
kernel_pkey_params *params,
info->max_sig_size = len;
info->max_enc_size = len;
info->max_dec_size = len;
-   info->supported_ops = KEYCTL_SUPPORTS_VERIFY;
+   info->supported_ops = (KEYCTL_SUPPORTS_ENCRYPT |
+  KEYCTL_SUPPORTS_VERIFY);
+   if (pkey->key_is_private)
+   info->supported_ops |= (KEYCTL_SUPPORTS_DECRYPT |
+   KEYCTL_SUPPORTS_SIGN);
ret = 0;
 
 error_free_tfm:
@@ -142,7 +146,7 @@ struct public_key_completion {
int err;
 };
 
-static void public_key_verify_done(struct crypto_async_request *req, int err)
+static void public_key_crypto_done(struct crypto_async_request *req, int err)
 {
struct public_key_completion *compl = req->data;
 
@@ -154,6 +158,84 @@ static void public_key_verify_done(struct 
crypto_async_request *req, int err)
 }
 
 /*
+ * Do encryption, decryption and signing ops.
+ */
+static int software_key_eds_op(struct kernel_pkey_params *params,
+  const void *in, void *out)
+{
+   struct public_key_completion compl;
+   const struct public_key *pkey = params->key->payload.data[asym_crypto];
+   struct akcipher_request *req;
+   struct crypto_akcipher *tfm;
+   struct scatterlist in_sg, out_sg;
+   char alg_name[CRYPTO_MAX_ALG_NAME];
+   int ret;
+
+   pr_devel("==>%s()\n", __func__);
+
+   ret = software_key_determine_akcipher(params->encoding,
+ params->hash_algo,
+ pkey, alg_name);
+   if (ret < 0)
+   return ret;
+
+   tfm = crypto_alloc_akcipher(alg_name, 0, 0);
+   if (IS_ERR(tfm))
+   return PTR_ERR(tfm);
+
+   req = akcipher_request_alloc(tfm, GFP_KERNEL);
+   if (!req)
+   goto error_free_tfm;
+
+   if (pkey->key_is_private)
+   ret = crypto_akcipher_set_priv_key(tfm,
+  pkey->key, pkey->keylen);
+   else
+   ret = crypto_akcipher_set_pub_key(tfm,
+ pkey->key, pkey->keylen);
+   if (ret)
+   goto error_free_req;
+
+   sg_init_one(_sg, in, params->in_len);
+   sg_init_one(_sg, out, params->out_len);
+   akcipher_request_set_crypt(req, _sg, _sg, params->in_len,
+  params->out_len);
+   init_completion();
+   akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
+ CRYPTO_TFM_REQ_MAY_SLEEP,
+ public_key_crypto_done, );
+
+   /* Perform the encryption calculation. */
+   switch (params->op) {
+   case kernel_pkey_encrypt:
+   ret = crypto_akcipher_encrypt(req);
+   break;
+   case kernel_pkey_decrypt:
+   ret = crypto_akcipher_decrypt(req);
+   break;
+   case kernel_pkey_sign:
+   ret = crypto_akcipher_sign(req);
+   break;
+   default:
+   BUG();
+   }
+   if (ret == -EINPROGRESS) {
+   wait_for_completion();
+   ret = compl.err;
+   }
+
+   if (ret == 0)
+   ret = req->dst_len;
+
+e

[RFC PATCH 0/8] KEYS: keyctl operations for asymmetric keys [ver 3]

2016-05-11 Thread David Howells

Here's a set of patches that provides keyctl access for asymmetric keys,
including a query function, and functions to do encryption, decryption,
signature creation and signature verification.

I've added a PKCS#8 asymmetric key parser so that you can load an RSA private
key into the kernel.  Currently only DER-encoded and unencrypted PKCS#8 is
supported.  Encryption and verification can use a public key from an X.509
cert, but signing and decryption require a private key, though encryption and
verification can use that too.

Example usage:

j=`openssl pkcs8 -in ~/pkcs7/firmwarekey2.priv -topk8 -nocrypt -outform 
DER | \
keyctl padd asymmetric foo @s`
echo -n abcdefghijklmnopqrst >/tmp/data
keyctl pkey_encrypt $j 0 /tmp/data enc=pkcs1 >/tmp/enc
keyctl pkey_decrypt $j 0 /tmp/enc enc=pkcs1 >/tmp/dec
cmp /tmp/data /tmp/dec
keyctl pkey_sign $j 0 /tmp/data enc=pkcs1 hash=sha1 >/tmp/sig
keyctl pkey_verify $j 0 /tmp/data /tmp/sig enc=pkcs1 hash=sha1

The kernel patches can be found here also:


http://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=keys-asym-keyctl

The keyutils changes needed can be found here:


http://git.kernel.org/cgit/linux/kernel/git/dhowells/keyutils.git/log/?h=pkey

David
---
David Howells (8):
  KEYS: Provide key type operations for asymmetric key ops
  KEYS: Provide keyctls to drive the new key type ops for asymmetric keys
  KEYS: Provide missing asymmetric key subops for new key type ops
  KEYS: Make the X.509 and PKCS7 parsers supply the sig encoding type
  KEYS: Provide software public key query function
  KEYS: Allow the public_key struct to hold a private key
  KEYS: Implement encrypt, decrypt and sign for software asymmetric key
  KEYS: Implement PKCS#8 RSA Private Key parser


 Documentation/crypto/asymmetric-keys.txt  |   33 ++-
 Documentation/security/keys.txt   |  224 +++
 crypto/asymmetric_keys/Kconfig|   10 +
 crypto/asymmetric_keys/Makefile   |   13 +
 crypto/asymmetric_keys/asymmetric_keys.h  |3 
 crypto/asymmetric_keys/asymmetric_type.c  |   60 +
 crypto/asymmetric_keys/pkcs7_parser.c |1 
 crypto/asymmetric_keys/pkcs7_trust.c  |2 
 crypto/asymmetric_keys/pkcs8.asn1 |   24 ++
 crypto/asymmetric_keys/pkcs8_parser.c |  184 
 crypto/asymmetric_keys/public_key.c   |  196 +++--
 crypto/asymmetric_keys/restrict.c |2 
 crypto/asymmetric_keys/signature.c|  112 ++
 crypto/asymmetric_keys/x509_cert_parser.c |   21 +-
 include/crypto/public_key.h   |   14 +
 include/keys/asymmetric-subtype.h |   10 +
 include/linux/key-type.h  |   11 +
 include/linux/keyctl.h|   47 
 include/uapi/linux/keyctl.h   |   31 +++
 security/integrity/digsig_asymmetric.c|2 
 security/keys/Makefile|1 
 security/keys/compat.c|   15 +
 security/keys/internal.h  |   39 +++
 security/keys/keyctl.c|   23 ++
 security/keys/keyctl_pkey.c   |  335 +
 25 files changed, 1364 insertions(+), 49 deletions(-)
 create mode 100644 crypto/asymmetric_keys/pkcs8.asn1
 create mode 100644 crypto/asymmetric_keys/pkcs8_parser.c
 create mode 100644 include/linux/keyctl.h
 create mode 100644 security/keys/keyctl_pkey.c

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: RSA/MPI handling issues and keyctl access to public key keyrings

2016-05-11 Thread David Howells
Tadeusz Struk  wrote:

> >  (2) rsa-pkcs1pad needs to indicate what the maximum content size is, given
> >  the minimum possible padding for the specified hash type (ie. a
> >  particular OID).
> 
> The user needs to use crypto_akcipher_maxsize(tfm) to get the required buffer
> size for a given key.
> We do check if the buffer if big enough to accommodate padding and hash info.
> This is needed in sign and encrypt operations, and in both cases we check it,
> sign:
> https://git.kernel.org/cgit/linux/kernel/git/herbert/cryptodev-2.6.git/tree/crypto/rsa-pkcs1pad.c#n434
> and encrypt:
> https://git.kernel.org/cgit/linux/kernel/git/herbert/cryptodev-2.6.git/tree/crypto/rsa-pkcs1pad.c#n252

Can you supply a way to find out the reduced size from the padding?

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] lib: asn1_decoder - add MODULE_LICENSE("GPL")

2016-05-11 Thread David Howells
Tudor Ambarus  wrote:

> A kernel taint results when loading the rsa_generic module:
> 
> root@(none):~# modprobe rsa_generic
> asn1_decoder: module license 'unspecified' taints kernel.
> Disabling lock debugging due to kernel taint
> 
> "Tainting" of the kernel is (usually) a way of indicating that
> a proprietary module has been inserted, which is not the case here.
> 
> Signed-off-by: Tudor Ambarus 

Applied.
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 2/5] KEYS: Provide keyctls to drive the new key type ops for asymmetric keys

2016-05-05 Thread David Howells
I've pushed a fix to #include  in keyctl_pkey.c into the git
tree.

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: v4.6-rc1 regression bisected, Problem loading in-kernel X.509 certificate (-2)

2016-05-04 Thread David Howells
Tadeusz Struk  wrote:

> I think the problem is that pkcs1pad template needs CRYPTO_MANAGER, but
> your configuration doesn't enable CRYPTO_MANAGER. Could you try this
> please:
> 
> diff --git a/crypto/Kconfig b/crypto/Kconfig
> index 93a1fdc..1d33beb 100644
> --- a/crypto/Kconfig
> +++ b/crypto/Kconfig
> @@ -96,6 +96,7 @@ config CRYPTO_AKCIPHER
>  config CRYPTO_RSA
>   tristate "RSA algorithm"
>   select CRYPTO_AKCIPHER
> + select CRYPTO_MANAGER
>   select MPILIB
>   select ASN1
>   help

Do you want to push this via Herbert's tree?

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: v4.6-rc1 regression bisected, Problem loading in-kernel X.509 certificate (-2)

2016-05-03 Thread David Howells
(cc'ing Tadeusz as he did the pkcs1 padding function)

Jamie Heilman  wrote:

> > > Problem loading in-kernel X.509 certificate (-2)
> > 
> > ENOENT?  Hmmm...  The only place that is generated is in the crypto layer.
> > That suggests missing crypto of some sort.
> > 
> > The attached patch enables some debugging in some relevant files if you can
> > try applying it to your kernel.
> 
> Alrighty, presumably relevant bits:
>
> X.509: Cert Issuer: Build time autogenerated kernel key
> X.509: Cert Subject: Build time autogenerated kernel key
> X.509: Cert Key Algo: rsa
> X.509: Cert Valid period: 1461826791-4615426791
> X.509: Cert Signature: rsa + sha512
> X.509: ==>x509_check_signature()
> X.509: ==>x509_get_sig_params()
> X.509: <==x509_get_sig_params() = 0
> PKEY: ==>public_key_verify_signature()
> X.509: Cert Verification: -2

Hmmm...  Okay, the only ways out of public_key_verify_signature() without
printing a leaving message are for snprintf() to overrun (which would return
error -22) or for crypto_alloc_akcipher() to have failed; everything else must
go through the kleave() at the pr_devel() at the bottom of the function.

Can you stick:

pr_devel("ALGO: %s\n", alg_name);

immediately before this line:

tfm = crypto_alloc_akcipher(alg_name, 0, 0);

and try it again?

Thanks,
David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: v4.6-rc1 regression bisected, Problem loading in-kernel X.509 certificate (-2)

2016-05-03 Thread David Howells
> Problem loading in-kernel X.509 certificate (-2)

ENOENT?  Hmmm...  The only place that is generated is in the crypto layer.
That suggests missing crypto of some sort.

The attached patch enables some debugging in some relevant files if you can
try applying it to your kernel.

David
---
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c 
b/crypto/asymmetric_keys/pkcs7_verify.c
index 50be2a15e531..573b3960867b 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -8,7 +8,7 @@
  * as published by the Free Software Foundation; either version
  * 2 of the Licence, or (at your option) any later version.
  */
-
+#define DEBUG
 #define pr_fmt(fmt) "PKCS7: "fmt
 #include 
 #include 
diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index 0f8b264b3961..99f297129381 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -10,7 +10,7 @@
  * as published by the Free Software Foundation; either version
  * 2 of the Licence, or (at your option) any later version.
  */
-
+#define DEBUG
 #define pr_fmt(fmt) "PKEY: "fmt
 #include 
 #include 
diff --git a/crypto/asymmetric_keys/x509_public_key.c 
b/crypto/asymmetric_keys/x509_public_key.c
index 733c046aacc6..373d472022ef 100644
--- a/crypto/asymmetric_keys/x509_public_key.c
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -8,7 +8,7 @@
  * as published by the Free Software Foundation; either version
  * 2 of the Licence, or (at your option) any later version.
  */
-
+#define DEBUG
 #define pr_fmt(fmt) "X.509: "fmt
 #include 
 #include 
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: v4.6-rc1 regression bisected, Problem loading in-kernel X.509 certificate (-2)

2016-05-03 Thread David Howells
Jamie Heilman  wrote:

> I usually build my kernels to require module signatures and use
> automatic signing.  As of v4.6-rc1 I'm getting this on boot:
> 
> Problem loading in-kernel X.509 certificate (-2)
> 
> I bisected that to commit d43de6c780a84def056afaf4fb3e66bdaa1efc00
> (akcipher: Move the RSA DER encoding check to the crypto layer)
> 
> For some reason after this commit my system keyring always ends up
> empty.  I use the deb-pkg make target.  My kernel config can
> be found at
> http://audible.transient.net/~jamie/k/modsign.config-4.6.0-rc5-guest

Do you have an example malfunctioning certificate that I can have a look at?

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH] KEYS: Provide keyctls to do public key operations [ver #2]

2016-04-16 Thread David Howells
Here's v2 of the patch with the reported errors fixed.  It's still untested by
me, however.

David
---
KEYS: Provide keyctls to do public key operations

From: David Howells <dhowe...@redhat.com>

Provide keyctl functions to do public key operations (sign, verify, encrypt
and decrypt) if the target key supports them, plus a query function to find
out about the key.

Not-yet-signed-off-by: David Howells <dhowe...@redhat.com>
---
 Documentation/security/keys.txt   |  105 +
 crypto/asymmetric_keys/pkcs7_parser.c |1 
 crypto/asymmetric_keys/public_key.c   |   38 +++
 crypto/asymmetric_keys/signature.c|  150 +
 crypto/asymmetric_keys/x509_cert_parser.c |   21 +-
 include/crypto/public_key.h   |   13 +
 include/keys/asymmetric-subtype.h |   13 +
 include/linux/keyctl.h|   36 +++
 include/uapi/linux/keyctl.h   |   27 ++
 security/keys/Makefile|1 
 security/keys/compat.c|   11 +
 security/keys/internal.h  |   35 +++
 security/keys/keyctl.c|   21 ++
 security/keys/keyctl_pkey.c   |  325 +
 14 files changed, 782 insertions(+), 15 deletions(-)
 create mode 100644 include/linux/keyctl.h
 create mode 100644 security/keys/keyctl_pkey.c

diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt
index 20d05719bceb..de90cdaa1a4e 100644
--- a/Documentation/security/keys.txt
+++ b/Documentation/security/keys.txt
@@ -854,6 +854,111 @@ The keyctl syscall functions are:
  supported, error ENOKEY if the key could not be found, or error
  EACCES if the key is not readable by the caller.
 
+
+ (*) Query an asymmetric key.
+
+   long keyctl(KEYCTL_PKEY_QUERY, key_serial_t key,
+   struct keyctl_pkey_query *info);
+
+ Get information about an asymmetric key.  The information is returned in
+ the keyctl_pkey_query struct:
+
+   __u32   supported_ops;
+
+ A bit mask of flags indicating which ops are supported.  This is
+ constructed from a bitwise-OR of:
+
+   KEYCTL_SUPPORTS_{ENCRYPT,DECRYPT,SIGN,VERIFY}
+
+   __u32   key_size;
+
+ The size in bits of the key.
+
+   __u16   max_data_size;
+   __u16   max_sig_size;
+   __u16   max_enc_size;
+   __u16   max_dec_size;
+
+ The maximum sizes in bytes of a blob of data to be signed, a signature
+ blob, a blob to be encrypted and a blob to be decypted.
+
+ If successful, 0 is returned.  If the key is not an asymmetric key,
+ EOPNOTSUPP is returned.
+
+
+ (*) Encrypt, decrypt, sign or verify a blob using an asymmetric key.
+
+   long keyctl(KEYCTL_PKEY_ENCRYPT,
+   const struct keyctl_pkey_params *params,
+   const char *info,
+   const void *data,
+   void *enc);
+
+   long keyctl(KEYCTL_PKEY_DECRYPT,
+   const struct keyctl_pkey_params *params,
+   const char *info,
+   const void *enc,
+   void *data);
+
+   long keyctl(KEYCTL_PKEY_SIGN,
+   const struct keyctl_pkey_params *params,
+   const char *info,
+   const void *data,
+   void *enc);
+
+   long keyctl(KEYCTL_PKEY_VERIFY,
+   const struct keyctl_pkey_params *params,
+   const char *info,
+   const void *data,
+   const void *enc);
+
+ Use an asymmetric key to perform a public-key cryptographic operation a
+ blob of data.  For encryption and verification, the asymmetric key may
+ only need the public parts to be available, but for decryption and signing
+ the private parts are required also.
+
+ The parameter block pointed to by params contains a number of integer
+ values:
+
+   __s32   key_id;
+   __s32   password_id;
+   __u32   data_len;
+   __u32   enc_len;
+
+ key_id is the ID of the asymmetric key to be used.  data_len indicates the
+ length of the data or buffer pointed to by data whilst enc_len indicates
+ the length of the data or buffer pointed to by enc.
+
+ If the key must be unlocked with a password before it can be used,
+ password_id should point to a logon-type key that holds this.
+
+ info is a string of key=value pairs that supply supplementary
+ information.  These include:
+
+   enc=  The encoding of the encrypted/signature blob.  This can
+   be "pkcs1" for RSASSA-PKCS1-v1.5 or RSAES-PKCS1-v1.5;
+   "pss" for "RSASSA-PSS"; "oaep" for "RSAES-OAEP".  If
+   omitted or is "raw", the raw output of the encryption
+   function is specified.
+
+   hash= If the da

Re: [RFC PATCH] KEYS: Provide keyctls to do public key operations

2016-04-16 Thread David Howells
Mat Martineau  wrote:

> > The interface for the active ops is a bit clunky as the syscall interface
> > doesn't provide sufficient argument space to pass everything I need to
> > specify.  Some basic integer arguments are specified in a struct and more
> > complex options through a string of key=val pairs - just so I don't have to
> > deal with the compat code for dealing with a struct containing pointers
> > (but I can change to that if it's preferable).
>
> It sounds like the struct would still have pointers to strings that would
> need parsing,

It doesn't:

struct keyctl_pkey_params {
__s32   key_id;
__s32   password_id;
__u32   data_len;
__u32   enc_len;
__u32   __spare[4];
};

because I have sufficient syscall arguments to pass four pointers - the struct
above, one info string and two buffer pointers.

> so I'm not sure it's that much overhead to handle the short
> strings of key=val pairs. But I'll agree that it feels clunky.

... fixes applied ...

> > +   info->supported_ops = KEYCTL_SUPPORTS_VERIFY;
> 
> Did you intend to include encrypt/decrypt/sign here?

When they're implemented there.

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH] KEYS: Provide keyctls to do public key operations

2016-04-15 Thread David Howells
Tadeusz Struk  wrote:

> > --- a/crypto/asymmetric_keys/signature.c
> > +++ b/crypto/asymmetric_keys/signature.c
> 
> Since this file implements the enc/dec operations also
> should it be renamed to crypto/asymmetric_keys/public_key_ops.c
> or something similar? signature.c is a bit confusing now.

Yes.  Or maybe accessors.c.  I'm also tempted to merge it into
asymmetric_type.c.  One question is how many other ops we might want to add.

It might even be worth making the functions key_encrypt_blob(),
key_decrypt_blob(), key_create_signature() and key_verify_signature() and
jumping through the type ops table.  I still haven't decided whether I want to
go to that extent yet as it leads to an extra function call on the stack.

> This will work perfectly for the algif_akcipher. Thanks for providing this.
> I'm going to rebase my patches on top of this and resend.

Note that this is a bit thrown together.  I'm travelling right now and
conferencing next week which is why I haven't managed to test it yet - so
beware, there may be dragons;-)

> Should I use your keys-next as a base for the new version?

That's the base I used.

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH] KEYS: Provide keyctls to do public key operations

2016-04-14 Thread David Howells
Here's a patch that does a first attempt at implementing keyctls for public
key operations using asymmetric-type keys.  This includes provision of a
query function.

[!] Note that whilst this patch compiles, it has not yet been tested.

I make the assumption that the asymmetric key type is the only one that
supports such things and call the asymmetric type accessor functions
directly rather than adding more key_type operations.  It would, however,
be cleaner to go through key_type ops - but would add an extra call into
the stack.

Encrypt, decrypt and sign ops could be combined with an argument to select
which op is desired.

The interface for the active ops is a bit clunky as the syscall interface
doesn't provide sufficient argument space to pass everything I need to
specify.  Some basic integer arguments are specified in a struct and more
complex options through a string of key=val pairs - just so I don't have to
deal with the compat code for dealing with a struct containing pointers
(but I can change to that if it's preferable).

I've specified data and enc buffer pointer for the keyctls, the order of
which are reversed for decrypt.  I'm tempted to change that to in and out
and just accept that for verify, out is actually an input.  I do not want
to pass data out for verify and then leave it to the caller to make the
comparison as I can't assume that hardware crypto will give me the computed
result of the verify crypto operation.

This patch really needs splitting into three: (1) internal op functions to
invoke the subtype (verify_signature() already exists in this set), (2) the
keyctl interface and (3) the software public key subtype methods.

I also have not yet implemented the hoop jumping in public_key.c to get the
software public key implementation to invoke the crypto layer to do the
missing three operations.

David
---
KEYS: Provide keyctls to do public key operations

Provide keyctl functions to do public key operations (sign, verify, encrypt
and decrypt) if the target key supports them, plus a query function to find
out about the key.

Not-yet-signed-off-by: David Howells <dhowe...@redhat.com>
---
 Documentation/security/keys.txt   |  105 +
 crypto/asymmetric_keys/pkcs7_parser.c |1 
 crypto/asymmetric_keys/public_key.c   |   38 +++
 crypto/asymmetric_keys/signature.c|  150 +
 crypto/asymmetric_keys/x509_cert_parser.c |   21 +-
 include/crypto/public_key.h   |   13 +
 include/keys/asymmetric-subtype.h |   13 +
 include/linux/keyctl.h|   36 +++
 include/uapi/linux/keyctl.h   |   27 ++
 security/keys/Makefile|1 
 security/keys/compat.c|   11 +
 security/keys/internal.h  |   35 +++
 security/keys/keyctl.c|   21 ++
 security/keys/keyctl_pkey.c   |  324 +
 14 files changed, 781 insertions(+), 15 deletions(-)
 create mode 100644 include/linux/keyctl.h
 create mode 100644 security/keys/keyctl_pkey.c

diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt
index 20d05719bceb..8a0dbf289631 100644
--- a/Documentation/security/keys.txt
+++ b/Documentation/security/keys.txt
@@ -854,6 +854,111 @@ The keyctl syscall functions are:
  supported, error ENOKEY if the key could not be found, or error
  EACCES if the key is not readable by the caller.
 
+
+ (*) Query an asymmetric key.
+
+   long keyctl(KEYCTL_PKEY_QUERY, key_serial_t key,
+   struct keyctl_pkey_query *info);
+
+ Get information about an asymmetric key.  The information is returned in
+ the keyctl_pkey_query struct:
+
+   __u32   supported_ops;
+
+ A bit mask of flags indicating which ops are supported.  This is
+ constructed from a bitwise-OR of:
+
+   KEYCTL_SUPPORTS_{ENCRYPT,DECRYPT,SIGN,VERIFY}
+
+   __u32   key_size;
+
+ The size in bits of the key.
+
+   __u16   max_data_size;
+   __u16   max_sig_size;
+   __u16   max_enc_size;
+   __u16   max_dec_size;
+
+ The maximum sizes in bytes of a blob of data to be signed, a signature
+ blob, a blob to be encrypted and a blob to be decypted.
+
+ If successful, 0 is returned.  If the key is not an asymmetric key,
+ EOPNOTSUPP is returned.
+
+
+ (*) Encrypt, decrypt, sign or verify a blob using an asymmetric key.
+
+   long keyctl(KEYCTL_PKEY_ENCRYPT,
+   const struct keyctl_pkey_params *params,
+   const char *info,
+   const void *data,
+   void *enc);
+
+   long keyctl(KEYCTL_PKEY_DECRYPT,
+   const struct keyctl_pkey_params *params,
+   const char *info,
+   const void *enc,
+   void *data);
+
+   long keyctl(KEYCTL_PKEY_SIGN,
+   const struct keyctl_pkey_params *params,
+   const char

Re: [PATCH v4 6/7] crypto: KEYS - add generic handlers to symmetric key type

2016-04-12 Thread David Howells
Tadeusz Struk  wrote:

> +/**
> + * asymmetric_key_verify_signature - invoke verify signature operation on a 
> key
> + *of the asymmetric subtype
> + * @key: key from the system keyring
> + * @sig: signature to verify
> + *
> + * return: 0 on success or errno on failure
> + */
> +int asymmetric_key_verify_signature(const struct key *key,
> + const struct public_key_signature *sig)

This is duplicating what's in signature.c in the same directory.

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] PKCS#7: fix missing break on OID_sha224 case

2016-04-06 Thread David Howells
Colin King <colin.k...@canonical.com> wrote:

> From: Colin Ian King <colin.k...@canonical.com>
> 
> The OID_sha224 case is missing a break and it falls through
> to the -ENOPKG error default.  Since HASH_ALGO_SHA224 seems
> to be supported, this looks like an unintentional missing break.
> 
> Fixes: 07f081fb5057 ("PKCS#7: Add OIDs for sha224, sha284 and sha512 hash 
> algos and use them")
> Cc: <sta...@vger.kernel.org> # 4.2+
> Signed-off-by: Colin Ian King <colin.k...@canonical.com>

Acked-by: David Howells <dhowe...@redhat.com>
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 7/7] crypto: AF_ALG - add support for key_id

2016-03-30 Thread David Howells
Tadeusz Struk  wrote:

> + keyring = request_key(_type_asymmetric, key_name, NULL);
> +
> + err = -ENOKEY;
> + if (IS_ERR(keyring))
> + goto out;
> +
> + pkey = keyring->payload.data[asym_crypto];

NAK.  This is liable to crash in future.  You may not assume that you know
what keyring->payload.data[asym_crypto] points to.

You may not use struct public_key outside of crypto/asymmetric_key/.  It's the
internal data of the software subtype.  I'll move it out of the global header
to remove the temptation;-).

You must use accessor functions such as verify_signature().  Feel free to add
further accessor functions such as query_asym_capabilities(),
create_signature(), encrypt_blob() and decrypt_blob() or something like that.

David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] security: integrity: Remove select to deleted option PUBLIC_KEY_ALGO_RSA

2016-03-07 Thread David Howells
Andreas Ziegler  wrote:

> Commit d43de6c780a8 ("akcipher: Move the RSA DER encoding check to
> the crypto layer") removed the Kconfig option PUBLIC_KEY_ALGO_RSA,
> but forgot to remove a 'select' to this option in the definition of
> INTEGRITY_ASYMMETRIC_KEYS.
> 
> Let's remove the select, as it's ineffective now.
> 
> Signed-off-by: Andreas Ziegler 

Applied.
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Left-over select to PUBLIC_KEY_ALGO_RSA

2016-03-04 Thread David Howells
Andreas Ziegler  wrote:

> As the corresponding option is gone, the select statement can safely be
> removed. Should I prepare a simple patch for that?

Please.

> I detected this by using scripts/checkkconfigsymbols on today's and
> yesterday's linux-next trees (i.e., "./scripts/checkkconfigsymbols.py -d
> next-20160303..next-20160304").

Interesting - I didn't realise that exists.  This sort of consistency check
should be run every time the Kconfig files are parsed.

Thanks,
David
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[GIT PULL] KEYS: Miscellaneous bits for security/next

2016-03-03 Thread David Howells
Hi James,

Could you pull this into security/next, please?

The most important patches here are the ones that deal with making the
asymmetric key software public key subtype use the akcipher crypto API for
the actual public key algorithm.

But there are also:

 (1) Allow space to be reserved for extra certificate insertion in the
 unsigned kernel image.

 (2) Allow modules to be signed with a raw signature.

 (3) Allow utilities to be built with LibreSSL instead of OpenSSL.

 (4) Fix X.509 time & date parsing.

 (5) Use text-based identifiers within the public key code instead of
 enums.
 
Plus other small fixes.

Thanks,
David
---
The following changes since commit 388f7b1d6e8ca06762e2454d28d6c3c55ad0fe95:

  Linux 4.5-rc3 (2016-02-07 15:38:30 -0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git 
tags/keys-next-20160303

for you to fetch changes up to 4e8ae72a75aae285ec5b93518b9680da198afd0d:

  X.509: Make algo identifiers text instead of enum (2016-03-03 21:49:27 +)


Keyrings changes for next


Arnd Bergmann (1):
  modsign: hide openssl output in silent builds

Codarren Velvindron (1):
  v2 linux-next scripts/sign-file.c Fix LibreSSL support

Colin Ian King (1):
  PKCS#7: fix unitialized boolean 'want'

David Howells (10):
  KEYS: Add an alloc flag to convey the builtinness of a key
  KEYS: CONFIG_KEYS_DEBUG_PROC_KEYS is no longer an option
  X.509: Fix leap year handling again
  Handle ISO 8601 leap seconds and encodings of midnight in mktime64()
  X.509: Support leap seconds
  X.509: Handle midnight alternative notation in GeneralizedTime
  certs: Fix misaligned data in extra certificate list
  MODSIGN: linux/string.h should be #included to get memcpy()
  akcipher: Move the RSA DER encoding check to the crypto layer
  X.509: Make algo identifiers text instead of enum

Juerg Haefliger (1):
  scripts/sign-file.c: Add support for signing with a raw signature

Marc-Antoine Perennou (1):
  sign-file: fix build with CMS support disabled

Mehmet Kayaalp (2):
  KEYS: Reserve an extra certificate symbol for inserting without 
recompiling
  KEYS: Use the symbol value for list size, updated by 
scripts/insert-sys-cert

Paul Gortmaker (1):
  security/keys: make big_key.c explicitly non-modular

Tadeusz Struk (4):
  crypto: KEYS: convert public key and digsig asym to the akcipher api
  integrity: convert digsig to akcipher api
  crypto: public_key: remove MPIs from public_key_signature struct
  crypto: Add hash param to pkcs1pad

 arch/arm/configs/colibri_pxa270_defconfig   |   1 -
 arch/arm/configs/iop13xx_defconfig  |   1 -
 arch/arm/configs/iop32x_defconfig   |   1 -
 arch/arm/configs/trizeps4_defconfig |   1 -
 arch/microblaze/configs/mmu_defconfig   |   1 -
 arch/microblaze/configs/nommu_defconfig |   1 -
 arch/mips/configs/bigsur_defconfig  |   1 -
 arch/mips/configs/ip22_defconfig|   1 -
 arch/mips/configs/ip27_defconfig|   1 -
 arch/mips/configs/ip32_defconfig|   1 -
 arch/mips/configs/jazz_defconfig|   1 -
 arch/mips/configs/lemote2f_defconfig|   1 -
 arch/mips/configs/rm200_defconfig   |   1 -
 arch/mips/configs/sb1250_swarm_defconfig|   1 -
 arch/parisc/configs/712_defconfig   |   1 -
 arch/parisc/configs/a500_defconfig  |   1 -
 arch/parisc/configs/default_defconfig   |   1 -
 arch/parisc/configs/generic-32bit_defconfig |   1 -
 arch/powerpc/configs/c2k_defconfig  |   1 -
 arch/powerpc/configs/ppc6xx_defconfig   |   1 -
 arch/score/configs/spct6600_defconfig   |   1 -
 arch/tile/configs/tilegx_defconfig  |   1 -
 arch/tile/configs/tilepro_defconfig |   1 -
 arch/x86/configs/i386_defconfig |   1 -
 arch/x86/configs/x86_64_defconfig   |   1 -
 certs/Kconfig   |  16 ++
 certs/Makefile  |  33 ++-
 certs/system_certificates.S |  13 +
 certs/system_keyring.c  |   4 +-
 crypto/asymmetric_keys/Kconfig  |   7 -
 crypto/asymmetric_keys/Makefile |   8 +-
 crypto/asymmetric_keys/mscode_parser.c  |  14 +-
 crypto/asymmetric_keys/pkcs7_parser.c   |  32 +--
 crypto/asymmetric_keys/pkcs7_trust.c|   2 +-
 crypto/asymmetric_keys/pkcs7_verify.c   |  10 +-
 crypto/asymmetric_keys/public_key.c | 154 +++
 crypto/asymmetric_keys/public_key.h |  36 ---
 crypto/asymmetric_keys/rsa.c| 278 ---
 crypto/asymmetric_keys/verify_pefile.c  |   4 +-
 crypto/asymmetric_keys/verify_pefile.h  |   2 +-
 crypto/asymmetric_keys/x509_cert_parser.c   |  75 ++---
 cr

Re: [PATCH] PKCS#7: fix unitialized boolean 'want'

2016-02-29 Thread David Howells
Colin King  wrote:

> The boolean want is not initialized and hence garbage. The default should
> be false (later it is only set to true on tne sinfo->authattrs check).
> 
> Found with static analysis using CoverityScan
> 
> Signed-off-by: Colin Ian King 

Applied.
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


  1   2   3   4   >