Re: [V4 PATCH 3/6] pci: Generic function for setting up PCI device DMA coherency
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
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
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
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
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
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
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
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
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
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
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
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
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()
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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()
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()
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
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()
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
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
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, +