Message ID | 20190410064635.11813-6-ebiggers@kernel.org (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Herbert Xu |
Headers | show |
Series | crypto: fixes in preparation of new fuzz tests | expand |
Hi, [This is an automated email] This commit has been processed because it contains a "Fixes:" tag, fixing commit: d00aa19b507b [CRYPTO] gcm: Allow block cipher parameter. The bot has tested the following trees: v5.0.7, v4.19.34, v4.14.111, v4.9.168, v4.4.178, v3.18.138. v5.0.7: Build OK! v4.19.34: Build OK! v4.14.111: Build OK! v4.9.168: Failed to apply! Possible dependencies: 9b40f79c08e8 ("crypto: gcm - Fix error return code in crypto_gcm_create_common()") v4.4.178: Failed to apply! Possible dependencies: 16f37ecdd068 ("crypto: gcm - Use skcipher") 9b40f79c08e8 ("crypto: gcm - Fix error return code in crypto_gcm_create_common()") v3.18.138: Failed to apply! Possible dependencies: 16f37ecdd068 ("crypto: gcm - Use skcipher") 17db85469970 ("crypto: gcm - Use default null skcipher") 5d72336f1b2c ("crypto: gcm - Use crypto_aead_set_reqsize helper") 9b40f79c08e8 ("crypto: gcm - Fix error return code in crypto_gcm_create_common()") adcbc688fe2f ("crypto: gcm - Convert to new AEAD interface") How should we proceed with this patch? -- Thanks, Sasha
Eric Biggers <ebiggers@kernel.org> wrote: > > @@ -638,7 +637,7 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl, > goto err_free_inst; > > err = -EINVAL; > - if (ghash->digestsize != 16) > + if (strcmp(ghash->base.cra_name, "ghash") != 0) > goto err_drop_ghash; We should keep both tests because the self-tests can be compiled out so there is no guarantee that something claiming to be ghash actually is ghash. Cheers,
On Thu, Apr 18, 2019 at 10:00:06PM +0800, Herbert Xu wrote: > Eric Biggers <ebiggers@kernel.org> wrote: > > > > @@ -638,7 +637,7 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl, > > goto err_free_inst; > > > > err = -EINVAL; > > - if (ghash->digestsize != 16) > > + if (strcmp(ghash->base.cra_name, "ghash") != 0) > > goto err_drop_ghash; > > We should keep both tests because the self-tests can be compiled > out so there is no guarantee that something claiming to be ghash > actually is ghash. > I'm not necessarily opposed to doing this, but if we're assuming that untested, arbitrarily broken algorithms may be registered with the crypto API under any name, "ghash" could easily still be broken even if it declares a 16-byte digest size. Verifying the digest size is just an extra sanity check; we're really still relying on the implementation to be correct. (Same for the ccm patch.) - Eric
On Thu, Apr 18, 2019 at 11:41:46AM -0700, Eric Biggers wrote: > > I'm not necessarily opposed to doing this, but if we're assuming that untested, > arbitrarily broken algorithms may be registered with the crypto API under any > name, "ghash" could easily still be broken even if it declares a 16-byte digest > size. Verifying the digest size is just an extra sanity check; we're really > still relying on the implementation to be correct. (Same for the ccm patch.) The check is not so much for the purpose of producing the correct output for the given algorithm, since as you correctly stated that would rely on the correctness of the underlying algorithm. It is more about not crashing when the underlying algorithm has a geometry that is completely different (e.g., by overwriting the digest buffer). Come to think of it, perhaps we should check the geometry of algorithms even when self-tests are compiled out. That way these checks could be replaced by a simple name check. This would be good anyway because the self-tests may indeed crash if an algorithm with an incorrect geometry is used. Cheers,
diff --git a/crypto/gcm.c b/crypto/gcm.c index e1a11f529d257..c7354ed1fa4d4 100644 --- a/crypto/gcm.c +++ b/crypto/gcm.c @@ -597,7 +597,6 @@ static void crypto_gcm_free(struct aead_instance *inst) static int crypto_gcm_create_common(struct crypto_template *tmpl, struct rtattr **tb, - const char *full_name, const char *ctr_name, const char *ghash_name) { @@ -638,7 +637,7 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl, goto err_free_inst; err = -EINVAL; - if (ghash->digestsize != 16) + if (strcmp(ghash->base.cra_name, "ghash") != 0) goto err_drop_ghash; crypto_set_skcipher_spawn(&ctx->ctr, aead_crypto_instance(inst)); @@ -650,24 +649,23 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl, ctr = crypto_spawn_skcipher_alg(&ctx->ctr); - /* We only support 16-byte blocks. */ + /* The skcipher algorithm must be CTR mode, using 16-byte blocks. */ err = -EINVAL; - if (crypto_skcipher_alg_ivsize(ctr) != 16) + if (strncmp(ctr->base.cra_name, "ctr(", 4) != 0 || + crypto_skcipher_alg_ivsize(ctr) != 16) goto out_put_ctr; - /* Not a stream cipher? */ - if (ctr->base.cra_blocksize != 1) + err = -ENAMETOOLONG; + if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, + "gcm(%s", ctr->base.cra_name + 4) >= CRYPTO_MAX_ALG_NAME) goto out_put_ctr; - err = -ENAMETOOLONG; if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME, "gcm_base(%s,%s)", ctr->base.cra_driver_name, ghash_alg->cra_driver_name) >= CRYPTO_MAX_ALG_NAME) goto out_put_ctr; - memcpy(inst->alg.base.cra_name, full_name, CRYPTO_MAX_ALG_NAME); - inst->alg.base.cra_flags = (ghash->base.cra_flags | ctr->base.cra_flags) & CRYPTO_ALG_ASYNC; inst->alg.base.cra_priority = (ghash->base.cra_priority + @@ -709,7 +707,6 @@ static int crypto_gcm_create(struct crypto_template *tmpl, struct rtattr **tb) { const char *cipher_name; char ctr_name[CRYPTO_MAX_ALG_NAME]; - char full_name[CRYPTO_MAX_ALG_NAME]; cipher_name = crypto_attr_alg_name(tb[1]); if (IS_ERR(cipher_name)) @@ -719,12 +716,7 @@ static int crypto_gcm_create(struct crypto_template *tmpl, struct rtattr **tb) CRYPTO_MAX_ALG_NAME) return -ENAMETOOLONG; - if (snprintf(full_name, CRYPTO_MAX_ALG_NAME, "gcm(%s)", cipher_name) >= - CRYPTO_MAX_ALG_NAME) - return -ENAMETOOLONG; - - return crypto_gcm_create_common(tmpl, tb, full_name, - ctr_name, "ghash"); + return crypto_gcm_create_common(tmpl, tb, ctr_name, "ghash"); } static int crypto_gcm_base_create(struct crypto_template *tmpl, @@ -732,7 +724,6 @@ static int crypto_gcm_base_create(struct crypto_template *tmpl, { const char *ctr_name; const char *ghash_name; - char full_name[CRYPTO_MAX_ALG_NAME]; ctr_name = crypto_attr_alg_name(tb[1]); if (IS_ERR(ctr_name)) @@ -742,12 +733,7 @@ static int crypto_gcm_base_create(struct crypto_template *tmpl, if (IS_ERR(ghash_name)) return PTR_ERR(ghash_name); - if (snprintf(full_name, CRYPTO_MAX_ALG_NAME, "gcm_base(%s,%s)", - ctr_name, ghash_name) >= CRYPTO_MAX_ALG_NAME) - return -ENAMETOOLONG; - - return crypto_gcm_create_common(tmpl, tb, full_name, - ctr_name, ghash_name); + return crypto_gcm_create_common(tmpl, tb, ctr_name, ghash_name); } static int crypto_rfc4106_setkey(struct crypto_aead *parent, const u8 *key,