Re: [V4 PATCH 3/6] pci: Generic function for setting up PCI device DMA coherency

2015-05-20 Thread Catalin Marinas
On Wed, May 20, 2015 at 11:27:54AM +0200, Arnd Bergmann wrote:
 On Wednesday 20 May 2015 10:24:15 Catalin Marinas wrote:
  On Sat, May 16, 2015 at 01:59:00AM +0200, Rafael J. Wysocki wrote:
   On Friday, May 15, 2015 04:23:11 PM Suravee Suthikulpanit wrote:
+/**
+ * pci_dma_configure - Setup DMA configuration
+ * @pci_dev: ptr to pci_dev struct of the PCI device
+ *
+ * Function to update PCI devices's DMA configuration using the same
+ * info from the OF node or ACPI node of host bridge's parent (if any).
+ */
+static void pci_dma_configure(struct pci_dev *pci_dev)
+{
+   struct device *dev = pci_dev-dev;
+   struct device *bridge = pci_get_host_bridge_device(pci_dev);
+   struct device *host = bridge-parent;
+   struct acpi_device *adev;
+
+   if (!host)
+   return;
+
+   if (acpi_disabled) {
+   of_dma_configure(dev, host-of_node);
   
   I'd rather do
   
 if (IS_ENABLED(CONFIG_OF)  host-of_node) {
 of_dma_configure(dev, host-of_node);
  
  Nitpick: do we need the CONFIG_OF check? If disabled, I don't think
  anyone would set host-of_node.
 
 If of_dma_configure() is defined in a file that is built conditionally
 based on CONFIG_OF, you need it.

We have a dummy of_dma_configure() already when !CONFIG_OF, otherwise
we would need #ifndef here. I already replied, I think for other
architectures we need this check to avoid a useless host-of_node test.

-- 
Catalin
--
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 PATCH 2/6] arm64 : Introduce support for ACPI _CCA object

2015-05-20 Thread Suravee Suthikulanit

On 5/20/2015 5:03 AM, Catalin Marinas wrote:

On Fri, May 15, 2015 at 04:23:10PM -0500, Suravee Suthikulpanit wrote:

 From http://www.uefi.org/sites/default/files/resources/ACPI_6.0.pdf,
section 6.2.17 _CCA states that ARM platforms require ACPI _CCA
object to be specified for DMA-cabpable devices. This patch introduces
ACPI_MUST_HAVE_CCA in arm64 Kconfig to specify such requirement.

In case _CCA is missing, arm64 would assign dummy_dma_ops
to disable DMA capability of the device.

Signed-off-by: Mark Salter msal...@redhat.com
Signed-off-by: Suravee Suthikulpanit suravee.suthikulpa...@amd.com
CC: Catalin Marinas catalin.mari...@arm.com
CC: Will Deacon will.dea...@arm.com
CC: Arnd Bergmann a...@arndb.de


Acked-by: Catalin Marinas catalin.mari...@arm.com



Thanks,

Suravee

--
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: [Linaro-acpi] [V4 PATCH 1/6] ACPI / scan: Parse _CCA and setup device coherency

2015-05-20 Thread Arnd Bergmann
On Wednesday 20 May 2015 06:52:03 Suravee Suthikulanit wrote:
 On 5/20/2015 5:01 AM, Catalin Marinas wrote:
  On Fri, May 15, 2015 at 04:23:09PM -0500, Suravee Suthikulpanit wrote:
  +static inline bool acpi_dma_is_supported(struct acpi_device *adev)
  +{
  +/**
  + * Currently, we mainly support _CCA=1 (i.e. is_coherent=1)
  + * This should be equivalent to specifyig dma-coherent for
  + * a device in OF.
  + *
  + * For the case when _CCA=0 (i.e. is_coherent=0  cca_seen=1),
  + * There are two approaches:
  + * 1. Do not support and disable DMA.
  + * 2. Support but rely on arch-specific cache maintenance for
  + * non-coherence DMA operations. ARM64 is one example.
  + *
  + * For the case when _CCA is missing (i.e. cca_seen=0) but
  + * platform specifies ACPI_CCA_REQUIRED, we do not support DMA,
  + * and fallback to arch-specific default handling.
  + *
  + * See acpi_init_coherency() for more info.
  + */
  +return adev  (adev-flags.is_coherent ||
  +(adev-flags.cca_seen  IS_ENABLED(CONFIG_ARM64)));
  +}
 
  I don't particularly like the check for CONFIG_ARM64 here but I
  understand why it was added (I had the wrong impression that x86 can
  cope with _CCA = 0).
 
  Alternatively, we could leave it out (together with cca_seen) until
  someone comes forward with a real use-case for _CCA = 0 on arm64. One
  platform I'm aware of is Juno but even though it boot with ACPI, I
  wouldn't call it a server platform.
 
 Ok. That seems to be what Arnd would prefer as well.  Let's just leave 
 the support for _CCA=0 out until it is needed then.
 

Yes, that would be best (as I said repeatedly ;-) )

Arnd
--
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 PATCH 1/6] ACPI / scan: Parse _CCA and setup device coherency

2015-05-20 Thread Catalin Marinas
On Fri, May 15, 2015 at 04:23:09PM -0500, Suravee Suthikulpanit wrote:
 +static inline bool acpi_dma_is_supported(struct acpi_device *adev)
 +{
 + /**
 +  * Currently, we mainly support _CCA=1 (i.e. is_coherent=1)
 +  * This should be equivalent to specifyig dma-coherent for
 +  * a device in OF.
 +  *
 +  * For the case when _CCA=0 (i.e. is_coherent=0  cca_seen=1),
 +  * There are two approaches:
 +  * 1. Do not support and disable DMA.
 +  * 2. Support but rely on arch-specific cache maintenance for
 +  * non-coherence DMA operations. ARM64 is one example.
 +  *
 +  * For the case when _CCA is missing (i.e. cca_seen=0) but
 +  * platform specifies ACPI_CCA_REQUIRED, we do not support DMA,
 +  * and fallback to arch-specific default handling.
 +  *
 +  * See acpi_init_coherency() for more info.
 +  */
 + return adev  (adev-flags.is_coherent ||
 + (adev-flags.cca_seen  IS_ENABLED(CONFIG_ARM64)));
 +}

I don't particularly like the check for CONFIG_ARM64 here but I
understand why it was added (I had the wrong impression that x86 can
cope with _CCA = 0).

Alternatively, we could leave it out (together with cca_seen) until
someone comes forward with a real use-case for _CCA = 0 on arm64. One
platform I'm aware of is Juno but even though it boot with ACPI, I
wouldn't call it a server platform.

-- 
Catalin
--
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] crypto: allow to assign gfp_t for __crypto_alloc_tfm

2015-05-20 Thread Ard Biesheuvel
On 20 May 2015 at 16:59, Theodore Ts'o ty...@mit.edu wrote:
 On Wed, May 20, 2015 at 09:21:20AM +0200, Steffen Klassert wrote:
 The current pcrypt version is used just for IPsec because it supports
 only AEAD type algorithms and does not support request backlog. But
 I have patches to support ablkcipher algorithms and request backlog.
 I could provide them if there is interest in it.

 I don't know the crypto layer well enough, and I certainly don't know
 how to deal with things like ARM CPU's with big-little architectures
 to understand what we might need to do to power optimize things for
 mobile handsets.  But if someone has time to look at this, that would
 be great.


I'd be interested in getting involved: I'm fairly intimate with the
crypto layer and the ARM/arm64 architectures, since I wrote a big
chunk of the ARM/arm64 CPU based crypto drivers.

However, it's quite a can of worms you're opening here. Speed is
easily quantified, and it may even be feasible to introduce some kind
of boottime benchmark to select the fastest implementation available
(like already exists for xor and raid6, for instance).
@Herbert: was something like this ever proposed? And would you
consider merging it if it were implemented adequately?

Power efficiency is *much* harder, since you're not only dealing with
big.LITTLE, but also NEON versus ALU (i.e., SIMD math versus integer
math) and CPU versus hw accelerator based crypto. (We have the NEON
based bit sliced AES as an example: we know it does fundamentally more
work by calculating values that the table based AES implementation
reads from a lookup table, so while it is a lot faster on most NEON
implementations, it is most likely not as power efficient) Even if it
were possible to quantify the power efficiency in the first place,
whether the most power efficient implementation should be preferred
over the fastest one is a policy decision which does not really belong
inside the kernel.

Are there any background materials or other references you can share
that shed a bit more light on this?
--
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] crypto: allow to assign gfp_t for __crypto_alloc_tfm

2015-05-20 Thread Herbert Xu
On Wed, May 20, 2015 at 05:30:14PM +0200, Ard Biesheuvel wrote:
 
 However, it's quite a can of worms you're opening here. Speed is
 easily quantified, and it may even be feasible to introduce some kind
 of boottime benchmark to select the fastest implementation available
 (like already exists for xor and raid6, for instance).
 @Herbert: was something like this ever proposed? And would you
 consider merging it if it were implemented adequately?

Up until now static priorities have been sufficient in selecting
the best implementation.  However, if you can show us a case where
a given implementation is slower on one host but faster on another
then sure we can add a run-time test and priority adjustment for it.

Cheers,
-- 
Email: Herbert Xu herb...@gondor.apana.org.au
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
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] random: add random_initialized command line param

2015-05-20 Thread Stephan Mueller
Am Mittwoch, 20. Mai 2015, 11:06:42 schrieb Theodore Ts'o:

Hi Theodore,

As a side note to this discussion, may I ask why entropy_total is used for 
checking against the threshold value and not entropy_count?

The reason for my question is the following: until a DRNG (in the worst case, 
nonblocking_pool is a DRNG) is fully seeded, partial seeds may be eaten up 
by the caller.

For the discussion, let us assume the worst case that there is coming in one 
bit of entropy at a time. In between the addition of each bit of entropy, an 
attacker can access the DRNG (i.e. the SHA1 output of the nonblocking_pool). 
When only one bit of entropy is added to the nonblocking_pool, the attack 
complexity would be 1 bit. When an attacker would access the nonblocking_pool 
after each received bit, in the worst case, the attack complexity is not 
2**128 but rather 256 (i.e. 1 bit for each individual attack between the 
addition of one new bit of entropy).

So, the total attack complexity is the sum of the individual attack 
complexities (i.e. the complexity added after the previous attack is 
performed).

When using the entropy_count variable which is affected by account() (i.e. it 
is decreased when a reader obtains data), the threshold is only reached when 
truly 128 unobserved bits are collected.

Ciao
Stephan
--
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 v9 4/5] crypto: drbg - use Jitter RNG to obtain seed

2015-05-20 Thread Stephan Mueller
During initialization, the DRBG now tries to allocate a handle of the
Jitter RNG. If such a Jitter RNG is available during seeding, the DRBG
pulls the required entropy/nonce string from get_random_bytes and
concatenates it with a string of equal size from the Jitter RNG. That
combined string is now the seed for the DRBG.

Written differently, the initial seed of the DRBG is now:

get_random_bytes(entropy/nonce) || jitterentropy (entropy/nonce)

If the Jitter RNG is not available, the DRBG only seeds from
get_random_bytes.

CC: Andreas Steffen andreas.stef...@strongswan.org
CC: Theodore Ts'o ty...@mit.edu
CC: Sandy Harris sandyinch...@gmail.com
Signed-off-by: Stephan Mueller smuel...@chronox.de
---
 crypto/drbg.c | 51 ---
 include/crypto/drbg.h |  1 +
 2 files changed, 45 insertions(+), 7 deletions(-)

diff --git a/crypto/drbg.c b/crypto/drbg.c
index 563e5e9..e9fd60d 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -1072,7 +1072,11 @@ static void drbg_async_seed(struct work_struct *work)
drbg_string_fill(data, drbg-seed_buf, drbg-seed_buf_len);
list_add_tail(data.list, seedlist);
mutex_lock(drbg-drbg_mutex);
-   __drbg_seed(drbg, seedlist, true);
+   ret = __drbg_seed(drbg, seedlist, true);
+   if (!ret  drbg-jent) {
+   crypto_free_rng(drbg-jent);
+   drbg-jent = NULL;
+   }
memzero_explicit(drbg-seed_buf, drbg-seed_buf_len);
mutex_unlock(drbg-drbg_mutex);
 }
@@ -1107,10 +,24 @@ static int drbg_seed(struct drbg_state *drbg, struct 
drbg_string *pers,
 drbg-test_data.len);
pr_devel(DRBG: using test entropy\n);
} else {
-   pr_devel(DRBG: (re)seeding with %zu bytes of entropy\n,
-drbg-seed_buf_len);
+   /* Get seed from in-kernel /dev/urandom */
get_random_bytes(drbg-seed_buf, drbg-seed_buf_len);
-   drbg_string_fill(data1, drbg-seed_buf, drbg-seed_buf_len);
+
+   /* Get seed from Jitter RNG */
+   if (!drbg-jent ||
+   crypto_rng_get_bytes(drbg-jent,
+drbg-seed_buf + drbg-seed_buf_len,
+drbg-seed_buf_len)) {
+   drbg_string_fill(data1, drbg-seed_buf,
+drbg-seed_buf_len);
+   pr_devel(DRBG: (re)seeding with %zu bytes of 
entropy\n,
+drbg-seed_buf_len);
+   } else {
+   drbg_string_fill(data1, drbg-seed_buf,
+drbg-seed_buf_len * 2);
+   pr_devel(DRBG: (re)seeding with %zu bytes of 
entropy\n,
+drbg-seed_buf_len * 2);
+   }
}
list_add_tail(data1.list, seedlist);
 
@@ -1135,7 +1153,7 @@ static int drbg_seed(struct drbg_state *drbg, struct 
drbg_string *pers,
 * Clear the initial entropy buffer as the async call may not overwrite
 * that buffer for quite some time.
 */
-   memzero_explicit(drbg-seed_buf, drbg-seed_buf_len);
+   memzero_explicit(drbg-seed_buf, drbg-seed_buf_len * 2);
if (ret)
goto out;
/*
@@ -1175,6 +1193,10 @@ static inline void drbg_dealloc_state(struct drbg_state 
*drbg)
 #endif
kzfree(drbg-seed_buf);
drbg-seed_buf = NULL;
+   if (drbg-jent) {
+   crypto_free_rng(drbg-jent);
+   drbg-jent = NULL;
+   }
 }
 
 /*
@@ -1250,14 +1272,29 @@ static inline int drbg_alloc_state(struct drbg_state 
*drbg)
ret = -EFAULT;
goto err;
}
-   /* ensure we have sufficient buffer space for initial seed */
+   /*
+* Ensure we have sufficient buffer space for initial seed which
+* consists of the seed from get_random_bytes and the Jitter RNG.
+*/
drbg-seed_buf_len = ((drbg-seed_buf_len + 1) / 2) * 3;
-   drbg-seed_buf = kzalloc(drbg-seed_buf_len, GFP_KERNEL);
+   drbg-seed_buf = kzalloc(drbg-seed_buf_len * 2, GFP_KERNEL);
if (!drbg-seed_buf)
goto err;
 
INIT_WORK(drbg-seed_work, drbg_async_seed);
 
+   drbg-jent = crypto_alloc_rng(jitterentropy_rng, 0, 0);
+   if(IS_ERR(drbg-jent))
+   {
+   pr_info(DRBG: could not allocate Jitter RNG handle for 
seeding\n);
+   /*
+* As the Jitter RNG is a module that may not be present, we
+* continue with the operation and do not fully tie the DRBG
+* to the Jitter RNG.
+*/
+   drbg-jent = NULL;
+   }
+
return 0;
 
 err:
diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
index 46994b2..c3f208d 100644
--- a/include/crypto/drbg.h
+++ b/include/crypto/drbg.h
@@ -123,6 +123,7 @@ 

[PATCH v9 3/5] crypto: drbg - add async seeding operation

2015-05-20 Thread Stephan Mueller
The async seeding operation is triggered during initalization right
after the first non-blocking seeding is completed. As required by the
asynchronous operation of random.c, a callback function is provided that
is triggered by random.c once entropy is available. That callback
function performs the actual seeding of the DRBG.

CC: Andreas Steffen andreas.stef...@strongswan.org
CC: Theodore Ts'o ty...@mit.edu
CC: Sandy Harris sandyinch...@gmail.com
Signed-off-by: Stephan Mueller smuel...@chronox.de
---
 crypto/drbg.c | 28 
 include/crypto/drbg.h |  2 ++
 2 files changed, 30 insertions(+)

diff --git a/crypto/drbg.c b/crypto/drbg.c
index 36dfece..563e5e9 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -1056,6 +1056,27 @@ static inline int __drbg_seed(struct drbg_state *drbg, 
struct list_head *seed,
return ret;
 }
 
+static void drbg_async_seed(struct work_struct *work)
+{
+   struct drbg_string data;
+   LIST_HEAD(seedlist);
+   struct drbg_state *drbg = container_of(work, struct drbg_state,
+  seed_work);
+   int ret;
+
+   do {
+   ret = get_blocking_random_bytes(drbg-seed_buf,
+   drbg-seed_buf_len);
+   } while (ret == -ERESTARTSYS);
+
+   drbg_string_fill(data, drbg-seed_buf, drbg-seed_buf_len);
+   list_add_tail(data.list, seedlist);
+   mutex_lock(drbg-drbg_mutex);
+   __drbg_seed(drbg, seedlist, true);
+   memzero_explicit(drbg-seed_buf, drbg-seed_buf_len);
+   mutex_unlock(drbg-drbg_mutex);
+}
+
 /*
  * Seeding or reseeding of the DRBG
  *
@@ -1125,6 +1146,10 @@ static int drbg_seed(struct drbg_state *drbg, struct 
drbg_string *pers,
if (!reseed)
drbg-seed_buf_len = drbg-seed_buf_len / 3 * 2;
 
+   /* Invoke asynchronous seeding unless DRBG is in test mode. */
+   if (!list_empty(drbg-test_data.list)  !reseed)
+   schedule_work(drbg-seed_work);
+
 out:
return ret;
 }
@@ -1231,6 +1256,8 @@ static inline int drbg_alloc_state(struct drbg_state 
*drbg)
if (!drbg-seed_buf)
goto err;
 
+   INIT_WORK(drbg-seed_work, drbg_async_seed);
+
return 0;
 
 err:
@@ -1487,6 +1514,7 @@ unlock:
  */
 static int drbg_uninstantiate(struct drbg_state *drbg)
 {
+   cancel_work_sync(drbg-seed_work);
if (drbg-d_ops)
drbg-d_ops-crypto_fini(drbg);
drbg_dealloc_state(drbg);
diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
index b052698..46994b2 100644
--- a/include/crypto/drbg.h
+++ b/include/crypto/drbg.h
@@ -51,6 +51,7 @@
 #include linux/fips.h
 #include linux/mutex.h
 #include linux/list.h
+#include linux/workqueue.h
 
 /*
  * Concatenation Helper and string operation helper
@@ -119,6 +120,7 @@ struct drbg_state {
bool fips_primed;   /* Continuous test primed? */
unsigned char *prev;/* FIPS 140-2 continuous test value */
 #endif
+   struct work_struct seed_work;   /* asynchronous seeding support */
u8 *seed_buf;   /* buffer holding the seed */
size_t seed_buf_len;
const struct drbg_state_ops *d_ops;
-- 
2.1.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 v9 2/5] crypto: drbg - prepare for async seeding

2015-05-20 Thread Stephan Mueller
In order to prepare for the addition of the asynchronous seeding call,
the invocation of seeding the DRBG is moved out into a helper function.

In addition, a block of memory is allocated during initialization time
that will be used as a scratchpad for obtaining entropy. That scratchpad
is used for the initial seeding operation as well as by the
asynchronous seeding call. The memory must be zeroized every time the
DRBG seeding call succeeds to avoid entropy data lingering in memory.

CC: Andreas Steffen andreas.stef...@strongswan.org
CC: Theodore Ts'o ty...@mit.edu
CC: Sandy Harris sandyinch...@gmail.com
Signed-off-by: Stephan Mueller smuel...@chronox.de
---
 crypto/drbg.c | 81 ++-
 include/crypto/drbg.h |  2 ++
 2 files changed, 56 insertions(+), 27 deletions(-)

diff --git a/crypto/drbg.c b/crypto/drbg.c
index 23d444e..36dfece 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -1041,6 +1041,21 @@ static struct drbg_state_ops drbg_hash_ops = {
  * Functions common for DRBG implementations
  **/
 
+static inline int __drbg_seed(struct drbg_state *drbg, struct list_head *seed,
+ int reseed)
+{
+   int ret = drbg-d_ops-update(drbg, seed, reseed);
+
+   if (ret)
+   return ret;
+
+   drbg-seeded = true;
+   /* 10.1.1.2 / 10.1.1.3 step 5 */
+   drbg-reseed_ctr = 1;
+
+   return ret;
+}
+
 /*
  * Seeding or reseeding of the DRBG
  *
@@ -1056,8 +1071,6 @@ static int drbg_seed(struct drbg_state *drbg, struct 
drbg_string *pers,
 bool reseed)
 {
int ret = 0;
-   unsigned char *entropy = NULL;
-   size_t entropylen = 0;
struct drbg_string data1;
LIST_HEAD(seedlist);
 
@@ -1073,26 +1086,10 @@ static int drbg_seed(struct drbg_state *drbg, struct 
drbg_string *pers,
 drbg-test_data.len);
pr_devel(DRBG: using test entropy\n);
} else {
-   /*
-* Gather entropy equal to the security strength of the DRBG.
-* With a derivation function, a nonce is required in addition
-* to the entropy. A nonce must be at least 1/2 of the security
-* strength of the DRBG in size. Thus, entropy * nonce is 3/2
-* of the strength. The consideration of a nonce is only
-* applicable during initial seeding.
-*/
-   entropylen = drbg_sec_strength(drbg-core-flags);
-   if (!entropylen)
-   return -EFAULT;
-   if (!reseed)
-   entropylen = ((entropylen + 1) / 2) * 3;
pr_devel(DRBG: (re)seeding with %zu bytes of entropy\n,
-entropylen);
-   entropy = kzalloc(entropylen, GFP_KERNEL);
-   if (!entropy)
-   return -ENOMEM;
-   get_random_bytes(entropy, entropylen);
-   drbg_string_fill(data1, entropy, entropylen);
+drbg-seed_buf_len);
+   get_random_bytes(drbg-seed_buf, drbg-seed_buf_len);
+   drbg_string_fill(data1, drbg-seed_buf, drbg-seed_buf_len);
}
list_add_tail(data1.list, seedlist);
 
@@ -,16 +1108,24 @@ static int drbg_seed(struct drbg_state *drbg, struct 
drbg_string *pers,
memset(drbg-C, 0, drbg_statelen(drbg));
}
 
-   ret = drbg-d_ops-update(drbg, seedlist, reseed);
+   ret = __drbg_seed(drbg, seedlist, reseed);
+
+   /*
+* Clear the initial entropy buffer as the async call may not overwrite
+* that buffer for quite some time.
+*/
+   memzero_explicit(drbg-seed_buf, drbg-seed_buf_len);
if (ret)
goto out;
-
-   drbg-seeded = true;
-   /* 10.1.1.2 / 10.1.1.3 step 5 */
-   drbg-reseed_ctr = 1;
+   /*
+* For all subsequent seeding calls, we only need the seed buffer
+* equal to the security strength of the DRBG. We undo the calculation
+* in drbg_alloc_state.
+*/
+   if (!reseed)
+   drbg-seed_buf_len = drbg-seed_buf_len / 3 * 2;
 
 out:
-   kzfree(entropy);
return ret;
 }
 
@@ -1143,6 +1148,8 @@ static inline void drbg_dealloc_state(struct drbg_state 
*drbg)
drbg-prev = NULL;
drbg-fips_primed = false;
 #endif
+   kzfree(drbg-seed_buf);
+   drbg-seed_buf = NULL;
 }
 
 /*
@@ -1204,6 +1211,26 @@ static inline int drbg_alloc_state(struct drbg_state 
*drbg)
if (!drbg-scratchpad)
goto err;
}
+
+   /*
+* Gather entropy equal to the security strength of the DRBG.
+* With a derivation function, a nonce is required in addition
+* to the entropy. A nonce must be at least 1/2 of the security
+* strength of the DRBG in size. Thus, 

[PATCH v9 1/5] random: Blocking API for accessing nonblocking_pool

2015-05-20 Thread Stephan Mueller
The added API calls provide a synchronous function call
get_blocking_random_bytes where the caller is blocked until
the nonblocking_pool is initialized.

CC: Andreas Steffen andreas.stef...@strongswan.org
CC: Theodore Ts'o ty...@mit.edu
CC: Sandy Harris sandyinch...@gmail.com
Signed-off-by: Stephan Mueller smuel...@chronox.de
---
 drivers/char/random.c  | 20 
 include/linux/random.h |  1 +
 2 files changed, 21 insertions(+)

diff --git a/drivers/char/random.c b/drivers/char/random.c
index 9cd6968..9815a26 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1245,6 +1245,26 @@ void get_random_bytes(void *buf, int nbytes)
 EXPORT_SYMBOL(get_random_bytes);
 
 /*
+ * Equivalent function to get_random_bytes with the difference that this
+ * function blocks the request until the nonblocking_pool is initialized.
+ */
+int get_blocking_random_bytes(void *buf, int nbytes)
+{
+   int rc = 0;
+
+   if (unlikely(nonblocking_pool.initialized == 0))
+   rc = wait_event_interruptible(urandom_init_wait,
+ nonblocking_pool.initialized);
+   if (rc)
+   return rc;
+
+   extract_entropy(nonblocking_pool, buf, nbytes, 0, 0);
+
+   return 0;
+}
+EXPORT_SYMBOL(get_blocking_random_bytes);
+
+/*
  * This function will use the architecture-specific hardware random
  * number generator if it is available.  The arch-specific hw RNG will
  * almost certainly be faster than what we can do in software, but it
diff --git a/include/linux/random.h b/include/linux/random.h
index b05856e..7d0d72f 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -14,6 +14,7 @@ extern void add_input_randomness(unsigned int type, unsigned 
int code,
 extern void add_interrupt_randomness(int irq, int irq_flags);
 
 extern void get_random_bytes(void *buf, int nbytes);
+extern int get_blocking_random_bytes(void *buf, int nbytes);
 extern void get_random_bytes_arch(void *buf, int nbytes);
 void generate_random_uuid(unsigned char uuid_out[16]);
 extern int random_int_secret_init(void);
-- 
2.1.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


Re: [V4 PATCH 3/6] pci: Generic function for setting up PCI device DMA coherency

2015-05-20 Thread Russell King - ARM Linux
On Wed, May 20, 2015 at 07:00:25AM -0500, Suravee Suthikulanit wrote:
 On 5/20/2015 4:34 AM, Catalin Marinas wrote:
 We have a dummy of_dma_configure() already when !CONFIG_OF, otherwise
 we would need #ifndef here. I already replied, I think for other
 architectures we need this check to avoid a useless host-of_node test.
 
 It seems that there are several places that have similar check. Would it be
 good to convert this into a macro? Something like:
 
 #define OF_NODE_ENABLED(dev)  (IS_ENABLED(CONFIG_OF)  dev-of_node)

This /could/ be a useful compile-time optimisation: when CONFIG_OF is
disabled, dev-of_node exists but will always be NULL - but the
compiler doesn't know this.  Your suggestion above would tell the
compiler that when CONFIG_OF is disabled, OF_NODE_ENABLED() will
evaluate to a constant false, which means it can eliminate code.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.
--
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 v9 3/5] crypto: drbg - add async seeding operation

2015-05-20 Thread Herbert Xu
On Wed, May 20, 2015 at 10:03:45PM +0200, Stephan Mueller wrote:
 @@ -1487,6 +1514,7 @@ unlock:
   */
  static int drbg_uninstantiate(struct drbg_state *drbg)
  {
 + cancel_work_sync(drbg-seed_work);

This will just block until the work is done, i.e., until the
pool is ready.  It's no different to an uninterruptible sleep.

So either just do an uninterruptible sleep, or allow the async
seed to fail.

Cheers,
-- 
Email: Herbert Xu herb...@gondor.apana.org.au
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
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 PATCH 4/6] device property: Introduces device_dma_is_coherent()

2015-05-20 Thread Suravee Suthikulanit

On 5/20/2015 5:28 AM, Will Deacon wrote:

On Fri, May 15, 2015 at 10:23:12PM +0100, Suravee Suthikulpanit wrote:

Currently, device drivers, which support both OF and ACPI,
need to call two separate APIs, of_dma_is_coherent() and
acpi_dma_is_coherent()) to determine device coherency attribute.

This patch simplifies this process by introducing a new device
property API, device_dma_is_coherent(), which calls the appropriate
interface based on the booting architecture.

Signed-off-by: Suravee Suthikulpanit suravee.suthikulpa...@amd.com
CC: Rafael J. Wysocki r...@rjwysocki.net
---
  drivers/base/property.c  | 12 
  include/linux/property.h |  2 ++
  2 files changed, 14 insertions(+)

diff --git a/drivers/base/property.c b/drivers/base/property.c
index 1d0b116..8123c6e 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -14,6 +14,7 @@
  #include linux/export.h
  #include linux/kernel.h
  #include linux/of.h
+#include linux/of_address.h
  #include linux/property.h

  /**
@@ -519,3 +520,14 @@ unsigned int device_get_child_node_count(struct device 
*dev)
return count;
  }
  EXPORT_SYMBOL_GPL(device_get_child_node_count);
+
+bool device_dma_is_coherent(struct device *dev)
+{
+   if (IS_ENABLED(CONFIG_OF)  dev-of_node)
+   return of_dma_is_coherent(dev-of_node);
+   else if (has_acpi_companion(dev))
+   return acpi_dma_is_coherent(acpi_node(dev-fwnode));


I don't think you need the has_acpi_companion check, as acpi_node handles
this and acpi_dma_is_coherent(NULL) returns false.

Will


You are right.

Thanks,

Suravee

--
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 v7 2/5] crypto: drbg - prepare for async seeding

2015-05-20 Thread Stephan Mueller
In order to prepare for the addition of the asynchronous seeding call,
the invocation of seeding the DRBG is moved out into a helper function.

In addition, a block of memory is allocated during initialization time
that will be used as a scratchpad for obtaining entropy. That scratchpad
is used for the initial seeding operation as well as by the
asynchronous seeding call. The memory must be zeroized every time the
DRBG seeding call succeeds to avoid entropy data lingering in memory.

CC: Andreas Steffen andreas.stef...@strongswan.org
CC: Theodore Ts'o ty...@mit.edu
CC: Sandy Harris sandyinch...@gmail.com
Signed-off-by: Stephan Mueller smuel...@chronox.de
---
 crypto/drbg.c | 81 ++-
 include/crypto/drbg.h |  2 ++
 2 files changed, 56 insertions(+), 27 deletions(-)

diff --git a/crypto/drbg.c b/crypto/drbg.c
index 23d444e..36dfece 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -1041,6 +1041,21 @@ static struct drbg_state_ops drbg_hash_ops = {
  * Functions common for DRBG implementations
  **/
 
+static inline int __drbg_seed(struct drbg_state *drbg, struct list_head *seed,
+ int reseed)
+{
+   int ret = drbg-d_ops-update(drbg, seed, reseed);
+
+   if (ret)
+   return ret;
+
+   drbg-seeded = true;
+   /* 10.1.1.2 / 10.1.1.3 step 5 */
+   drbg-reseed_ctr = 1;
+
+   return ret;
+}
+
 /*
  * Seeding or reseeding of the DRBG
  *
@@ -1056,8 +1071,6 @@ static int drbg_seed(struct drbg_state *drbg, struct 
drbg_string *pers,
 bool reseed)
 {
int ret = 0;
-   unsigned char *entropy = NULL;
-   size_t entropylen = 0;
struct drbg_string data1;
LIST_HEAD(seedlist);
 
@@ -1073,26 +1086,10 @@ static int drbg_seed(struct drbg_state *drbg, struct 
drbg_string *pers,
 drbg-test_data.len);
pr_devel(DRBG: using test entropy\n);
} else {
-   /*
-* Gather entropy equal to the security strength of the DRBG.
-* With a derivation function, a nonce is required in addition
-* to the entropy. A nonce must be at least 1/2 of the security
-* strength of the DRBG in size. Thus, entropy * nonce is 3/2
-* of the strength. The consideration of a nonce is only
-* applicable during initial seeding.
-*/
-   entropylen = drbg_sec_strength(drbg-core-flags);
-   if (!entropylen)
-   return -EFAULT;
-   if (!reseed)
-   entropylen = ((entropylen + 1) / 2) * 3;
pr_devel(DRBG: (re)seeding with %zu bytes of entropy\n,
-entropylen);
-   entropy = kzalloc(entropylen, GFP_KERNEL);
-   if (!entropy)
-   return -ENOMEM;
-   get_random_bytes(entropy, entropylen);
-   drbg_string_fill(data1, entropy, entropylen);
+drbg-seed_buf_len);
+   get_random_bytes(drbg-seed_buf, drbg-seed_buf_len);
+   drbg_string_fill(data1, drbg-seed_buf, drbg-seed_buf_len);
}
list_add_tail(data1.list, seedlist);
 
@@ -,16 +1108,24 @@ static int drbg_seed(struct drbg_state *drbg, struct 
drbg_string *pers,
memset(drbg-C, 0, drbg_statelen(drbg));
}
 
-   ret = drbg-d_ops-update(drbg, seedlist, reseed);
+   ret = __drbg_seed(drbg, seedlist, reseed);
+
+   /*
+* Clear the initial entropy buffer as the async call may not overwrite
+* that buffer for quite some time.
+*/
+   memzero_explicit(drbg-seed_buf, drbg-seed_buf_len);
if (ret)
goto out;
-
-   drbg-seeded = true;
-   /* 10.1.1.2 / 10.1.1.3 step 5 */
-   drbg-reseed_ctr = 1;
+   /*
+* For all subsequent seeding calls, we only need the seed buffer
+* equal to the security strength of the DRBG. We undo the calculation
+* in drbg_alloc_state.
+*/
+   if (!reseed)
+   drbg-seed_buf_len = drbg-seed_buf_len / 3 * 2;
 
 out:
-   kzfree(entropy);
return ret;
 }
 
@@ -1143,6 +1148,8 @@ static inline void drbg_dealloc_state(struct drbg_state 
*drbg)
drbg-prev = NULL;
drbg-fips_primed = false;
 #endif
+   kzfree(drbg-seed_buf);
+   drbg-seed_buf = NULL;
 }
 
 /*
@@ -1204,6 +1211,26 @@ static inline int drbg_alloc_state(struct drbg_state 
*drbg)
if (!drbg-scratchpad)
goto err;
}
+
+   /*
+* Gather entropy equal to the security strength of the DRBG.
+* With a derivation function, a nonce is required in addition
+* to the entropy. A nonce must be at least 1/2 of the security
+* strength of the DRBG in size. Thus, 

[PATCH v7 1/5] random: Blocking API for accessing nonblocking_pool

2015-05-20 Thread Stephan Mueller
The added API calls provide a synchronous function call
get_blocking_random_bytes where the caller is blocked until
the nonblocking_pool is initialized.

CC: Andreas Steffen andreas.stef...@strongswan.org
CC: Theodore Ts'o ty...@mit.edu
CC: Sandy Harris sandyinch...@gmail.com
Signed-off-by: Stephan Mueller smuel...@chronox.de
---
 drivers/char/random.c  | 18 ++
 include/linux/random.h |  1 +
 2 files changed, 19 insertions(+)

diff --git a/drivers/char/random.c b/drivers/char/random.c
index 9cd6968..3d1c027 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1245,6 +1245,24 @@ void get_random_bytes(void *buf, int nbytes)
 EXPORT_SYMBOL(get_random_bytes);
 
 /*
+ * Equivalent function to get_random_bytes with the difference that this
+ * function blocks the request until the nonblocking_pool is initialized.
+ */
+void get_blocking_random_bytes(void *buf, int nbytes)
+{
+   int rc;
+
+   if (unlikely(nonblocking_pool.initialized == 0)) {
+   do {
+   rc = wait_event_interruptible(urandom_init_wait,
+   nonblocking_pool.initialized);
+   } while (rc == -ERESTARTSYS);
+   }
+   extract_entropy(nonblocking_pool, buf, nbytes, 0, 0);
+}
+EXPORT_SYMBOL(get_blocking_random_bytes);
+
+/*
  * This function will use the architecture-specific hardware random
  * number generator if it is available.  The arch-specific hw RNG will
  * almost certainly be faster than what we can do in software, but it
diff --git a/include/linux/random.h b/include/linux/random.h
index b05856e..796267d 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -14,6 +14,7 @@ extern void add_input_randomness(unsigned int type, unsigned 
int code,
 extern void add_interrupt_randomness(int irq, int irq_flags);
 
 extern void get_random_bytes(void *buf, int nbytes);
+extern void get_blocking_random_bytes(void *buf, int nbytes);
 extern void get_random_bytes_arch(void *buf, int nbytes);
 void generate_random_uuid(unsigned char uuid_out[16]);
 extern int random_int_secret_init(void);
-- 
2.1.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


Re: [PATCH v8 1/5] random: Blocking API for accessing nonblocking_pool

2015-05-20 Thread Stephan Mueller
Am Mittwoch, 20. Mai 2015, 21:44:46 schrieb Stephan Mueller:

Hi,

 +int get_blocking_random_bytes(void *buf, int nbytes)
 +{
 + int rc;

Sorry, I should be more carefully here: the rc should be initialized to 0 :-(
-- 
Ciao
Stephan
--
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 v7 0/5] Seeding DRBG with more entropy

2015-05-20 Thread Stephan Mueller
Hi,

as of now, the DRBG is only seeded from get_random_bytes. In various
circumstances, the nonblocking_pool behind get_random_bytes may not be fully
seeded from hardware events at the time the DRBG requires to be seeded.
Based on the discussion in [1], the DRBG seeding is updated such that it
does not completely rely on get_random_bytes any more.

The seeding approach can be characterized as follows:

1. pull buffer of size entropy + nonce from get_random_bytes

2. pull another buffer of size entropy + nonce from my Jitter RNG

3. concatenate both buffers

4. seed the DRBG with the concatenated buffer

5. trigger the async invocation of the blocking API for accessing
   the nonblocking pool with a buffer of size entropy

6. return the DRBG instance to the caller without waiting for the completion
   of step 5

7. at some point in time, the blocking API returns with a full buffer
   which is then used to re-seed the DRBG

This way, we will get entropy during the first initialization without
blocking.

The patch set adds a blocking API to access the nonblocking pool to wait
until the nonblocking pool is initialized.

Note: the DRBG and Jitter RNG patches are against the current cryptodev-2.6
tree.

The new Jitter RNG is an RNG that has large set of tests and was presented on
LKML some time back. After speaking with mathematicians at NIST, that Jitter
RNG approach would be acceptable from their side as a noise source. Note, I
personally think that the Jitter RNG has sufficient entropy in almost all
circumstances (see the massive testing I conducted on all more widely used
CPUs as shown in [2]).

Changes v7:
* patch 01: Catch ERESTARTSYS error for wait_event_interruptible
* patch 03: move the cancel invocation to drbg_uninstantiate to ensure that
  the -fini function pointer is not yet invoked before the cancel is completed.
  As the cancel operation may potentially invoke crypto operations, the
  cipher state must be available.
* patch 04: deallocate Jitter RNG after nonblocking_pool is fully initialized.
  The change implies that regardless of the state of the nonblocking_pool, the
  Jitter RNG is used for the initial seeding in any case and only dropped for
  later reseeding operations.

Changes v6:
* patch 01: simplify patch by just adding a blocking API call to random.c as
  suggested by Herbert Xu.
* patch 03: move the async operation into this patch: the DRBG is in control
  of the async work.

Changes v5:
* drop patch 01 and therefore drop the creation of a kernel pool
* change patch 02 to use the nonblocking pool and block until the nonblocking
  pool is initialized or until the cancel operation is triggered.

Changes v4:
* Patch 02: Change get_blocking_random_bytes_cb to allow callers to call it
  multiple times without re-initializing the work data structure. Furthermore,
  only change the pointers to the output buffer and callback if work is not
  pending to avoid race conditions.
* Patch 04: No canceling of seeding during drbg_seed as the invocation of
  get_blocking_random_bytes_cb can now be done repeatedly without
  re-initializing the work data structure.

Changes v3:
* Patch 01: Correct calculation of entropy count as pointed out by Herbert Xu
* Patch 06: Correct a trivial coding issue in jent_entropy_init for
  checking JENT_EMINVARVAR reported by cppcheck

Changes v2:
* Use Dual BSD/GPL license in MODULE_LICENSE as suggested by
  Paul Bolle pebo...@tiscali.nl
* Patch 05, drbg_dealloc_state: only deallocate Jitter RNG if one was
  instantiated in the first place. There are two main reasons why the Jitter RNG
  may not be allocated: either it is not available as kernel module/in vmlinuz
  or during init time of the Jitter RNG, the performed testing shows that the
  underlying hardware is not suitable for the Jitter RNG (e.g. has a too coarse
  timer).


[1] http://www.mail-archive.com/linux-crypto@vger.kernel.org/msg13891.html

[2] http://www.chronox.de/jent.html

 crypto/Kconfig |  10 +
 crypto/Makefile|   2 +
 crypto/drbg.c  | 143 ++--
 crypto/jitterentropy.c | 909 +
 crypto/testmgr.c   |   4 +
 drivers/char/random.c  |  18 +
 include/crypto/drbg.h  |   5 +
 include/linux/random.h |   1 +
 8 files changed, 1065 insertions(+), 27 deletions(-)
 create mode 100644 crypto/jitterentropy.c

-- 
2.1.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 v7 4/5] crypto: drbg - use Jitter RNG to obtain seed

2015-05-20 Thread Stephan Mueller
During initialization, the DRBG now tries to allocate a handle of the
Jitter RNG. If such a Jitter RNG is available during seeding, the DRBG
pulls the required entropy/nonce string from get_random_bytes and
concatenates it with a string of equal size from the Jitter RNG. That
combined string is now the seed for the DRBG.

Written differently, the initial seed of the DRBG is now:

get_random_bytes(entropy/nonce) || jitterentropy (entropy/nonce)

If the Jitter RNG is not available, the DRBG only seeds from
get_random_bytes.

CC: Andreas Steffen andreas.stef...@strongswan.org
CC: Theodore Ts'o ty...@mit.edu
CC: Sandy Harris sandyinch...@gmail.com
Signed-off-by: Stephan Mueller smuel...@chronox.de
---
 crypto/drbg.c | 52 ---
 include/crypto/drbg.h |  1 +
 2 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/crypto/drbg.c b/crypto/drbg.c
index aca8684..9284348 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -1062,13 +1062,18 @@ static void drbg_async_seed(struct work_struct *work)
LIST_HEAD(seedlist);
struct drbg_state *drbg = container_of(work, struct drbg_state,
   seed_work);
+   int ret;
 
get_blocking_random_bytes(drbg-seed_buf, drbg-seed_buf_len);
 
drbg_string_fill(data, drbg-seed_buf, drbg-seed_buf_len);
list_add_tail(data.list, seedlist);
mutex_lock(drbg-drbg_mutex);
-   __drbg_seed(drbg, seedlist, true);
+   ret = __drbg_seed(drbg, seedlist, true);
+   if (!ret  drbg-jent) {
+   crypto_free_rng(drbg-jent);
+   drbg-jent = NULL;
+   }
memzero_explicit(drbg-seed_buf, drbg-seed_buf_len);
mutex_unlock(drbg-drbg_mutex);
 }
@@ -1103,10 +1108,24 @@ static int drbg_seed(struct drbg_state *drbg, struct 
drbg_string *pers,
 drbg-test_data.len);
pr_devel(DRBG: using test entropy\n);
} else {
-   pr_devel(DRBG: (re)seeding with %zu bytes of entropy\n,
-drbg-seed_buf_len);
+   /* Get seed from in-kernel /dev/urandom */
get_random_bytes(drbg-seed_buf, drbg-seed_buf_len);
-   drbg_string_fill(data1, drbg-seed_buf, drbg-seed_buf_len);
+
+   /* Get seed from Jitter RNG */
+   if (!drbg-jent ||
+   crypto_rng_get_bytes(drbg-jent,
+drbg-seed_buf + drbg-seed_buf_len,
+drbg-seed_buf_len)) {
+   drbg_string_fill(data1, drbg-seed_buf,
+drbg-seed_buf_len);
+   pr_devel(DRBG: (re)seeding with %zu bytes of 
entropy\n,
+drbg-seed_buf_len);
+   } else {
+   drbg_string_fill(data1, drbg-seed_buf,
+drbg-seed_buf_len * 2);
+   pr_devel(DRBG: (re)seeding with %zu bytes of 
entropy\n,
+drbg-seed_buf_len * 2);
+   }
}
list_add_tail(data1.list, seedlist);
 
@@ -1131,7 +1150,7 @@ static int drbg_seed(struct drbg_state *drbg, struct 
drbg_string *pers,
 * Clear the initial entropy buffer as the async call may not overwrite
 * that buffer for quite some time.
 */
-   memzero_explicit(drbg-seed_buf, drbg-seed_buf_len);
+   memzero_explicit(drbg-seed_buf, drbg-seed_buf_len * 2);
if (ret)
goto out;
/*
@@ -1171,6 +1190,10 @@ static inline void drbg_dealloc_state(struct drbg_state 
*drbg)
 #endif
kzfree(drbg-seed_buf);
drbg-seed_buf = NULL;
+   if (drbg-jent) {
+   crypto_free_rng(drbg-jent);
+   drbg-jent = NULL;
+   }
 }
 
 /*
@@ -1246,14 +1269,29 @@ static inline int drbg_alloc_state(struct drbg_state 
*drbg)
ret = -EFAULT;
goto err;
}
-   /* ensure we have sufficient buffer space for initial seed */
+   /*
+* Ensure we have sufficient buffer space for initial seed which
+* consists of the seed from get_random_bytes and the Jitter RNG.
+*/
drbg-seed_buf_len = ((drbg-seed_buf_len + 1) / 2) * 3;
-   drbg-seed_buf = kzalloc(drbg-seed_buf_len, GFP_KERNEL);
+   drbg-seed_buf = kzalloc(drbg-seed_buf_len * 2, GFP_KERNEL);
if (!drbg-seed_buf)
goto err;
 
INIT_WORK(drbg-seed_work, drbg_async_seed);
 
+   drbg-jent = crypto_alloc_rng(jitterentropy_rng, 0, 0);
+   if(IS_ERR(drbg-jent))
+   {
+   pr_info(DRBG: could not allocate Jitter RNG handle for 
seeding\n);
+   /*
+* As the Jitter RNG is a module that may not be present, we
+* continue with the operation and do not fully tie the DRBG
+* to the Jitter RNG.
+   

[PATCH v7 3/5] crypto: drbg - add async seeding operation

2015-05-20 Thread Stephan Mueller
The async seeding operation is triggered during initalization right
after the first non-blocking seeding is completed. As required by the
asynchronous operation of random.c, a callback function is provided that
is triggered by random.c once entropy is available. That callback
function performs the actual seeding of the DRBG.

CC: Andreas Steffen andreas.stef...@strongswan.org
CC: Theodore Ts'o ty...@mit.edu
CC: Sandy Harris sandyinch...@gmail.com
Signed-off-by: Stephan Mueller smuel...@chronox.de
---
 crypto/drbg.c | 24 
 include/crypto/drbg.h |  2 ++
 2 files changed, 26 insertions(+)

diff --git a/crypto/drbg.c b/crypto/drbg.c
index 36dfece..aca8684 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -1056,6 +1056,23 @@ static inline int __drbg_seed(struct drbg_state *drbg, 
struct list_head *seed,
return ret;
 }
 
+static void drbg_async_seed(struct work_struct *work)
+{
+   struct drbg_string data;
+   LIST_HEAD(seedlist);
+   struct drbg_state *drbg = container_of(work, struct drbg_state,
+  seed_work);
+
+   get_blocking_random_bytes(drbg-seed_buf, drbg-seed_buf_len);
+
+   drbg_string_fill(data, drbg-seed_buf, drbg-seed_buf_len);
+   list_add_tail(data.list, seedlist);
+   mutex_lock(drbg-drbg_mutex);
+   __drbg_seed(drbg, seedlist, true);
+   memzero_explicit(drbg-seed_buf, drbg-seed_buf_len);
+   mutex_unlock(drbg-drbg_mutex);
+}
+
 /*
  * Seeding or reseeding of the DRBG
  *
@@ -1125,6 +1142,10 @@ static int drbg_seed(struct drbg_state *drbg, struct 
drbg_string *pers,
if (!reseed)
drbg-seed_buf_len = drbg-seed_buf_len / 3 * 2;
 
+   /* Invoke asynchronous seeding unless DRBG is in test mode. */
+   if (!list_empty(drbg-test_data.list)  !reseed)
+   schedule_work(drbg-seed_work);
+
 out:
return ret;
 }
@@ -1231,6 +1252,8 @@ static inline int drbg_alloc_state(struct drbg_state 
*drbg)
if (!drbg-seed_buf)
goto err;
 
+   INIT_WORK(drbg-seed_work, drbg_async_seed);
+
return 0;
 
 err:
@@ -1487,6 +1510,7 @@ unlock:
  */
 static int drbg_uninstantiate(struct drbg_state *drbg)
 {
+   cancel_work_sync(drbg-seed_work);
if (drbg-d_ops)
drbg-d_ops-crypto_fini(drbg);
drbg_dealloc_state(drbg);
diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
index b052698..46994b2 100644
--- a/include/crypto/drbg.h
+++ b/include/crypto/drbg.h
@@ -51,6 +51,7 @@
 #include linux/fips.h
 #include linux/mutex.h
 #include linux/list.h
+#include linux/workqueue.h
 
 /*
  * Concatenation Helper and string operation helper
@@ -119,6 +120,7 @@ struct drbg_state {
bool fips_primed;   /* Continuous test primed? */
unsigned char *prev;/* FIPS 140-2 continuous test value */
 #endif
+   struct work_struct seed_work;   /* asynchronous seeding support */
u8 *seed_buf;   /* buffer holding the seed */
size_t seed_buf_len;
const struct drbg_state_ops *d_ops;
-- 
2.1.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


Re: [PATCH v7 1/5] random: Blocking API for accessing nonblocking_pool

2015-05-20 Thread Herbert Xu
On Wed, May 20, 2015 at 07:44:39PM +0200, Stephan Mueller wrote:

 + if (unlikely(nonblocking_pool.initialized == 0)) {
 + do {
 + rc = wait_event_interruptible(urandom_init_wait,
 + nonblocking_pool.initialized);
 + } while (rc == -ERESTARTSYS);

This is just a convoluted way of doing an uninterruptible sleep.
Either make it uninterruptible or allow the function to return
an error.

Cheers,
-- 
Email: Herbert Xu herb...@gondor.apana.org.au
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
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 v7 1/5] random: Blocking API for accessing nonblocking_pool

2015-05-20 Thread Stephan Mueller
Am Mittwoch, 20. Mai 2015, 20:49:45 schrieb Stephan Mueller:

Hi Herbert,

  This is just a convoluted way of doing an uninterruptible sleep.
  Either make it uninterruptible or allow the function to return
  an error.
 
 Sorry, I overlooked the availability of wait_event. I was looking for it
 initially, but missed it. I will fix it right away.

After checking a bit more, I see that an uninterruptible sleep cannot be 
canceled with cancel_work_sync. Therefore, replacing it with wait_event does 
not work.

Thus, go get an uninterruptible sleep which yet can be canceled seems to 
require wait_event_interruptible together with the check for ERESTARTSYS.

Nonetheless, I move the loop out to the DRBG code as requested.

-- 
Ciao
Stephan
--
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 v8 4/5] crypto: drbg - use Jitter RNG to obtain seed

2015-05-20 Thread Stephan Mueller
During initialization, the DRBG now tries to allocate a handle of the
Jitter RNG. If such a Jitter RNG is available during seeding, the DRBG
pulls the required entropy/nonce string from get_random_bytes and
concatenates it with a string of equal size from the Jitter RNG. That
combined string is now the seed for the DRBG.

Written differently, the initial seed of the DRBG is now:

get_random_bytes(entropy/nonce) || jitterentropy (entropy/nonce)

If the Jitter RNG is not available, the DRBG only seeds from
get_random_bytes.

CC: Andreas Steffen andreas.stef...@strongswan.org
CC: Theodore Ts'o ty...@mit.edu
CC: Sandy Harris sandyinch...@gmail.com
Signed-off-by: Stephan Mueller smuel...@chronox.de
---
 crypto/drbg.c | 51 ---
 include/crypto/drbg.h |  1 +
 2 files changed, 45 insertions(+), 7 deletions(-)

diff --git a/crypto/drbg.c b/crypto/drbg.c
index 4e54973..21d93ce 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -1072,7 +1072,11 @@ static void drbg_async_seed(struct work_struct *work)
drbg_string_fill(data, drbg-seed_buf, drbg-seed_buf_len);
list_add_tail(data.list, seedlist);
mutex_lock(drbg-drbg_mutex);
-   __drbg_seed(drbg, seedlist, true);
+   ret = __drbg_seed(drbg, seedlist, true);
+   if (!ret  drbg-jent) {
+   crypto_free_rng(drbg-jent);
+   drbg-jent = NULL;
+   }
memzero_explicit(drbg-seed_buf, drbg-seed_buf_len);
mutex_unlock(drbg-drbg_mutex);
 }
@@ -1107,10 +,24 @@ static int drbg_seed(struct drbg_state *drbg, struct 
drbg_string *pers,
 drbg-test_data.len);
pr_devel(DRBG: using test entropy\n);
} else {
-   pr_devel(DRBG: (re)seeding with %zu bytes of entropy\n,
-drbg-seed_buf_len);
+   /* Get seed from in-kernel /dev/urandom */
get_random_bytes(drbg-seed_buf, drbg-seed_buf_len);
-   drbg_string_fill(data1, drbg-seed_buf, drbg-seed_buf_len);
+
+   /* Get seed from Jitter RNG */
+   if (!drbg-jent ||
+   crypto_rng_get_bytes(drbg-jent,
+drbg-seed_buf + drbg-seed_buf_len,
+drbg-seed_buf_len)) {
+   drbg_string_fill(data1, drbg-seed_buf,
+drbg-seed_buf_len);
+   pr_devel(DRBG: (re)seeding with %zu bytes of 
entropy\n,
+drbg-seed_buf_len);
+   } else {
+   drbg_string_fill(data1, drbg-seed_buf,
+drbg-seed_buf_len * 2);
+   pr_devel(DRBG: (re)seeding with %zu bytes of 
entropy\n,
+drbg-seed_buf_len * 2);
+   }
}
list_add_tail(data1.list, seedlist);
 
@@ -1135,7 +1153,7 @@ static int drbg_seed(struct drbg_state *drbg, struct 
drbg_string *pers,
 * Clear the initial entropy buffer as the async call may not overwrite
 * that buffer for quite some time.
 */
-   memzero_explicit(drbg-seed_buf, drbg-seed_buf_len);
+   memzero_explicit(drbg-seed_buf, drbg-seed_buf_len * 2);
if (ret)
goto out;
/*
@@ -1175,6 +1193,10 @@ static inline void drbg_dealloc_state(struct drbg_state 
*drbg)
 #endif
kzfree(drbg-seed_buf);
drbg-seed_buf = NULL;
+   if (drbg-jent) {
+   crypto_free_rng(drbg-jent);
+   drbg-jent = NULL;
+   }
 }
 
 /*
@@ -1250,14 +1272,29 @@ static inline int drbg_alloc_state(struct drbg_state 
*drbg)
ret = -EFAULT;
goto err;
}
-   /* ensure we have sufficient buffer space for initial seed */
+   /*
+* Ensure we have sufficient buffer space for initial seed which
+* consists of the seed from get_random_bytes and the Jitter RNG.
+*/
drbg-seed_buf_len = ((drbg-seed_buf_len + 1) / 2) * 3;
-   drbg-seed_buf = kzalloc(drbg-seed_buf_len, GFP_KERNEL);
+   drbg-seed_buf = kzalloc(drbg-seed_buf_len * 2, GFP_KERNEL);
if (!drbg-seed_buf)
goto err;
 
INIT_WORK(drbg-seed_work, drbg_async_seed);
 
+   drbg-jent = crypto_alloc_rng(jitterentropy_rng, 0, 0);
+   if(IS_ERR(drbg-jent))
+   {
+   pr_info(DRBG: could not allocate Jitter RNG handle for 
seeding\n);
+   /*
+* As the Jitter RNG is a module that may not be present, we
+* continue with the operation and do not fully tie the DRBG
+* to the Jitter RNG.
+*/
+   drbg-jent = NULL;
+   }
+
return 0;
 
 err:
diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
index 46994b2..c3f208d 100644
--- a/include/crypto/drbg.h
+++ b/include/crypto/drbg.h
@@ -123,6 +123,7 @@ 

[PATCH v8 3/5] crypto: drbg - add async seeding operation

2015-05-20 Thread Stephan Mueller
The async seeding operation is triggered during initalization right
after the first non-blocking seeding is completed. As required by the
asynchronous operation of random.c, a callback function is provided that
is triggered by random.c once entropy is available. That callback
function performs the actual seeding of the DRBG.

CC: Andreas Steffen andreas.stef...@strongswan.org
CC: Theodore Ts'o ty...@mit.edu
CC: Sandy Harris sandyinch...@gmail.com
Signed-off-by: Stephan Mueller smuel...@chronox.de
---
 crypto/drbg.c | 28 
 include/crypto/drbg.h |  2 ++
 2 files changed, 30 insertions(+)

diff --git a/crypto/drbg.c b/crypto/drbg.c
index 36dfece..4e54973 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -1056,6 +1056,27 @@ static inline int __drbg_seed(struct drbg_state *drbg, 
struct list_head *seed,
return ret;
 }
 
+static void drbg_async_seed(struct work_struct *work)
+{
+   struct drbg_string data;
+   LIST_HEAD(seedlist);
+   struct drbg_state *drbg = container_of(work, struct drbg_state,
+  seed_work);
+   int ret;
+
+   do {
+   ret = get_blocking_random_bytes(drbg-seed_buf,
+   drbg-seed_buf_len);
+   } while (ret == -ERESTARTSYS);
+
+   drbg_string_fill(data, drbg-seed_buf, drbg-seed_buf_len);
+   list_add_tail(data.list, seedlist);
+   mutex_lock(drbg-drbg_mutex);
+   __drbg_seed(drbg, seedlist, true);
+   memzero_explicit(drbg-seed_buf, drbg-seed_buf_len);
+   mutex_unlock(drbg-drbg_mutex);
+}
+
 /*
  * Seeding or reseeding of the DRBG
  *
@@ -1125,6 +1146,10 @@ static int drbg_seed(struct drbg_state *drbg, struct 
drbg_string *pers,
if (!reseed)
drbg-seed_buf_len = drbg-seed_buf_len / 3 * 2;
 
+   /* Invoke asynchronous seeding unless DRBG is in test mode. */
+   if (!list_empty(drbg-test_data.list)  !reseed)
+   schedule_work(drbg-seed_work);
+
 out:
return ret;
 }
@@ -1231,6 +1256,8 @@ static inline int drbg_alloc_state(struct drbg_state 
*drbg)
if (!drbg-seed_buf)
goto err;
 
+   INIT_WORK(drbg-seed_work, drbg_async_seed);
+
return 0;
 
 err:
@@ -1487,6 +1514,7 @@ unlock:
  */
 static int drbg_uninstantiate(struct drbg_state *drbg)
 {
+   cancel_work_sync(drbg-seed_work);
if (drbg-d_ops)
drbg-d_ops-crypto_fini(drbg);
drbg_dealloc_state(drbg);
diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
index b052698..46994b2 100644
--- a/include/crypto/drbg.h
+++ b/include/crypto/drbg.h
@@ -51,6 +51,7 @@
 #include linux/fips.h
 #include linux/mutex.h
 #include linux/list.h
+#include linux/workqueue.h
 
 /*
  * Concatenation Helper and string operation helper
@@ -119,6 +120,7 @@ struct drbg_state {
bool fips_primed;   /* Continuous test primed? */
unsigned char *prev;/* FIPS 140-2 continuous test value */
 #endif
+   struct work_struct seed_work;   /* asynchronous seeding support */
u8 *seed_buf;   /* buffer holding the seed */
size_t seed_buf_len;
const struct drbg_state_ops *d_ops;
-- 
2.1.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 v8 2/5] crypto: drbg - prepare for async seeding

2015-05-20 Thread Stephan Mueller
In order to prepare for the addition of the asynchronous seeding call,
the invocation of seeding the DRBG is moved out into a helper function.

In addition, a block of memory is allocated during initialization time
that will be used as a scratchpad for obtaining entropy. That scratchpad
is used for the initial seeding operation as well as by the
asynchronous seeding call. The memory must be zeroized every time the
DRBG seeding call succeeds to avoid entropy data lingering in memory.

CC: Andreas Steffen andreas.stef...@strongswan.org
CC: Theodore Ts'o ty...@mit.edu
CC: Sandy Harris sandyinch...@gmail.com
Signed-off-by: Stephan Mueller smuel...@chronox.de
---
 crypto/drbg.c | 81 ++-
 include/crypto/drbg.h |  2 ++
 2 files changed, 56 insertions(+), 27 deletions(-)

diff --git a/crypto/drbg.c b/crypto/drbg.c
index 23d444e..36dfece 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -1041,6 +1041,21 @@ static struct drbg_state_ops drbg_hash_ops = {
  * Functions common for DRBG implementations
  **/
 
+static inline int __drbg_seed(struct drbg_state *drbg, struct list_head *seed,
+ int reseed)
+{
+   int ret = drbg-d_ops-update(drbg, seed, reseed);
+
+   if (ret)
+   return ret;
+
+   drbg-seeded = true;
+   /* 10.1.1.2 / 10.1.1.3 step 5 */
+   drbg-reseed_ctr = 1;
+
+   return ret;
+}
+
 /*
  * Seeding or reseeding of the DRBG
  *
@@ -1056,8 +1071,6 @@ static int drbg_seed(struct drbg_state *drbg, struct 
drbg_string *pers,
 bool reseed)
 {
int ret = 0;
-   unsigned char *entropy = NULL;
-   size_t entropylen = 0;
struct drbg_string data1;
LIST_HEAD(seedlist);
 
@@ -1073,26 +1086,10 @@ static int drbg_seed(struct drbg_state *drbg, struct 
drbg_string *pers,
 drbg-test_data.len);
pr_devel(DRBG: using test entropy\n);
} else {
-   /*
-* Gather entropy equal to the security strength of the DRBG.
-* With a derivation function, a nonce is required in addition
-* to the entropy. A nonce must be at least 1/2 of the security
-* strength of the DRBG in size. Thus, entropy * nonce is 3/2
-* of the strength. The consideration of a nonce is only
-* applicable during initial seeding.
-*/
-   entropylen = drbg_sec_strength(drbg-core-flags);
-   if (!entropylen)
-   return -EFAULT;
-   if (!reseed)
-   entropylen = ((entropylen + 1) / 2) * 3;
pr_devel(DRBG: (re)seeding with %zu bytes of entropy\n,
-entropylen);
-   entropy = kzalloc(entropylen, GFP_KERNEL);
-   if (!entropy)
-   return -ENOMEM;
-   get_random_bytes(entropy, entropylen);
-   drbg_string_fill(data1, entropy, entropylen);
+drbg-seed_buf_len);
+   get_random_bytes(drbg-seed_buf, drbg-seed_buf_len);
+   drbg_string_fill(data1, drbg-seed_buf, drbg-seed_buf_len);
}
list_add_tail(data1.list, seedlist);
 
@@ -,16 +1108,24 @@ static int drbg_seed(struct drbg_state *drbg, struct 
drbg_string *pers,
memset(drbg-C, 0, drbg_statelen(drbg));
}
 
-   ret = drbg-d_ops-update(drbg, seedlist, reseed);
+   ret = __drbg_seed(drbg, seedlist, reseed);
+
+   /*
+* Clear the initial entropy buffer as the async call may not overwrite
+* that buffer for quite some time.
+*/
+   memzero_explicit(drbg-seed_buf, drbg-seed_buf_len);
if (ret)
goto out;
-
-   drbg-seeded = true;
-   /* 10.1.1.2 / 10.1.1.3 step 5 */
-   drbg-reseed_ctr = 1;
+   /*
+* For all subsequent seeding calls, we only need the seed buffer
+* equal to the security strength of the DRBG. We undo the calculation
+* in drbg_alloc_state.
+*/
+   if (!reseed)
+   drbg-seed_buf_len = drbg-seed_buf_len / 3 * 2;
 
 out:
-   kzfree(entropy);
return ret;
 }
 
@@ -1143,6 +1148,8 @@ static inline void drbg_dealloc_state(struct drbg_state 
*drbg)
drbg-prev = NULL;
drbg-fips_primed = false;
 #endif
+   kzfree(drbg-seed_buf);
+   drbg-seed_buf = NULL;
 }
 
 /*
@@ -1204,6 +1211,26 @@ static inline int drbg_alloc_state(struct drbg_state 
*drbg)
if (!drbg-scratchpad)
goto err;
}
+
+   /*
+* Gather entropy equal to the security strength of the DRBG.
+* With a derivation function, a nonce is required in addition
+* to the entropy. A nonce must be at least 1/2 of the security
+* strength of the DRBG in size. Thus, 

[PATCH v8 1/5] random: Blocking API for accessing nonblocking_pool

2015-05-20 Thread Stephan Mueller
The added API calls provide a synchronous function call
get_blocking_random_bytes where the caller is blocked until
the nonblocking_pool is initialized.

CC: Andreas Steffen andreas.stef...@strongswan.org
CC: Theodore Ts'o ty...@mit.edu
CC: Sandy Harris sandyinch...@gmail.com
Signed-off-by: Stephan Mueller smuel...@chronox.de
---
 drivers/char/random.c  | 20 
 include/linux/random.h |  1 +
 2 files changed, 21 insertions(+)

diff --git a/drivers/char/random.c b/drivers/char/random.c
index 9cd6968..9815a26 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1245,6 +1245,26 @@ void get_random_bytes(void *buf, int nbytes)
 EXPORT_SYMBOL(get_random_bytes);
 
 /*
+ * Equivalent function to get_random_bytes with the difference that this
+ * function blocks the request until the nonblocking_pool is initialized.
+ */
+int get_blocking_random_bytes(void *buf, int nbytes)
+{
+   int rc;
+
+   if (unlikely(nonblocking_pool.initialized == 0))
+   rc = wait_event_interruptible(urandom_init_wait,
+ nonblocking_pool.initialized);
+   if (rc)
+   return rc;
+
+   extract_entropy(nonblocking_pool, buf, nbytes, 0, 0);
+
+   return 0;
+}
+EXPORT_SYMBOL(get_blocking_random_bytes);
+
+/*
  * This function will use the architecture-specific hardware random
  * number generator if it is available.  The arch-specific hw RNG will
  * almost certainly be faster than what we can do in software, but it
diff --git a/include/linux/random.h b/include/linux/random.h
index b05856e..7d0d72f 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -14,6 +14,7 @@ extern void add_input_randomness(unsigned int type, unsigned 
int code,
 extern void add_interrupt_randomness(int irq, int irq_flags);
 
 extern void get_random_bytes(void *buf, int nbytes);
+extern int get_blocking_random_bytes(void *buf, int nbytes);
 extern void get_random_bytes_arch(void *buf, int nbytes);
 void generate_random_uuid(unsigned char uuid_out[16]);
 extern int random_int_secret_init(void);
-- 
2.1.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


Re: [PATCH v7 1/5] random: Blocking API for accessing nonblocking_pool

2015-05-20 Thread Stephan Mueller
Am Donnerstag, 21. Mai 2015, 02:45:35 schrieb Herbert Xu:

Hi Herbert,

 On Wed, May 20, 2015 at 07:44:39PM +0200, Stephan Mueller wrote:
  +   if (unlikely(nonblocking_pool.initialized == 0)) {
  +   do {
  +   rc = wait_event_interruptible(urandom_init_wait,
  +   nonblocking_pool.initialized);
  +   } while (rc == -ERESTARTSYS);
 
 This is just a convoluted way of doing an uninterruptible sleep.
 Either make it uninterruptible or allow the function to return
 an error.

Sorry, I overlooked the availability of wait_event. I was looking for it 
initially, but missed it. I will fix it right away.

-- 
Ciao
Stephan
--
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 v8 0/5] Seeding DRBG with more entropy

2015-05-20 Thread Stephan Mueller
Hi,

as of now, the DRBG is only seeded from get_random_bytes. In various
circumstances, the nonblocking_pool behind get_random_bytes may not be fully
seeded from hardware events at the time the DRBG requires to be seeded.
Based on the discussion in [1], the DRBG seeding is updated such that it
does not completely rely on get_random_bytes any more.

The seeding approach can be characterized as follows:

1. pull buffer of size entropy + nonce from get_random_bytes

2. pull another buffer of size entropy + nonce from my Jitter RNG

3. concatenate both buffers

4. seed the DRBG with the concatenated buffer

5. trigger the async invocation of the blocking API for accessing
   the nonblocking pool with a buffer of size entropy

6. return the DRBG instance to the caller without waiting for the completion
   of step 5

7. at some point in time, the blocking API returns with a full buffer
   which is then used to re-seed the DRBG

This way, we will get entropy during the first initialization without
blocking.

The patch set adds a blocking API to access the nonblocking pool to wait
until the nonblocking pool is initialized.

Note: the DRBG and Jitter RNG patches are against the current cryptodev-2.6
tree.

The new Jitter RNG is an RNG that has large set of tests and was presented on
LKML some time back. After speaking with mathematicians at NIST, that Jitter
RNG approach would be acceptable from their side as a noise source. Note, I
personally think that the Jitter RNG has sufficient entropy in almost all
circumstances (see the massive testing I conducted on all more widely used
CPUs as shown in [2]).

Changes v8:
* patch 01: make get_blocking_random_bytes to return the
  wait_event_interruptible error code
* patch 03: catch the ERESTARTSYS error code from get_blocking_random_bytes

Changes v7:
* patch 01: Catch ERESTARTSYS error for wait_event_interruptible
* patch 03: move the cancel invocation to drbg_uninstantiate to ensure that
  the -fini function pointer is not yet invoked before the cancel is completed.
  As the cancel operation may potentially invoke crypto operations, the
  cipher state must be available.
* patch 04: deallocate Jitter RNG after nonblocking_pool is fully initialized.
  The change implies that regardless of the state of the nonblocking_pool, the
  Jitter RNG is used for the initial seeding in any case and only dropped for
  later reseeding operations.

Changes v6:
* patch 01: simplify patch by just adding a blocking API call to random.c as
  suggested by Herbert Xu.
* patch 03: move the async operation into this patch: the DRBG is in control
  of the async work.

Changes v5:
* drop patch 01 and therefore drop the creation of a kernel pool
* change patch 02 to use the nonblocking pool and block until the nonblocking
  pool is initialized or until the cancel operation is triggered.

Changes v4:
* Patch 02: Change get_blocking_random_bytes_cb to allow callers to call it
  multiple times without re-initializing the work data structure. Furthermore,
  only change the pointers to the output buffer and callback if work is not
  pending to avoid race conditions.
* Patch 04: No canceling of seeding during drbg_seed as the invocation of
  get_blocking_random_bytes_cb can now be done repeatedly without
  re-initializing the work data structure.

Changes v3:
* Patch 01: Correct calculation of entropy count as pointed out by Herbert Xu
* Patch 06: Correct a trivial coding issue in jent_entropy_init for
  checking JENT_EMINVARVAR reported by cppcheck

Changes v2:
* Use Dual BSD/GPL license in MODULE_LICENSE as suggested by
  Paul Bolle pebo...@tiscali.nl
* Patch 05, drbg_dealloc_state: only deallocate Jitter RNG if one was
  instantiated in the first place. There are two main reasons why the Jitter RNG
  may not be allocated: either it is not available as kernel module/in vmlinuz
  or during init time of the Jitter RNG, the performed testing shows that the
  underlying hardware is not suitable for the Jitter RNG (e.g. has a too coarse
  timer).


[1] http://www.mail-archive.com/linux-crypto@vger.kernel.org/msg13891.html

[2] http://www.chronox.de/jent.html

Stephan Mueller (5):
  random: Blocking API for accessing nonblocking_pool
  crypto: drbg - prepare for async seeding
  crypto: drbg - add async seeding operation
  crypto: drbg - use Jitter RNG to obtain seed
  crypto: add jitterentropy RNG

 crypto/Kconfig |  10 +
 crypto/Makefile|   2 +
 crypto/drbg.c  | 146 ++--
 crypto/jitterentropy.c | 909 +
 crypto/testmgr.c   |   4 +
 drivers/char/random.c  |  20 ++
 include/crypto/drbg.h  |   5 +
 include/linux/random.h |   1 +
 8 files changed, 1070 insertions(+), 27 deletions(-)
 create mode 100644 crypto/jitterentropy.c

-- 
2.1.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


[V5 PATCH 3/5] device property: Introduces device_dma_is_coherent()

2015-05-20 Thread Suravee Suthikulpanit
Currently, device drivers, which support both OF and ACPI,
need to call two separate APIs, of_dma_is_coherent() and
acpi_dma_is_coherent()) to determine device coherency attribute.

This patch simplifies this process by introducing a new device
property API, device_dma_is_coherent(), which calls the appropriate
interface based on the booting architecture.

Signed-off-by: Suravee Suthikulpanit suravee.suthikulpa...@amd.com
---
 drivers/base/property.c  | 14 ++
 include/linux/property.h |  2 ++
 2 files changed, 16 insertions(+)

diff --git a/drivers/base/property.c b/drivers/base/property.c
index 1d0b116..e645852 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -14,6 +14,7 @@
 #include linux/export.h
 #include linux/kernel.h
 #include linux/of.h
+#include linux/of_address.h
 #include linux/property.h
 
 /**
@@ -519,3 +520,16 @@ unsigned int device_get_child_node_count(struct device 
*dev)
return count;
 }
 EXPORT_SYMBOL_GPL(device_get_child_node_count);
+
+bool device_dma_is_coherent(struct device *dev)
+{
+   bool coherent = false;
+
+   if (IS_ENABLED(CONFIG_OF)  dev-of_node)
+   coherent = of_dma_is_coherent(dev-of_node);
+   else
+   acpi_check_dma(ACPI_COMPANION(dev), coherent);
+
+   return coherent;
+}
+EXPORT_SYMBOL_GPL(device_dma_is_coherent);
diff --git a/include/linux/property.h b/include/linux/property.h
index de8bdf4..76ebde9 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -164,4 +164,6 @@ struct property_set {
 
 void device_add_property_set(struct device *dev, struct property_set *pset);
 
+bool device_dma_is_coherent(struct device *dev);
+
 #endif /* _LINUX_PROPERTY_H_ */
-- 
2.1.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


[V5 PATCH 4/5] crypto: ccp - Unify coherency checking logic with device_dma_is_coherent()

2015-05-20 Thread Suravee Suthikulpanit
Currently, the driver has separate logic to determine device coherency
for DT vs ACPI.  This patch simplifies the code with a call to
device_dma_is_coherent().

Signed-off-by: Tom Lendacky thomas.lenda...@amd.com
Signed-off-by: Suravee Suthikulpanit suravee.suthikulpa...@amd.com
---
 drivers/crypto/ccp/ccp-platform.c | 60 +--
 1 file changed, 1 insertion(+), 59 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-platform.c 
b/drivers/crypto/ccp/ccp-platform.c
index b1c20b2..e446781 100644
--- a/drivers/crypto/ccp/ccp-platform.c
+++ b/drivers/crypto/ccp/ccp-platform.c
@@ -90,58 +90,6 @@ static struct resource *ccp_find_mmio_area(struct ccp_device 
*ccp)
return NULL;
 }
 
-#ifdef CONFIG_ACPI
-static int ccp_acpi_support(struct ccp_device *ccp)
-{
-   struct ccp_platform *ccp_platform = ccp-dev_specific;
-   struct acpi_device *adev = ACPI_COMPANION(ccp-dev);
-   acpi_handle handle;
-   acpi_status status;
-   unsigned long long data;
-   int cca;
-
-   /* Retrieve the device cache coherency value */
-   handle = adev-handle;
-   do {
-   status = acpi_evaluate_integer(handle, _CCA, NULL, data);
-   if (!ACPI_FAILURE(status)) {
-   cca = data;
-   break;
-   }
-   } while (!ACPI_FAILURE(status));
-
-   if (ACPI_FAILURE(status)) {
-   dev_err(ccp-dev, error obtaining acpi coherency value\n);
-   return -EINVAL;
-   }
-
-   ccp_platform-coherent = !!cca;
-
-   return 0;
-}
-#else  /* CONFIG_ACPI */
-static int ccp_acpi_support(struct ccp_device *ccp)
-{
-   return -EINVAL;
-}
-#endif
-
-#ifdef CONFIG_OF
-static int ccp_of_support(struct ccp_device *ccp)
-{
-   struct ccp_platform *ccp_platform = ccp-dev_specific;
-
-   ccp_platform-coherent = of_dma_is_coherent(ccp-dev-of_node);
-
-   return 0;
-}
-#else
-static int ccp_of_support(struct ccp_device *ccp)
-{
-   return -EINVAL;
-}
-#endif
-
 static int ccp_platform_probe(struct platform_device *pdev)
 {
struct ccp_device *ccp;
@@ -182,13 +130,7 @@ static int ccp_platform_probe(struct platform_device *pdev)
goto e_err;
}
 
-   if (ccp_platform-use_acpi)
-   ret = ccp_acpi_support(ccp);
-   else
-   ret = ccp_of_support(ccp);
-   if (ret)
-   goto e_err;
-
+   ccp_platform-coherent = device_dma_is_coherent(ccp-dev);
if (ccp_platform-coherent)
ccp-axcache = CACHE_WB_NO_ALLOC;
else
-- 
2.1.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


[V5 PATCH 0/5] ACPI: Introduce support for _CCA object

2015-05-20 Thread Suravee Suthikulpanit
This patch series introduce support for _CCA object, which is currently
used mainly by ARM64 platform to specify DMA coherency attribute for
devices when booting with ACPI.

A copy of ACPIv6 can be found here:
http://www.uefi.org/sites/default/files/resources/ACPI_6.0.pdf

This patch also introduces a new APIS:
1. acpi_check_dma() as part of ACPI API.
2. device_dma_is_coherent() as part of unified device property API.

This simplifies the logic in device drivers to determine device coherency
attribute regardless of booting with DT vs ACPI.

This has been tested on AMD-Seattle platform, which implements _CCA 
object as described in the AMD Opteron A1100 Series Processor ACPI Porting 
Guide:

http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2012/10/Seattle_ACPI_Guide.pdf

Changes from V4 (https://lkml.org/lkml/2015/5/15/669):
* Patch1:
  - Move the arch_setup_dma_ops() call from acpi_create_platform_device()
to acpi_bind_one() to support other bus types (per Rafael).
  - Rename acpi_device_flags.is_coherent to acpi_device_flags.coherent_dma.
(per Rafael)
  - Refactor acpi_dma_is_supported() and acpi_dma_is_coherent() to
acpi_check_dma() to simplify the new interface.
  - Only support _CCA=1 for now. See acpi_check_dma() (per Arnd and Catalin)
* Patch2:
  - Add acked-by Catalin.
* Patch3:
  - Use ACPI_COMPANION() instead of acpi_node().
  - Remove has_acpi_companion() check since already done by acpi_node().
(per Will)
* Remove the patch Generic function for setting up PCI device DMA 
coherency
  introduced in V4. (per Bjorn)

Changes from V3 (https://lkml.org/lkml/2015/5/7/1004):
* Remove ARCH64_SUPPORT_ACPI_CCA_ZERO and just use CONFIG_ARM64.
  (per Catalin and Rafael)
* Do not need to call arch_setup_dma_ops() for acpi_device-dev.
  (per Rafael)
* [3/6] (New) We also need to call arch_setup_dma_ops() for pci
  devices and check the CCA of the host bridge. Similar logic
  exists for OF. So, I refactor of_pci_dma_configure() to
  the more generic version pci_dma_configure(), and add support
  for ACPI.

Changes from V2 (https://lkml.org/lkml/2015/5/5/510):
* Reword ACPI_MUST_HAVE_CCA to ACPI_CCA_REQUIRED (per Rafael)
* Reword ACPI_SUPPORT_CCA_ZERO to ARCH64_SUPPORT_ACPI_CCA_ZERO
  (per Rafael and Arnd)
* Misc code styling clean up (per Rafael)
* Only print missing _CCA warning message in debug mode.
* Refactor logic in acpi_setup_device_dma() into
  if acpi_dma_is_supported() then call arch_setup_dma_ops().
* Do not allocate device dma_mask if !acpi_dma_is_supported()
  (per Arnd).
* Re-use the dummy functions with the same signature.

Changes from V1 (https://lkml.org/lkml/2015/4/29/290):
* Remove supports for 32-bit ARM since doesn't currently
  supporting ACPI (Per Catalin suggestions.)
* Do not call arch_setup_dma_ops() and when _CCA is missing.
  (per Arnd suggestion)
* Add CONFIG_ACPI_SUPPORT_CCA_ZERO kernel config flag to
  allow architectures to specify the behavior when _CCA=0.
* Add dummy_dma_ops for ARM64 (per Catalin suggestions).
* Fixed build error when ACPI is not configured by defining
  acpi_dma_is_coherent() for when CONFIG_ACPI is not set.
* Introduce device_dma_is_coherent().
* Use device_dma_is_coherent in crypto/ccp and amd-xgbe driver.

Changes from RFC: (https://lkml.org/lkml/2015/4/1/389)
* New logic for deriving and propagating coherent attribute from
  parent devices. (by Mark)
* Introducing acpi_dma_is_coherent() API (Per Tom suggestion)
* Introducing CONFIG_ACPI_MUST_HAVE_CCA kernel configuration.
* Rebased to linux-4.1-rc1

Suravee Suthikulpanit (5):
  ACPI / scan: Parse _CCA and setup device coherency
  arm64 : Introduce support for ACPI _CCA object
  device property: Introduces device_dma_is_coherent()
  crypto: ccp - Unify coherency checking logic with
device_dma_is_coherent()
  amd-xgbe: Unify coherency checking logic with device_dma_is_coherent()

 arch/arm64/Kconfig|  1 +
 arch/arm64/include/asm/dma-mapping.h  | 18 +-
 arch/arm64/mm/dma-mapping.c   | 92 +++
 drivers/acpi/Kconfig  |  3 +
 drivers/acpi/acpi_platform.c  |  2 +-
 drivers/acpi/glue.c   |  5 ++
 drivers/acpi/scan.c   | 35 
 drivers/base/property.c   | 14 +
 drivers/crypto/ccp/ccp-platform.c | 60 +---
 drivers/net/ethernet/amd/xgbe/xgbe-main.c | 27 +
 include/acpi/acpi_bus.h   | 37 -
 include/linux/acpi.h  |  5 ++
 include/linux/property.h  |  2 +
 13 files changed, 212 insertions(+), 89 deletions(-)

-- 
2.1.0

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message 

[V5 PATCH 5/5] amd-xgbe: Unify coherency checking logic with device_dma_is_coherent()

2015-05-20 Thread Suravee Suthikulpanit
Currently, amd-xgbe driver has separate logic to determine device
coherency for DT vs. ACPI. This patch simplifies the code with
a call to device_dma_is_coherent().

Signed-off-by: Tom Lendacky thomas.lenda...@amd.com
Signed-off-by: Suravee Suthikulpanit suravee.suthikulpa...@amd.com
---
 drivers/net/ethernet/amd/xgbe/xgbe-main.c | 27 +--
 1 file changed, 1 insertion(+), 26 deletions(-)

diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c 
b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
index 7149053..6d2c702 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
@@ -168,13 +168,8 @@ static void xgbe_init_all_fptrs(struct xgbe_prv_data 
*pdata)
 #ifdef CONFIG_ACPI
 static int xgbe_acpi_support(struct xgbe_prv_data *pdata)
 {
-   struct acpi_device *adev = pdata-adev;
struct device *dev = pdata-dev;
u32 property;
-   acpi_handle handle;
-   acpi_status status;
-   unsigned long long data;
-   int cca;
int ret;
 
/* Obtain the system clock setting */
@@ -195,24 +190,6 @@ static int xgbe_acpi_support(struct xgbe_prv_data *pdata)
}
pdata-ptpclk_rate = property;
 
-   /* Retrieve the device cache coherency value */
-   handle = adev-handle;
-   do {
-   status = acpi_evaluate_integer(handle, _CCA, NULL, data);
-   if (!ACPI_FAILURE(status)) {
-   cca = data;
-   break;
-   }
-
-   status = acpi_get_parent(handle, handle);
-   } while (!ACPI_FAILURE(status));
-
-   if (ACPI_FAILURE(status)) {
-   dev_err(dev, error obtaining acpi coherency value\n);
-   return -EINVAL;
-   }
-   pdata-coherent = !!cca;
-
return 0;
 }
 #else   /* CONFIG_ACPI */
@@ -243,9 +220,6 @@ static int xgbe_of_support(struct xgbe_prv_data *pdata)
}
pdata-ptpclk_rate = clk_get_rate(pdata-ptpclk);
 
-   /* Retrieve the device cache coherency value */
-   pdata-coherent = of_dma_is_coherent(dev-of_node);
-
return 0;
 }
 #else   /* CONFIG_OF */
@@ -364,6 +338,7 @@ static int xgbe_probe(struct platform_device *pdev)
goto err_io;
 
/* Set the DMA coherency values */
+   pdata-coherent = device_dma_is_coherent(pdata-dev);
if (pdata-coherent) {
pdata-axdomain = XGBE_DMA_OS_AXDOMAIN;
pdata-arcache = XGBE_DMA_OS_ARCACHE;
-- 
2.1.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


[V5 PATCH 1/5] ACPI / scan: Parse _CCA and setup device coherency

2015-05-20 Thread Suravee Suthikulpanit
This patch implements support for ACPI _CCA object, which is introduced in
ACPIv5.1, can be used for specifying device DMA coherency attribute.

The parsing logic traverses device namespace to parse coherency
information, and stores it in acpi_device_flags. Then uses it to call
arch_setup_dma_ops() when creating each device enumerated in DSDT
during ACPI scan.

This patch also introduces acpi_dma_is_coherent(), which provides
an interface for device drivers to check the coherency information
similarly to the of_dma_is_coherent().

Signed-off-by: Mark Salter msal...@redhat.com
Signed-off-by: Suravee Suthikulpanit suravee.suthikulpa...@amd.com
---
 drivers/acpi/Kconfig |  3 +++
 drivers/acpi/acpi_platform.c |  2 +-
 drivers/acpi/glue.c  |  5 +
 drivers/acpi/scan.c  | 35 +++
 include/acpi/acpi_bus.h  | 37 -
 include/linux/acpi.h |  5 +
 6 files changed, 85 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index ab2cbb5..212735f 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -54,6 +54,9 @@ config ACPI_GENERIC_GSI
 config ACPI_SYSTEM_POWER_STATES_SUPPORT
bool
 
+config ACPI_CCA_REQUIRED
+   bool
+
 config ACPI_SLEEP
bool
depends on SUSPEND || HIBERNATION
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
index 4bf7559..06a67d5 100644
--- a/drivers/acpi/acpi_platform.c
+++ b/drivers/acpi/acpi_platform.c
@@ -103,7 +103,7 @@ struct platform_device *acpi_create_platform_device(struct 
acpi_device *adev)
pdevinfo.res = resources;
pdevinfo.num_res = count;
pdevinfo.fwnode = acpi_fwnode_handle(adev);
-   pdevinfo.dma_mask = DMA_BIT_MASK(32);
+   pdevinfo.dma_mask = acpi_check_dma(adev, NULL) ? DMA_BIT_MASK(32) : 0;
pdev = platform_device_register_full(pdevinfo);
if (IS_ERR(pdev))
dev_err(adev-dev, platform device creation failed: %ld\n,
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 39c485b..b9657af 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -13,6 +13,7 @@
 #include linux/slab.h
 #include linux/rwsem.h
 #include linux/acpi.h
+#include linux/dma-mapping.h
 
 #include internal.h
 
@@ -167,6 +168,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device 
*acpi_dev)
struct list_head *physnode_list;
unsigned int node_id;
int retval = -EINVAL;
+   bool coherent;
 
if (has_acpi_companion(dev)) {
if (acpi_dev) {
@@ -223,6 +225,9 @@ int acpi_bind_one(struct device *dev, struct acpi_device 
*acpi_dev)
if (!has_acpi_companion(dev))
ACPI_COMPANION_SET(dev, acpi_dev);
 
+   if (acpi_check_dma(acpi_dev, coherent))
+   arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
+
acpi_physnode_link_name(physical_node_name, node_id);
retval = sysfs_create_link(acpi_dev-dev.kobj, dev-kobj,
   physical_node_name);
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 849b699..fdedb63 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -11,6 +11,7 @@
 #include linux/kthread.h
 #include linux/dmi.h
 #include linux/nls.h
+#include linux/dma-mapping.h
 
 #include asm/pgtable.h
 
@@ -2137,6 +2138,39 @@ void acpi_free_pnp_ids(struct acpi_device_pnp *pnp)
kfree(pnp-unique_id);
 }
 
+static void acpi_init_coherency(struct acpi_device *adev)
+{
+   unsigned long long cca = 0;
+   acpi_status status;
+   struct acpi_device *parent = adev-parent;
+
+   if (parent  parent-flags.cca_seen) {
+   /*
+* From ACPI spec, OSPM will ignore _CCA if an ancestor
+* already saw one.
+*/
+   adev-flags.cca_seen = 1;
+   cca = parent-flags.coherent_dma;
+   } else {
+   status = acpi_evaluate_integer(adev-handle, _CCA,
+  NULL, cca);
+   if (ACPI_SUCCESS(status))
+   adev-flags.cca_seen = 1;
+   else if (!IS_ENABLED(CONFIG_ACPI_CCA_REQUIRED))
+   /*
+* If architecture does not specify that _CCA is
+* required for DMA-able devices (e.g. x86),
+* we default to _CCA=1.
+*/
+   cca = 1;
+   else
+   acpi_handle_debug(adev-handle,
+ ACPI device is missing _CCA.\n);
+   }
+
+   adev-flags.coherent_dma = cca;
+}
+
 void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
 int type, unsigned long long sta)
 {
@@ -2155,6 +2189,7 @@ void acpi_init_device_object(struct acpi_device *device, 
acpi_handle handle,
device-flags.visited = false;

[V5 PATCH 2/5] arm64 : Introduce support for ACPI _CCA object

2015-05-20 Thread Suravee Suthikulpanit
From http://www.uefi.org/sites/default/files/resources/ACPI_6.0.pdf,
section 6.2.17 _CCA states that ARM platforms require ACPI _CCA
object to be specified for DMA-cabpable devices. Therefore, this patch
specifies ACPI_CCA_REQUIRED in arm64 Kconfig.

In addition, to handle the case when _CCA is missing, arm64 would assign
dummy_dma_ops to disable DMA capability of the device.

Acked-by: Catalin Marinas catalin.mari...@arm.com
Signed-off-by: Mark Salter msal...@redhat.com
Signed-off-by: Suravee Suthikulpanit suravee.suthikulpa...@amd.com
---
 arch/arm64/Kconfig   |  1 +
 arch/arm64/include/asm/dma-mapping.h | 18 ++-
 arch/arm64/mm/dma-mapping.c  | 92 
 3 files changed, 109 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 4269dba..95307b4 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1,5 +1,6 @@
 config ARM64
def_bool y
+   select ACPI_CCA_REQUIRED if ACPI
select ACPI_GENERIC_GSI if ACPI
select ACPI_REDUCED_HARDWARE_ONLY if ACPI
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
diff --git a/arch/arm64/include/asm/dma-mapping.h 
b/arch/arm64/include/asm/dma-mapping.h
index 9437e3d..f0d6d0b 100644
--- a/arch/arm64/include/asm/dma-mapping.h
+++ b/arch/arm64/include/asm/dma-mapping.h
@@ -18,6 +18,7 @@
 
 #ifdef __KERNEL__
 
+#include linux/acpi.h
 #include linux/types.h
 #include linux/vmalloc.h
 
@@ -28,13 +29,23 @@
 
 #define DMA_ERROR_CODE (~(dma_addr_t)0)
 extern struct dma_map_ops *dma_ops;
+extern struct dma_map_ops dummy_dma_ops;
 
 static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
 {
-   if (unlikely(!dev) || !dev-archdata.dma_ops)
+   if (unlikely(!dev))
return dma_ops;
-   else
+   else if (dev-archdata.dma_ops)
return dev-archdata.dma_ops;
+   else if (acpi_disabled)
+   return dma_ops;
+
+   /*
+* When ACPI is enabled, if arch_set_dma_ops is not called,
+* we will disable device DMA capability by setting it
+* to dummy_dma_ops.
+*/
+   return dummy_dma_ops;
 }
 
 static inline struct dma_map_ops *get_dma_ops(struct device *dev)
@@ -48,6 +59,9 @@ static inline struct dma_map_ops *get_dma_ops(struct device 
*dev)
 static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 
size,
  struct iommu_ops *iommu, bool coherent)
 {
+   if (!acpi_disabled  !dev-archdata.dma_ops)
+   dev-archdata.dma_ops = dma_ops;
+
dev-archdata.dma_coherent = coherent;
 }
 #define arch_setup_dma_ops arch_setup_dma_ops
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index ef7d112..6e6d6ad 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -415,6 +415,98 @@ out:
return -ENOMEM;
 }
 
+/
+ * The following APIs are for dummy DMA ops *
+ /
+
+static void *__dummy_alloc(struct device *dev, size_t size,
+  dma_addr_t *dma_handle, gfp_t flags,
+  struct dma_attrs *attrs)
+{
+   return NULL;
+}
+
+static void __dummy_free(struct device *dev, size_t size,
+void *vaddr, dma_addr_t dma_handle,
+struct dma_attrs *attrs)
+{
+}
+
+static int __dummy_mmap(struct device *dev,
+   struct vm_area_struct *vma,
+   void *cpu_addr, dma_addr_t dma_addr, size_t size,
+   struct dma_attrs *attrs)
+{
+   return -ENXIO;
+}
+
+static dma_addr_t __dummy_map_page(struct device *dev, struct page *page,
+  unsigned long offset, size_t size,
+  enum dma_data_direction dir,
+  struct dma_attrs *attrs)
+{
+   return DMA_ERROR_CODE;
+}
+
+static void __dummy_unmap_page(struct device *dev, dma_addr_t dev_addr,
+  size_t size, enum dma_data_direction dir,
+  struct dma_attrs *attrs)
+{
+}
+
+static int __dummy_map_sg(struct device *dev, struct scatterlist *sgl,
+ int nelems, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+   return 0;
+}
+
+static void __dummy_unmap_sg(struct device *dev,
+struct scatterlist *sgl, int nelems,
+enum dma_data_direction dir,
+struct dma_attrs *attrs)
+{
+}
+
+static void __dummy_sync_single(struct device *dev,
+   dma_addr_t dev_addr, size_t size,
+   enum dma_data_direction dir)
+{
+}
+
+static void __dummy_sync_sg(struct device *dev,
+   struct scatterlist *sgl, int nelems,
+