| From: Eric Biggers <ebiggers@google.com> |
| Date: Wed, 3 Jan 2018 11:16:26 -0800 |
| Subject: crypto: hash - annotate algorithms taking optional key |
| |
| commit a208fa8f33031b9e0aba44c7d1b7e68eb0cbd29e upstream. |
| |
| We need to consistently enforce that keyed hashes cannot be used without |
| setting the key. To do this we need a reliable way to determine whether |
| a given hash algorithm is keyed or not. AF_ALG currently does this by |
| checking for the presence of a ->setkey() method. However, this is |
| actually slightly broken because the CRC-32 algorithms implement |
| ->setkey() but can also be used without a key. (The CRC-32 "key" is not |
| actually a cryptographic key but rather represents the initial state. |
| If not overridden, then a default initial state is used.) |
| |
| Prepare to fix this by introducing a flag CRYPTO_ALG_OPTIONAL_KEY which |
| indicates that the algorithm has a ->setkey() method, but it is not |
| required to be called. Then set it on all the CRC-32 algorithms. |
| |
| The same also applies to the Adler-32 implementation in Lustre. |
| |
| Also, the cryptd and mcryptd templates have to pass through the flag |
| from their underlying algorithm. |
| |
| Signed-off-by: Eric Biggers <ebiggers@google.com> |
| Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> |
| [bwh: Backported to 3.16: |
| - Drop changes to nonexistent drivers |
| - There's no CRYPTO_ALG_INTERNAL flag |
| - Adjust filenames] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| --- a/arch/sparc/crypto/crc32c_glue.c |
| +++ b/arch/sparc/crypto/crc32c_glue.c |
| @@ -133,6 +133,7 @@ static struct shash_alg alg = { |
| .cra_name = "crc32c", |
| .cra_driver_name = "crc32c-sparc64", |
| .cra_priority = SPARC_CR_OPCODE_PRIORITY, |
| + .cra_flags = CRYPTO_ALG_OPTIONAL_KEY, |
| .cra_blocksize = CHKSUM_BLOCK_SIZE, |
| .cra_ctxsize = sizeof(u32), |
| .cra_alignmask = 7, |
| --- a/arch/x86/crypto/crc32-pclmul_glue.c |
| +++ b/arch/x86/crypto/crc32-pclmul_glue.c |
| @@ -162,6 +162,7 @@ static struct shash_alg alg = { |
| .cra_name = "crc32", |
| .cra_driver_name = "crc32-pclmul", |
| .cra_priority = 200, |
| + .cra_flags = CRYPTO_ALG_OPTIONAL_KEY, |
| .cra_blocksize = CHKSUM_BLOCK_SIZE, |
| .cra_ctxsize = sizeof(u32), |
| .cra_module = THIS_MODULE, |
| --- a/arch/x86/crypto/crc32c-intel_glue.c |
| +++ b/arch/x86/crypto/crc32c-intel_glue.c |
| @@ -240,6 +240,7 @@ static struct shash_alg alg = { |
| .cra_name = "crc32c", |
| .cra_driver_name = "crc32c-intel", |
| .cra_priority = 200, |
| + .cra_flags = CRYPTO_ALG_OPTIONAL_KEY, |
| .cra_blocksize = CHKSUM_BLOCK_SIZE, |
| .cra_ctxsize = sizeof(u32), |
| .cra_module = THIS_MODULE, |
| --- a/crypto/crc32.c |
| +++ b/crypto/crc32.c |
| @@ -133,6 +133,7 @@ static struct shash_alg alg = { |
| .cra_name = "crc32", |
| .cra_driver_name = "crc32-table", |
| .cra_priority = 100, |
| + .cra_flags = CRYPTO_ALG_OPTIONAL_KEY, |
| .cra_blocksize = CHKSUM_BLOCK_SIZE, |
| .cra_ctxsize = sizeof(u32), |
| .cra_module = THIS_MODULE, |
| --- a/crypto/crc32c_generic.c |
| +++ b/crypto/crc32c_generic.c |
| @@ -146,6 +146,7 @@ static struct shash_alg alg = { |
| .cra_name = "crc32c", |
| .cra_driver_name = "crc32c-generic", |
| .cra_priority = 100, |
| + .cra_flags = CRYPTO_ALG_OPTIONAL_KEY, |
| .cra_blocksize = CHKSUM_BLOCK_SIZE, |
| .cra_alignmask = 3, |
| .cra_ctxsize = sizeof(struct chksum_ctx), |
| --- a/crypto/cryptd.c |
| +++ b/crypto/cryptd.c |
| @@ -603,7 +603,8 @@ static int cryptd_create_hash(struct cry |
| if (err) |
| goto out_free_inst; |
| |
| - inst->alg.halg.base.cra_flags = CRYPTO_ALG_ASYNC; |
| + inst->alg.halg.base.cra_flags = CRYPTO_ALG_ASYNC | |
| + (alg->cra_flags & CRYPTO_ALG_OPTIONAL_KEY); |
| |
| inst->alg.halg.digestsize = salg->digestsize; |
| inst->alg.halg.base.cra_ctxsize = sizeof(struct cryptd_hash_ctx); |
| --- a/drivers/crypto/bfin_crc.c |
| +++ b/drivers/crypto/bfin_crc.c |
| @@ -514,7 +514,8 @@ static struct ahash_alg algs = { |
| .cra_driver_name = DRIVER_NAME, |
| .cra_priority = 100, |
| .cra_flags = CRYPTO_ALG_TYPE_AHASH | |
| - CRYPTO_ALG_ASYNC, |
| + CRYPTO_ALG_ASYNC | |
| + CRYPTO_ALG_OPTIONAL_KEY, |
| .cra_blocksize = CHKSUM_BLOCK_SIZE, |
| .cra_ctxsize = sizeof(struct bfin_crypto_crc_ctx), |
| .cra_alignmask = 3, |
| --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-crypto-adler.c |
| +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-crypto-adler.c |
| @@ -123,6 +123,7 @@ static struct shash_alg alg = { |
| .cra_name = "adler32", |
| .cra_driver_name = "adler32-zlib", |
| .cra_priority = 100, |
| + .cra_flags = CRYPTO_ALG_OPTIONAL_KEY, |
| .cra_blocksize = CHKSUM_BLOCK_SIZE, |
| .cra_ctxsize = sizeof(u32), |
| .cra_module = THIS_MODULE, |
| --- a/include/linux/crypto.h |
| +++ b/include/linux/crypto.h |
| @@ -95,6 +95,12 @@ |
| #define CRYPTO_ALG_KERN_DRIVER_ONLY 0x00001000 |
| |
| /* |
| + * Set if the algorithm has a ->setkey() method but can be used without |
| + * calling it first, i.e. there is a default key. |
| + */ |
| +#define CRYPTO_ALG_OPTIONAL_KEY 0x00004000 |
| + |
| +/* |
| * Transform masks and values (for crt_flags). |
| */ |
| #define CRYPTO_TFM_REQ_MASK 0x000fff00 |