static struct crypto_instance *crypto_ccm_alloc_common(struct rtattr **tb, const char *full_name, const char *ctr_name, const char *cipher_name) { struct crypto_attr_type *algt; struct crypto_instance *inst; struct crypto_alg *ctr; struct crypto_alg *cipher; struct ccm_instance_ctx *ictx; int err; algt = crypto_get_attr_type(tb); if (IS_ERR(algt)) return ERR_CAST(algt); if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask) return ERR_PTR(-EINVAL); cipher = crypto_alg_mod_lookup(cipher_name, CRYPTO_ALG_TYPE_CIPHER, CRYPTO_ALG_TYPE_MASK); if (IS_ERR(cipher)) return ERR_CAST(cipher); err = -EINVAL; if (cipher->cra_blocksize != 16) goto out_put_cipher; inst = kzalloc(sizeof(*inst) + sizeof(*ictx), GFP_KERNEL); err = -ENOMEM; if (!inst) goto out_put_cipher; ictx = crypto_instance_ctx(inst); err = crypto_init_spawn(&ictx->cipher, cipher, inst, CRYPTO_ALG_TYPE_MASK); if (err) goto err_free_inst; crypto_set_skcipher_spawn(&ictx->ctr, inst); err = crypto_grab_skcipher(&ictx->ctr, ctr_name, 0, crypto_requires_sync(algt->type, algt->mask)); if (err) goto err_drop_cipher; ctr = crypto_skcipher_spawn_alg(&ictx->ctr); /* Not a stream cipher? */ err = -EINVAL; if (ctr->cra_blocksize != 1) goto err_drop_ctr; /* We want the real thing! */ if (ctr->cra_ablkcipher.ivsize != 16) goto err_drop_ctr; err = -ENAMETOOLONG; if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, "ccm_base(%s,%s)", ctr->cra_driver_name, cipher->cra_driver_name) >= CRYPTO_MAX_ALG_NAME) goto err_drop_ctr; memcpy(inst->alg.cra_name, full_name, CRYPTO_MAX_ALG_NAME); inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD; inst->alg.cra_flags |= ctr->cra_flags & CRYPTO_ALG_ASYNC; inst->alg.cra_priority = cipher->cra_priority + ctr->cra_priority; inst->alg.cra_blocksize = 1; inst->alg.cra_alignmask = cipher->cra_alignmask | ctr->cra_alignmask | (__alignof__(u32) - 1); inst->alg.cra_type = &crypto_aead_type; inst->alg.cra_aead.ivsize = 16; inst->alg.cra_aead.maxauthsize = 16; inst->alg.cra_ctxsize = sizeof(struct crypto_ccm_ctx); inst->alg.cra_init = crypto_ccm_init_tfm; inst->alg.cra_exit = crypto_ccm_exit_tfm; inst->alg.cra_aead.setkey = crypto_ccm_setkey; inst->alg.cra_aead.setauthsize = crypto_ccm_setauthsize; inst->alg.cra_aead.encrypt = crypto_ccm_encrypt; inst->alg.cra_aead.decrypt = crypto_ccm_decrypt; out: crypto_mod_put(cipher); return inst; err_drop_ctr: crypto_drop_skcipher(&ictx->ctr); err_drop_cipher: crypto_drop_spawn(&ictx->cipher); err_free_inst: kfree(inst); out_put_cipher: inst = ERR_PTR(err); goto out; }
static struct crypto_instance *crypto_gcm_alloc_common(struct rtattr **tb, const char *full_name, const char *ctr_name, const char *ghash_name) { struct crypto_attr_type *algt; struct crypto_instance *inst; struct crypto_alg *ctr; struct crypto_alg *ghash_alg; struct ahash_alg *ghash_ahash_alg; struct gcm_instance_ctx *ctx; int err; algt = crypto_get_attr_type(tb); if (IS_ERR(algt)) return ERR_CAST(algt); if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask) return ERR_PTR(-EINVAL); ghash_alg = crypto_find_alg(ghash_name, &crypto_ahash_type, CRYPTO_ALG_TYPE_HASH, CRYPTO_ALG_TYPE_AHASH_MASK | crypto_requires_sync(algt->type, algt->mask)); if (IS_ERR(ghash_alg)) return ERR_CAST(ghash_alg); err = -ENOMEM; inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); if (!inst) goto out_put_ghash; ctx = crypto_instance_ctx(inst); ghash_ahash_alg = container_of(ghash_alg, struct ahash_alg, halg.base); err = crypto_init_ahash_spawn(&ctx->ghash, &ghash_ahash_alg->halg, inst); if (err) goto err_free_inst; crypto_set_skcipher_spawn(&ctx->ctr, inst); err = crypto_grab_skcipher(&ctx->ctr, ctr_name, 0, crypto_requires_sync(algt->type, algt->mask)); if (err) goto err_drop_ghash; ctr = crypto_skcipher_spawn_alg(&ctx->ctr); /* We only support 16-byte blocks. */ if (ctr->cra_ablkcipher.ivsize != 16) goto out_put_ctr; /* Not a stream cipher? */ err = -EINVAL; if (ctr->cra_blocksize != 1) goto out_put_ctr; err = -ENAMETOOLONG; if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, "gcm_base(%s,%s)", ctr->cra_driver_name, ghash_alg->cra_driver_name) >= CRYPTO_MAX_ALG_NAME) goto out_put_ctr; memcpy(inst->alg.cra_name, full_name, CRYPTO_MAX_ALG_NAME); inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD; inst->alg.cra_flags |= ctr->cra_flags & CRYPTO_ALG_ASYNC; inst->alg.cra_priority = ctr->cra_priority; inst->alg.cra_blocksize = 1; inst->alg.cra_alignmask = ctr->cra_alignmask | (__alignof__(u64) - 1); inst->alg.cra_type = &crypto_aead_type; inst->alg.cra_aead.ivsize = 16; inst->alg.cra_aead.maxauthsize = 16; inst->alg.cra_ctxsize = sizeof(struct crypto_gcm_ctx); inst->alg.cra_init = crypto_gcm_init_tfm; inst->alg.cra_exit = crypto_gcm_exit_tfm; inst->alg.cra_aead.setkey = crypto_gcm_setkey; inst->alg.cra_aead.setauthsize = crypto_gcm_setauthsize; inst->alg.cra_aead.encrypt = crypto_gcm_encrypt; inst->alg.cra_aead.decrypt = crypto_gcm_decrypt; out: crypto_mod_put(ghash_alg); return inst; out_put_ctr: crypto_drop_skcipher(&ctx->ctr); err_drop_ghash: crypto_drop_ahash(&ctx->ghash); err_free_inst: kfree(inst); out_put_ghash: inst = ERR_PTR(err); goto out; }
static struct crypto_instance *crypto_rfc4543_alloc(struct rtattr **tb) { struct crypto_attr_type *algt; struct crypto_instance *inst; struct crypto_aead_spawn *spawn; struct crypto_alg *alg; struct crypto_rfc4543_instance_ctx *ctx; const char *ccm_name; int err; algt = crypto_get_attr_type(tb); if (IS_ERR(algt)) return ERR_CAST(algt); if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask) return ERR_PTR(-EINVAL); ccm_name = crypto_attr_alg_name(tb[1]); if (IS_ERR(ccm_name)) return ERR_CAST(ccm_name); inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); if (!inst) return ERR_PTR(-ENOMEM); ctx = crypto_instance_ctx(inst); spawn = &ctx->aead; crypto_set_aead_spawn(spawn, inst); err = crypto_grab_aead(spawn, ccm_name, 0, crypto_requires_sync(algt->type, algt->mask)); if (err) goto out_free_inst; alg = crypto_aead_spawn_alg(spawn); crypto_set_skcipher_spawn(&ctx->null, inst); err = crypto_grab_skcipher(&ctx->null, "ecb(cipher_null)", 0, CRYPTO_ALG_ASYNC); if (err) goto out_drop_alg; crypto_skcipher_spawn_alg(&ctx->null); err = -EINVAL; /* We only support 16-byte blocks. */ if (alg->cra_aead.ivsize != 16) goto out_drop_ecbnull; /* Not a stream cipher? */ if (alg->cra_blocksize != 1) goto out_drop_ecbnull; err = -ENAMETOOLONG; if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, "rfc4543(%s)", alg->cra_name) >= CRYPTO_MAX_ALG_NAME || snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, "rfc4543(%s)", alg->cra_driver_name) >= CRYPTO_MAX_ALG_NAME) goto out_drop_ecbnull; inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD; inst->alg.cra_flags |= alg->cra_flags & CRYPTO_ALG_ASYNC; inst->alg.cra_priority = alg->cra_priority; inst->alg.cra_blocksize = 1; inst->alg.cra_alignmask = alg->cra_alignmask; inst->alg.cra_type = &crypto_nivaead_type; inst->alg.cra_aead.ivsize = 8; inst->alg.cra_aead.maxauthsize = 16; inst->alg.cra_ctxsize = sizeof(struct crypto_rfc4543_ctx); inst->alg.cra_init = crypto_rfc4543_init_tfm; inst->alg.cra_exit = crypto_rfc4543_exit_tfm; inst->alg.cra_aead.setkey = crypto_rfc4543_setkey; inst->alg.cra_aead.setauthsize = crypto_rfc4543_setauthsize; inst->alg.cra_aead.encrypt = crypto_rfc4543_encrypt; inst->alg.cra_aead.decrypt = crypto_rfc4543_decrypt; inst->alg.cra_aead.geniv = "seqiv"; out: return inst; out_drop_ecbnull: crypto_drop_skcipher(&ctx->null); out_drop_alg: crypto_drop_aead(spawn); out_free_inst: kfree(inst); inst = ERR_PTR(err); goto out; }
static struct crypto_instance *crypto_rfc3686_alloc(struct rtattr **tb) { struct crypto_attr_type *algt; struct crypto_instance *inst; struct crypto_alg *alg; struct crypto_skcipher_spawn *spawn; const char *cipher_name; int err; algt = crypto_get_attr_type(tb); if (IS_ERR(algt)) return ERR_CAST(algt); if ((algt->type ^ CRYPTO_ALG_TYPE_BLKCIPHER) & algt->mask) return ERR_PTR(-EINVAL); cipher_name = crypto_attr_alg_name(tb[1]); if (IS_ERR(cipher_name)) return ERR_CAST(cipher_name); inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); if (!inst) return ERR_PTR(-ENOMEM); spawn = crypto_instance_ctx(inst); crypto_set_skcipher_spawn(spawn, inst); err = crypto_grab_skcipher(spawn, cipher_name, 0, crypto_requires_sync(algt->type, algt->mask)); if (err) goto err_free_inst; alg = crypto_skcipher_spawn_alg(spawn); /* We only support 16-byte blocks. */ err = -EINVAL; if (alg->cra_ablkcipher.ivsize != CTR_RFC3686_BLOCK_SIZE) goto err_drop_spawn; /* Not a stream cipher? */ if (alg->cra_blocksize != 1) goto err_drop_spawn; err = -ENAMETOOLONG; if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, "rfc3686(%s)", alg->cra_name) >= CRYPTO_MAX_ALG_NAME) goto err_drop_spawn; if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, "rfc3686(%s)", alg->cra_driver_name) >= CRYPTO_MAX_ALG_NAME) goto err_drop_spawn; inst->alg.cra_priority = alg->cra_priority; inst->alg.cra_blocksize = 1; inst->alg.cra_alignmask = alg->cra_alignmask; inst->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | (alg->cra_flags & CRYPTO_ALG_ASYNC); inst->alg.cra_type = &crypto_ablkcipher_type; inst->alg.cra_ablkcipher.ivsize = CTR_RFC3686_IV_SIZE; inst->alg.cra_ablkcipher.min_keysize = alg->cra_ablkcipher.min_keysize + CTR_RFC3686_NONCE_SIZE; inst->alg.cra_ablkcipher.max_keysize = alg->cra_ablkcipher.max_keysize + CTR_RFC3686_NONCE_SIZE; inst->alg.cra_ablkcipher.geniv = "seqiv"; inst->alg.cra_ablkcipher.setkey = crypto_rfc3686_setkey; inst->alg.cra_ablkcipher.encrypt = crypto_rfc3686_crypt; inst->alg.cra_ablkcipher.decrypt = crypto_rfc3686_crypt; inst->alg.cra_ctxsize = sizeof(struct crypto_rfc3686_ctx); inst->alg.cra_init = crypto_rfc3686_init_tfm; inst->alg.cra_exit = crypto_rfc3686_exit_tfm; return inst; err_drop_spawn: crypto_drop_skcipher(spawn); err_free_inst: kfree(inst); return ERR_PTR(err); }
static int create(struct crypto_template *tmpl, struct rtattr **tb) { struct crypto_skcipher_spawn *spawn; struct skcipher_instance *inst; struct crypto_attr_type *algt; struct skcipher_alg *alg; const char *cipher_name; char ecb_name[CRYPTO_MAX_ALG_NAME]; int err; algt = crypto_get_attr_type(tb); if (IS_ERR(algt)) return PTR_ERR(algt); if ((algt->type ^ CRYPTO_ALG_TYPE_SKCIPHER) & algt->mask) return -EINVAL; cipher_name = crypto_attr_alg_name(tb[1]); if (IS_ERR(cipher_name)) return PTR_ERR(cipher_name); inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); if (!inst) return -ENOMEM; spawn = skcipher_instance_ctx(inst); crypto_set_skcipher_spawn(spawn, skcipher_crypto_instance(inst)); err = crypto_grab_skcipher(spawn, cipher_name, 0, crypto_requires_sync(algt->type, algt->mask)); if (err == -ENOENT) { err = -ENAMETOOLONG; if (snprintf(ecb_name, CRYPTO_MAX_ALG_NAME, "ecb(%s)", cipher_name) >= CRYPTO_MAX_ALG_NAME) goto err_free_inst; err = crypto_grab_skcipher(spawn, ecb_name, 0, crypto_requires_sync(algt->type, algt->mask)); } if (err) goto err_free_inst; alg = crypto_skcipher_spawn_alg(spawn); err = -EINVAL; if (alg->base.cra_blocksize != LRW_BLOCK_SIZE) goto err_drop_spawn; if (crypto_skcipher_alg_ivsize(alg)) goto err_drop_spawn; err = crypto_inst_setname(skcipher_crypto_instance(inst), "lrw", &alg->base); if (err) goto err_drop_spawn; err = -EINVAL; cipher_name = alg->base.cra_name; /* Alas we screwed up the naming so we have to mangle the * cipher name. */ if (!strncmp(cipher_name, "ecb(", 4)) { unsigned len; len = strlcpy(ecb_name, cipher_name + 4, sizeof(ecb_name)); if (len < 2 || len >= sizeof(ecb_name)) goto err_drop_spawn; if (ecb_name[len - 1] != ')') goto err_drop_spawn; ecb_name[len - 1] = 0; if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, "lrw(%s)", ecb_name) >= CRYPTO_MAX_ALG_NAME) { err = -ENAMETOOLONG; goto err_drop_spawn; } } else goto err_drop_spawn; inst->alg.base.cra_flags = alg->base.cra_flags & CRYPTO_ALG_ASYNC; inst->alg.base.cra_priority = alg->base.cra_priority; inst->alg.base.cra_blocksize = LRW_BLOCK_SIZE; inst->alg.base.cra_alignmask = alg->base.cra_alignmask | (__alignof__(__be32) - 1); inst->alg.ivsize = LRW_BLOCK_SIZE; inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(alg) + LRW_BLOCK_SIZE; inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(alg) + LRW_BLOCK_SIZE; inst->alg.base.cra_ctxsize = sizeof(struct priv); inst->alg.init = init_tfm; inst->alg.exit = exit_tfm; inst->alg.setkey = setkey; inst->alg.encrypt = encrypt; inst->alg.decrypt = decrypt; inst->free = free; err = skcipher_register_instance(tmpl, inst); if (err) goto err_drop_spawn; out: return err; err_drop_spawn: crypto_drop_skcipher(spawn); err_free_inst: kfree(inst); goto out; }
static int crypto_rfc3686_create(struct crypto_template *tmpl, struct rtattr **tb) { struct crypto_attr_type *algt; struct skcipher_instance *inst; struct skcipher_alg *alg; struct crypto_skcipher_spawn *spawn; const char *cipher_name; int err; algt = crypto_get_attr_type(tb); if (IS_ERR(algt)) return PTR_ERR(algt); if ((algt->type ^ CRYPTO_ALG_TYPE_SKCIPHER) & algt->mask) return -EINVAL; cipher_name = crypto_attr_alg_name(tb[1]); if (IS_ERR(cipher_name)) return PTR_ERR(cipher_name); inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); if (!inst) return -ENOMEM; spawn = skcipher_instance_ctx(inst); crypto_set_skcipher_spawn(spawn, skcipher_crypto_instance(inst)); err = crypto_grab_skcipher(spawn, cipher_name, 0, crypto_requires_sync(algt->type, algt->mask)); if (err) goto err_free_inst; alg = crypto_spawn_skcipher_alg(spawn); /* We only support 16-byte blocks. */ err = -EINVAL; if (crypto_skcipher_alg_ivsize(alg) != CTR_RFC3686_BLOCK_SIZE) goto err_drop_spawn; /* Not a stream cipher? */ if (alg->base.cra_blocksize != 1) goto err_drop_spawn; err = -ENAMETOOLONG; if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, "rfc3686(%s)", alg->base.cra_name) >= CRYPTO_MAX_ALG_NAME) goto err_drop_spawn; if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME, "rfc3686(%s)", alg->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME) goto err_drop_spawn; inst->alg.base.cra_priority = alg->base.cra_priority; inst->alg.base.cra_blocksize = 1; inst->alg.base.cra_alignmask = alg->base.cra_alignmask; inst->alg.base.cra_flags = alg->base.cra_flags & CRYPTO_ALG_ASYNC; inst->alg.ivsize = CTR_RFC3686_IV_SIZE; inst->alg.chunksize = crypto_skcipher_alg_chunksize(alg); inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(alg) + CTR_RFC3686_NONCE_SIZE; inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(alg) + CTR_RFC3686_NONCE_SIZE; inst->alg.setkey = crypto_rfc3686_setkey; inst->alg.encrypt = crypto_rfc3686_crypt; inst->alg.decrypt = crypto_rfc3686_crypt; inst->alg.base.cra_ctxsize = sizeof(struct crypto_rfc3686_ctx); inst->alg.init = crypto_rfc3686_init_tfm; inst->alg.exit = crypto_rfc3686_exit_tfm; inst->free = crypto_rfc3686_free; err = skcipher_register_instance(tmpl, inst); if (err) goto err_drop_spawn; out: return err; err_drop_spawn: crypto_drop_skcipher(spawn); err_free_inst: kfree(inst); goto out; }