[PATCH 0/3] enhance RNG api with flags to allow for different operational modes
Hey all- Ok, so I've got a story behind this one. It was recently called to my attention that the ansi cprng is missing an aspect of its compliance requrements for FIPS-140. Specifically, its missing a behavior in its continuous test. When the CPRNG produces random blocks, the firrst block that it produces must never be returned to the user. Instead it must be saved and a second block must be generated so that it can be compared to the first block before being returned to the user. I recently posted a patch to do this for the hardware RNG. Its fine to do this there, since there are no expectations of a predictable result in that RNG. The CPRNG however, provides a predictable random sequence for a given input seed key and iteration. The above requirement messes with that predictability however because it changes which block is returned on the zeroth iteration to the user. Some test vectors expect this, some do not. So the question is, how do I make this RNG fips compliant without breaking some subset of users out there that rely on the predictability of the CPRNG? The solution I've come up with is a dynamic flag. This patch series adds two api calls to the crypto RNG api rng_set_flags and rng_get_flags, which set flags with global meaning on instances of an rng. A given RNG can opt to set the registered agorithm methods for these api calls or not. In the event they don't a default handler is set for each that returns EOPNOTSUPPORT. Using this new mechanism I've implemented these calls in ansi_cprng so that setting the TEST_MODE flag disables the continuous check, allowing for the zeroth block to get returned to the user, which lets us pass most of the supplied test vectors (most notably the NIST provided vectors). Signed-off-by: Neil Horman nhor...@tuxdriver.com -- To unsubscribe from this list: send the line unsubscribe linux-crypto in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] add RNG api calls to set common flags
patch 1/3: Add flags infrastructure to rng api This patch adds api calls for get/set flags calls to the crypto rng api. This api allows algorithm implementations to register calls to respond to flag settings that are global and common to all rng's. If a given algorithm has no external flags that it needs to respond to, it can opt to not register any calls, and as a result a default handler will be registered for each which universally returns EOPNOTSUPPORT. Signed-off-by: Neil Horman nhor...@tuxdriver.com crypto/rng.c | 13 + include/crypto/rng.h | 21 + include/linux/crypto.h |9 + 3 files changed, 43 insertions(+) diff --git a/crypto/rng.c b/crypto/rng.c index ba05e73..98f10b1 100644 --- a/crypto/rng.c +++ b/crypto/rng.c @@ -46,6 +46,17 @@ static int rngapi_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen) return err; } +static int rngapi_set_flags(struct crypto_rng *tfm, u8 flags) +{ + return -EOPNOTSUPP; +} + +static int rngapi_get_flags(struct crypto_rng *tfm, u8 *flags) +{ + return -EOPNOTSUPP; +} + + static int crypto_init_rng_ops(struct crypto_tfm *tfm, u32 type, u32 mask) { struct rng_alg *alg = tfm-__crt_alg-cra_rng; @@ -53,6 +64,8 @@ static int crypto_init_rng_ops(struct crypto_tfm *tfm, u32 type, u32 mask) ops-rng_gen_random = alg-rng_make_random; ops-rng_reset = rngapi_reset; + ops-rng_set_flags = alg-rng_set_flags ? : rngapi_set_flags; + ops-rng_get_flags = alg-rng_get_flags ? : rngapi_get_flags; return 0; } diff --git a/include/crypto/rng.h b/include/crypto/rng.h index c93f9b9..a639955 100644 --- a/include/crypto/rng.h +++ b/include/crypto/rng.h @@ -15,6 +15,17 @@ #include linux/crypto.h +/* + * RNG behavioral flags + * CRYPTO_RNG_TEST_MODE + * places the RNG into a test mode for various certification tests. Some + * RNG's (most notably Deterministic RNGs) Can have internal tests which are + * required in normal operation mode, but affect the deterministic output + * of the RNG which throws some test vectors off, as they may not account for + * these tests. This flag allows us to disable the internal tests of an RNG. + */ +#define CRYPTO_RNG_TEST_MODE 0x01 + extern struct crypto_rng *crypto_default_rng; int crypto_get_default_rng(void); @@ -72,4 +83,14 @@ static inline int crypto_rng_seedsize(struct crypto_rng *tfm) return crypto_rng_alg(tfm)-seedsize; } +static inline int crypto_rng_set_flags(struct crypto_rng *tfm, u8 flags) +{ + return crypto_rng_alg(tfm)-rng_set_flags(tfm, flags); +} + +static inline int crypto_rng_get_flags(struct crypto_rng *tfm, u8 *flags) +{ + return crypto_rng_alg(tfm)-rng_get_flags(tfm, flags); +} + #endif diff --git a/include/linux/crypto.h b/include/linux/crypto.h index fd92988..6af8d2f 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -285,6 +285,10 @@ struct rng_alg { unsigned int dlen); int (*rng_reset)(struct crypto_rng *tfm, u8 *seed, unsigned int slen); + int (*rng_set_flags)(struct crypto_rng *tfm, u8 flags); + + int (*rng_get_flags)(struct crypto_rng *tfm, u8 *flags); + unsigned int seedsize; }; @@ -421,6 +425,11 @@ struct rng_tfm { int (*rng_gen_random)(struct crypto_rng *tfm, u8 *rdata, unsigned int dlen); int (*rng_reset)(struct crypto_rng *tfm, u8 *seed, unsigned int slen); + + int (*rng_set_flags)(struct crypto_rng *tfm, u8 flags); + + int (*rng_get_flags)(struct crypto_rng *tfm, u8 *flags); + }; #define crt_ablkcipher crt_u.ablkcipher -- 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 2/3] augment the testmgr code to set TEST_MODE flag on all rng instances
patch 2/3: Update testmgr code to place any rng it tests in TEST_MODE This patch instructs the testmgr code to place all rng allocations that it makes into test mode, so that in the event that it has internal mechanisms that may affect the testing of the RNG, they won't affect the outcome of the test they are preforming. Signed-off-by: Neil Horman nhor...@tuxdriver.com testmgr.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 6d5b746..89ea8c1 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -1470,6 +1470,8 @@ static int alg_test_cprng(const struct alg_test_desc *desc, const char *driver, return PTR_ERR(rng); } + crypto_rng_set_flags(rng, CRYPTO_RNG_TEST_MODE); + err = test_cprng(rng, desc-suite.cprng.vecs, desc-suite.cprng.count); crypto_free_rng(rng); -- 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 3/3] augment CPRNG to correctly implement continuous test for FIPS, and support TEST_MODE flags
patch 3/3: modify cprng to make contnuity check fips compliant and allow for a disabling of the continuity test when the RNG is placed in FIPS mode Signed-off-by: Neil Horman nhor...@txudriver.com ansi_cprng.c | 56 +++- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/crypto/ansi_cprng.c b/crypto/ansi_cprng.c index 3aa6e38..c1ba5e8 100644 --- a/crypto/ansi_cprng.c +++ b/crypto/ansi_cprng.c @@ -33,6 +33,7 @@ #define PRNG_FIXED_SIZE 0x1 #define PRNG_NEED_RESET 0x2 +#define PRNG_DISABLE_CONT_TEST 0x3 /* * Note: DT is our counter value @@ -85,7 +86,7 @@ static void xor_vectors(unsigned char *in1, unsigned char *in2, * Returns DEFAULT_BLK_SZ bytes of random data per call * returns 0 if generation succeded, 0 if something went wrong */ -static int _get_more_prng_bytes(struct prng_context *ctx) +static int _get_more_prng_bytes(struct prng_context *ctx, int test) { int i; unsigned char tmp[DEFAULT_BLK_SZ]; @@ -130,6 +131,9 @@ static int _get_more_prng_bytes(struct prng_context *ctx) * First check that we didn't produce the same * random data that we did last time around through this */ + if (ctx-flags PRNG_DISABLE_CONT_TEST) + goto skip_test; + if (!memcmp(ctx-rand_data, ctx-last_rand_data, DEFAULT_BLK_SZ)) { if (fips_enabled) { @@ -146,7 +150,7 @@ static int _get_more_prng_bytes(struct prng_context *ctx) } memcpy(ctx-last_rand_data, ctx-rand_data, DEFAULT_BLK_SZ); - +skip_test: /* * Lastly xor the random data with I * and encrypt that to obtain a new secret vector V @@ -220,7 +224,7 @@ static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx) remainder: if (ctx-rand_data_valid == DEFAULT_BLK_SZ) { - if (_get_more_prng_bytes(ctx) 0) { + if (_get_more_prng_bytes(ctx, 1) 0) { memset(buf, 0, nbytes); err = -EINVAL; goto done; @@ -247,7 +251,7 @@ empty_rbuf: */ for (; byte_count = DEFAULT_BLK_SZ; byte_count -= DEFAULT_BLK_SZ) { if (ctx-rand_data_valid == DEFAULT_BLK_SZ) { - if (_get_more_prng_bytes(ctx) 0) { + if (_get_more_prng_bytes(ctx, 1) 0) { memset(buf, 0, nbytes); err = -EINVAL; goto done; @@ -306,7 +310,6 @@ static int reset_prng_context(struct prng_context *ctx, memset(ctx-rand_data, 0, DEFAULT_BLK_SZ); memset(ctx-last_rand_data, 0, DEFAULT_BLK_SZ); - ctx-rand_data_valid = DEFAULT_BLK_SZ; ret = crypto_cipher_setkey(ctx-tfm, prng_key, klen); if (ret) { @@ -317,6 +320,18 @@ static int reset_prng_context(struct prng_context *ctx, ret = 0; ctx-flags = ~PRNG_NEED_RESET; + + /* +* If we don't disable the continuity test +* we need to seed the n=0 iteration for test +* comparison, so we get a first block here that +* we never return to the user +*/ + ctx-rand_data_valid = DEFAULT_BLK_SZ; + if (!(ctx-flags PRNG_DISABLE_CONT_TEST)) + _get_more_prng_bytes(ctx, 0); + + ctx-rand_data_valid = DEFAULT_BLK_SZ; out: spin_unlock_bh(ctx-prng_lock); return ret; @@ -384,6 +399,35 @@ static int cprng_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen) return 0; } + /* + * These are the registered functions which export behavioral flags + * to the crypto api. Most rng's don't have flags, but some might, like + * the cprng which implements a 'test mode' for validation of vecotors + * which disables the internal continuity tests + */ +static int cprng_set_flags(struct crypto_rng *tfm, u8 flags) +{ + struct prng_context *prng = crypto_rng_ctx(tfm); + + if (flags CRYPTO_RNG_TEST_MODE) + prng-flags |= PRNG_DISABLE_CONT_TEST; + + return 0; +} + + static int cprng_get_flags(struct crypto_rng *tfm, u8 *flags) +{ + struct prng_context *prng = crypto_rng_ctx(tfm); + + *flags = 0; + + if (prng-flags PRNG_DISABLE_CONT_TEST) + *flags |= CRYPTO_RNG_TEST_MODE; + + return 0; +} + + static struct crypto_alg rng_alg = { .cra_name = stdrng, .cra_driver_name= ansi_cprng, @@ -399,6 +443,8 @@ static struct crypto_alg rng_alg = { .rng = { .rng_make_random= cprng_get_random, .rng_reset
[PATCH] arm: new W macro to WORD_ACCESS
As reported by Frans Pop the new global macro W on ARM which is included via |arch/arm/include/asm/uaccess.h:20 |include/linux/uaccess.h:5 |include/linux/crypto.h:26 |crypto/cast6.c:23 leads to a build error because the crypto/cast6.c defines a function which is named W. Reported-by: Frans Pop elen...@planet.nl Signed-off-by: Sebastian Andrzej Siewior sebast...@breakpoint.cc --- * Frans Pop | 2009-09-16 16:01:34 [+0200]: Maybe it's a result of enabling the new config option CRYPTO_DEV_MV_CESA? please don't blame my shiny new driver :) Catalin: bisect leads to 8b592783a. I've renamed the macro in this commit and everything else I found due to compile error. Hope the new name is acceptable. I think W in global name space is a bad thing to do. In crypto there are many one letter identifier. Since you use this in assembly code only you might want to move it to another header file which does get included from every .c file. arch/arm/boot/compressed/head.S | 96 +++--- arch/arm/include/asm/unified.h |4 +- arch/arm/kernel/entry-armv.S| 50 ++-- arch/arm/lib/copy_from_user.S |2 +- arch/arm/lib/copy_template.S|4 +- arch/arm/lib/copy_to_user.S |2 +- arch/arm/lib/memcpy.S |4 +- arch/arm/lib/memmove.S | 28 ++-- 8 files changed, 95 insertions(+), 95 deletions(-) diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index fa6fbf4..6939dd0 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -612,8 +612,8 @@ call_cache_fn: adr r12, proc_types proc_types: .word 0x41560600 @ ARM6/610 .word 0xffe0 - W(b)__arm6_mmu_cache_off@ works, but slow - W(b)__arm6_mmu_cache_off + WORD_ACCESS(b) __arm6_mmu_cache_off@ works, but slow + WORD_ACCESS(b) __arm6_mmu_cache_off mov pc, lr THUMB(nop ) @ b __arm6_mmu_cache_on @ untested @@ -631,29 +631,29 @@ proc_types: .word 0x41007000 @ ARM7/710 .word 0xfff8fe00 - W(b)__arm7_mmu_cache_off - W(b)__arm7_mmu_cache_off + WORD_ACCESS(b) __arm7_mmu_cache_off + WORD_ACCESS(b) __arm7_mmu_cache_off mov pc, lr THUMB(nop ) .word 0x41807200 @ ARM720T (writethrough) .word 0xff00 - W(b)__armv4_mmu_cache_on - W(b)__armv4_mmu_cache_off + WORD_ACCESS(b) __armv4_mmu_cache_on + WORD_ACCESS(b) __armv4_mmu_cache_off mov pc, lr THUMB(nop ) .word 0x41007400 @ ARM74x .word 0xff00ff00 - W(b)__armv3_mpu_cache_on - W(b)__armv3_mpu_cache_off - W(b)__armv3_mpu_cache_flush + WORD_ACCESS(b) __armv3_mpu_cache_on + WORD_ACCESS(b) __armv3_mpu_cache_off + WORD_ACCESS(b) __armv3_mpu_cache_flush .word 0x41009400 @ ARM94x .word 0xff00ff00 - W(b)__armv4_mpu_cache_on - W(b)__armv4_mpu_cache_off - W(b)__armv4_mpu_cache_flush + WORD_ACCESS(b) __armv4_mpu_cache_on + WORD_ACCESS(b) __armv4_mpu_cache_off + WORD_ACCESS(b) __armv4_mpu_cache_flush .word 0x7000 @ ARM7 IDs .word 0xf000 @@ -668,39 +668,39 @@ proc_types: .word 0x4401a100 @ sa110 / sa1100 .word 0xffe0 - W(b)__armv4_mmu_cache_on - W(b)__armv4_mmu_cache_off - W(b)__armv4_mmu_cache_flush + WORD_ACCESS(b) __armv4_mmu_cache_on + WORD_ACCESS(b) __armv4_mmu_cache_off + WORD_ACCESS(b) __armv4_mmu_cache_flush .word 0x6901b110 @ sa1110 .word 0xfff0 - W(b)__armv4_mmu_cache_on - W(b)__armv4_mmu_cache_off - W(b)__armv4_mmu_cache_flush + WORD_ACCESS(b) __armv4_mmu_cache_on + WORD_ACCESS(b) __armv4_mmu_cache_off + WORD_ACCESS(b) __armv4_mmu_cache_flush .word 0x56056930 .word 0xff00 @ PXA935 - W(b)__armv4_mmu_cache_on - W(b)__armv4_mmu_cache_off - W(b)__armv4_mmu_cache_flush + WORD_ACCESS(b) __armv4_mmu_cache_on +
Re: [PATCH] arm: new W macro to WORD_ACCESS
On Wed, Sep 16, 2009 at 07:58:12PM +0200, Sebastian Andrzej Siewior wrote: leads to a build error because the crypto/cast6.c defines a function which is named W. W has nothing to do with the access size, so this change makes it _really_ confusing. What it's about is telling the compiler to use the ARM 32-bit version of the instruction coding when building for Thumb2 (which can intermix Thumb and ARM instruction sets.) So the macro needs to be renamed... NAK on this patch as it stands. -- To unsubscribe from this list: send the line unsubscribe linux-crypto in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] add RNG api calls to set common flags
On 09/16/2009 12:11 PM, Neil Horman wrote: patch 1/3: Add flags infrastructure to rng api This patch adds api calls for get/set flags calls to the crypto rng api. This api allows algorithm implementations to register calls to respond to flag settings that are global and common to all rng's. If a given algorithm has no external flags that it needs to respond to, it can opt to not register any calls, and as a result a default handler will be registered for each which universally returns EOPNOTSUPPORT. Signed-off-by: Neil Hormannhor...@tuxdriver.com Acked-by: Jarod Wilson ja...@redhat.com -- Jarod Wilson ja...@redhat.com -- To unsubscribe from this list: send the line unsubscribe linux-crypto in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/3] enhance RNG api with flags to allow for different operational modes
On 09/16/2009 12:04 PM, Neil Horman wrote: Hey all- Ok, so I've got a story behind this one. It was recently called to my attention that the ansi cprng is missing an aspect of its compliance requrements for FIPS-140. Specifically, its missing a behavior in its continuous test. When the CPRNG produces random blocks, the firrst block that it produces must never be returned to the user. Instead it must be saved and a second block must be generated so that it can be compared to the first block before being returned to the user. I recently posted a patch to do this for the hardware RNG. Its fine to do this there, since there are no expectations of a predictable result in that RNG. The CPRNG however, provides a predictable random sequence for a given input seed key and iteration. The above requirement messes with that predictability however because it changes which block is returned on the zeroth iteration to the user. Some test vectors expect this, some do not. So the question is, how do I make this RNG fips compliant without breaking some subset of users out there that rely on the predictability of the CPRNG? The solution I've come up with is a dynamic flag. This patch series adds two api calls to the crypto RNG api rng_set_flags and rng_get_flags, which set flags with global meaning on instances of an rng. A given RNG can opt to set the registered agorithm methods for these api calls or not. In the event they don't a default handler is set for each that returns EOPNOTSUPPORT. Using this new mechanism I've implemented these calls in ansi_cprng so that setting the TEST_MODE flag disables the continuous check, allowing for the zeroth block to get returned to the user, which lets us pass most of the supplied test vectors (most notably the NIST provided vectors). Neil and I discussed this whole mess off-list, and I'm in agreement that this is the cleanest solution to the problem, despite the relative complexity it adds to the base rng code. Will reply to each part individually for tracking purposes, but ACK for all three parts. -- Jarod Wilson ja...@redhat.com -- To unsubscribe from this list: send the line unsubscribe linux-crypto in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/3] augment the testmgr code to set TEST_MODE flag on all rng instances
On 09/16/2009 12:13 PM, Neil Horman wrote: patch 2/3: Update testmgr code to place any rng it tests in TEST_MODE This patch instructs the testmgr code to place all rng allocations that it makes into test mode, so that in the event that it has internal mechanisms that may affect the testing of the RNG, they won't affect the outcome of the test they are preforming. Signed-off-by: Neil Hormannhor...@tuxdriver.com With these same additions, my fips crypto test code arrives at expected results still as well. Acked-by: Jarod Wilson ja...@redhat.com -- Jarod Wilson ja...@redhat.com -- To unsubscribe from this list: send the line unsubscribe linux-crypto in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/3] augment CPRNG to correctly implement continuous test for FIPS, and support TEST_MODE flags
On 09/16/2009 12:25 PM, Neil Horman wrote: patch 3/3: modify cprng to make contnuity check fips compliant and allow for a disabling of the continuity test when the RNG is placed in FIPS mode Signed-off-by: Neil Hormannhor...@txudriver.com Acked-by: Jarod Wilson ja...@redhat.com -- Jarod Wilson ja...@redhat.com -- To unsubscribe from this list: send the line unsubscribe linux-crypto in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] arm: new W macro to WORD_ACCESS
On Wed, 2009-09-16 at 19:58 +0200, Sebastian Andrzej Siewior wrote: As reported by Frans Pop the new global macro W on ARM which is included via |arch/arm/include/asm/uaccess.h:20 |include/linux/uaccess.h:5 |include/linux/crypto.h:26 |crypto/cast6.c:23 leads to a build error because the crypto/cast6.c defines a function which is named W. This was already reported by Alexey Dobriyan and I included his patch in my Thumb-2 branch (and -next for now): http://linux-arm.org/git?p=linux-2.6.git;a=commitdiff;h=4fb3c2e2ab3549308a1b1663296d165e45d72ba5 Since this macro is only used in ARM assembly code, the patch simply adds some ifdefs around it. Russell, if you are OK with Alexey's patch, I'll send you a pull request (though for only one patch, alternatively just merge it manually). -- 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