]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - crypto/gcm.c
crypto: cryptd - Fix skcipher instance memory leak
[mirror_ubuntu-bionic-kernel.git] / crypto / gcm.c
index 8589681fb9f6d3b522894af6d9bc048a17d93cd2..19e1e423c057f2cf23f9dbd23bd60ee7995a7b86 100644 (file)
@@ -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,8 @@ 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 ||
+           ghash->digestsize != 16)
                goto err_drop_ghash;
 
        crypto_set_skcipher_spawn(&ctx->ctr, aead_crypto_instance(inst));
@@ -650,24 +650,24 @@ 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 ||
+           ctr->base.cra_blocksize != 1)
                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 +709,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 +718,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 struct crypto_template crypto_gcm_tmpl = {
@@ -738,7 +732,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))
@@ -748,12 +741,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 struct crypto_template crypto_gcm_base_tmpl = {