Back to home page

LXR

 
 

    


0001 /*
0002  * Authenc: Simple AEAD wrapper for IPsec
0003  *
0004  * Copyright (c) 2007-2015 Herbert Xu <herbert@gondor.apana.org.au>
0005  *
0006  * This program is free software; you can redistribute it and/or modify it
0007  * under the terms of the GNU General Public License as published by the Free
0008  * Software Foundation; either version 2 of the License, or (at your option)
0009  * any later version.
0010  *
0011  */
0012 
0013 #include <crypto/internal/aead.h>
0014 #include <crypto/internal/hash.h>
0015 #include <crypto/internal/skcipher.h>
0016 #include <crypto/authenc.h>
0017 #include <crypto/null.h>
0018 #include <crypto/scatterwalk.h>
0019 #include <linux/err.h>
0020 #include <linux/init.h>
0021 #include <linux/kernel.h>
0022 #include <linux/module.h>
0023 #include <linux/rtnetlink.h>
0024 #include <linux/slab.h>
0025 #include <linux/spinlock.h>
0026 
0027 struct authenc_instance_ctx {
0028     struct crypto_ahash_spawn auth;
0029     struct crypto_skcipher_spawn enc;
0030     unsigned int reqoff;
0031 };
0032 
0033 struct crypto_authenc_ctx {
0034     struct crypto_ahash *auth;
0035     struct crypto_skcipher *enc;
0036     struct crypto_skcipher *null;
0037 };
0038 
0039 struct authenc_request_ctx {
0040     struct scatterlist src[2];
0041     struct scatterlist dst[2];
0042     char tail[];
0043 };
0044 
0045 static void authenc_request_complete(struct aead_request *req, int err)
0046 {
0047     if (err != -EINPROGRESS)
0048         aead_request_complete(req, err);
0049 }
0050 
0051 int crypto_authenc_extractkeys(struct crypto_authenc_keys *keys, const u8 *key,
0052                    unsigned int keylen)
0053 {
0054     struct rtattr *rta = (struct rtattr *)key;
0055     struct crypto_authenc_key_param *param;
0056 
0057     if (!RTA_OK(rta, keylen))
0058         return -EINVAL;
0059     if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
0060         return -EINVAL;
0061     if (RTA_PAYLOAD(rta) < sizeof(*param))
0062         return -EINVAL;
0063 
0064     param = RTA_DATA(rta);
0065     keys->enckeylen = be32_to_cpu(param->enckeylen);
0066 
0067     key += RTA_ALIGN(rta->rta_len);
0068     keylen -= RTA_ALIGN(rta->rta_len);
0069 
0070     if (keylen < keys->enckeylen)
0071         return -EINVAL;
0072 
0073     keys->authkeylen = keylen - keys->enckeylen;
0074     keys->authkey = key;
0075     keys->enckey = key + keys->authkeylen;
0076 
0077     return 0;
0078 }
0079 EXPORT_SYMBOL_GPL(crypto_authenc_extractkeys);
0080 
0081 static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key,
0082                  unsigned int keylen)
0083 {
0084     struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
0085     struct crypto_ahash *auth = ctx->auth;
0086     struct crypto_skcipher *enc = ctx->enc;
0087     struct crypto_authenc_keys keys;
0088     int err = -EINVAL;
0089 
0090     if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
0091         goto badkey;
0092 
0093     crypto_ahash_clear_flags(auth, CRYPTO_TFM_REQ_MASK);
0094     crypto_ahash_set_flags(auth, crypto_aead_get_flags(authenc) &
0095                     CRYPTO_TFM_REQ_MASK);
0096     err = crypto_ahash_setkey(auth, keys.authkey, keys.authkeylen);
0097     crypto_aead_set_flags(authenc, crypto_ahash_get_flags(auth) &
0098                        CRYPTO_TFM_RES_MASK);
0099 
0100     if (err)
0101         goto out;
0102 
0103     crypto_skcipher_clear_flags(enc, CRYPTO_TFM_REQ_MASK);
0104     crypto_skcipher_set_flags(enc, crypto_aead_get_flags(authenc) &
0105                        CRYPTO_TFM_REQ_MASK);
0106     err = crypto_skcipher_setkey(enc, keys.enckey, keys.enckeylen);
0107     crypto_aead_set_flags(authenc, crypto_skcipher_get_flags(enc) &
0108                        CRYPTO_TFM_RES_MASK);
0109 
0110 out:
0111     return err;
0112 
0113 badkey:
0114     crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN);
0115     goto out;
0116 }
0117 
0118 static void authenc_geniv_ahash_done(struct crypto_async_request *areq, int err)
0119 {
0120     struct aead_request *req = areq->data;
0121     struct crypto_aead *authenc = crypto_aead_reqtfm(req);
0122     struct aead_instance *inst = aead_alg_instance(authenc);
0123     struct authenc_instance_ctx *ictx = aead_instance_ctx(inst);
0124     struct authenc_request_ctx *areq_ctx = aead_request_ctx(req);
0125     struct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff);
0126 
0127     if (err)
0128         goto out;
0129 
0130     scatterwalk_map_and_copy(ahreq->result, req->dst,
0131                  req->assoclen + req->cryptlen,
0132                  crypto_aead_authsize(authenc), 1);
0133 
0134 out:
0135     aead_request_complete(req, err);
0136 }
0137 
0138 static int crypto_authenc_genicv(struct aead_request *req, unsigned int flags)
0139 {
0140     struct crypto_aead *authenc = crypto_aead_reqtfm(req);
0141     struct aead_instance *inst = aead_alg_instance(authenc);
0142     struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
0143     struct authenc_instance_ctx *ictx = aead_instance_ctx(inst);
0144     struct crypto_ahash *auth = ctx->auth;
0145     struct authenc_request_ctx *areq_ctx = aead_request_ctx(req);
0146     struct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff);
0147     u8 *hash = areq_ctx->tail;
0148     int err;
0149 
0150     hash = (u8 *)ALIGN((unsigned long)hash + crypto_ahash_alignmask(auth),
0151                crypto_ahash_alignmask(auth) + 1);
0152 
0153     ahash_request_set_tfm(ahreq, auth);
0154     ahash_request_set_crypt(ahreq, req->dst, hash,
0155                 req->assoclen + req->cryptlen);
0156     ahash_request_set_callback(ahreq, flags,
0157                    authenc_geniv_ahash_done, req);
0158 
0159     err = crypto_ahash_digest(ahreq);
0160     if (err)
0161         return err;
0162 
0163     scatterwalk_map_and_copy(hash, req->dst, req->assoclen + req->cryptlen,
0164                  crypto_aead_authsize(authenc), 1);
0165 
0166     return 0;
0167 }
0168 
0169 static void crypto_authenc_encrypt_done(struct crypto_async_request *req,
0170                     int err)
0171 {
0172     struct aead_request *areq = req->data;
0173 
0174     if (err)
0175         goto out;
0176 
0177     err = crypto_authenc_genicv(areq, 0);
0178 
0179 out:
0180     authenc_request_complete(areq, err);
0181 }
0182 
0183 static int crypto_authenc_copy_assoc(struct aead_request *req)
0184 {
0185     struct crypto_aead *authenc = crypto_aead_reqtfm(req);
0186     struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
0187     SKCIPHER_REQUEST_ON_STACK(skreq, ctx->null);
0188 
0189     skcipher_request_set_tfm(skreq, ctx->null);
0190     skcipher_request_set_callback(skreq, aead_request_flags(req),
0191                       NULL, NULL);
0192     skcipher_request_set_crypt(skreq, req->src, req->dst, req->assoclen,
0193                    NULL);
0194 
0195     return crypto_skcipher_encrypt(skreq);
0196 }
0197 
0198 static int crypto_authenc_encrypt(struct aead_request *req)
0199 {
0200     struct crypto_aead *authenc = crypto_aead_reqtfm(req);
0201     struct aead_instance *inst = aead_alg_instance(authenc);
0202     struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
0203     struct authenc_instance_ctx *ictx = aead_instance_ctx(inst);
0204     struct authenc_request_ctx *areq_ctx = aead_request_ctx(req);
0205     struct crypto_skcipher *enc = ctx->enc;
0206     unsigned int cryptlen = req->cryptlen;
0207     struct skcipher_request *skreq = (void *)(areq_ctx->tail +
0208                           ictx->reqoff);
0209     struct scatterlist *src, *dst;
0210     int err;
0211 
0212     src = scatterwalk_ffwd(areq_ctx->src, req->src, req->assoclen);
0213     dst = src;
0214 
0215     if (req->src != req->dst) {
0216         err = crypto_authenc_copy_assoc(req);
0217         if (err)
0218             return err;
0219 
0220         dst = scatterwalk_ffwd(areq_ctx->dst, req->dst, req->assoclen);
0221     }
0222 
0223     skcipher_request_set_tfm(skreq, enc);
0224     skcipher_request_set_callback(skreq, aead_request_flags(req),
0225                       crypto_authenc_encrypt_done, req);
0226     skcipher_request_set_crypt(skreq, src, dst, cryptlen, req->iv);
0227 
0228     err = crypto_skcipher_encrypt(skreq);
0229     if (err)
0230         return err;
0231 
0232     return crypto_authenc_genicv(req, aead_request_flags(req));
0233 }
0234 
0235 static int crypto_authenc_decrypt_tail(struct aead_request *req,
0236                        unsigned int flags)
0237 {
0238     struct crypto_aead *authenc = crypto_aead_reqtfm(req);
0239     struct aead_instance *inst = aead_alg_instance(authenc);
0240     struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
0241     struct authenc_instance_ctx *ictx = aead_instance_ctx(inst);
0242     struct authenc_request_ctx *areq_ctx = aead_request_ctx(req);
0243     struct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff);
0244     struct skcipher_request *skreq = (void *)(areq_ctx->tail +
0245                           ictx->reqoff);
0246     unsigned int authsize = crypto_aead_authsize(authenc);
0247     u8 *ihash = ahreq->result + authsize;
0248     struct scatterlist *src, *dst;
0249 
0250     scatterwalk_map_and_copy(ihash, req->src, ahreq->nbytes, authsize, 0);
0251 
0252     if (crypto_memneq(ihash, ahreq->result, authsize))
0253         return -EBADMSG;
0254 
0255     src = scatterwalk_ffwd(areq_ctx->src, req->src, req->assoclen);
0256     dst = src;
0257 
0258     if (req->src != req->dst)
0259         dst = scatterwalk_ffwd(areq_ctx->dst, req->dst, req->assoclen);
0260 
0261     skcipher_request_set_tfm(skreq, ctx->enc);
0262     skcipher_request_set_callback(skreq, aead_request_flags(req),
0263                       req->base.complete, req->base.data);
0264     skcipher_request_set_crypt(skreq, src, dst,
0265                    req->cryptlen - authsize, req->iv);
0266 
0267     return crypto_skcipher_decrypt(skreq);
0268 }
0269 
0270 static void authenc_verify_ahash_done(struct crypto_async_request *areq,
0271                       int err)
0272 {
0273     struct aead_request *req = areq->data;
0274 
0275     if (err)
0276         goto out;
0277 
0278     err = crypto_authenc_decrypt_tail(req, 0);
0279 
0280 out:
0281     authenc_request_complete(req, err);
0282 }
0283 
0284 static int crypto_authenc_decrypt(struct aead_request *req)
0285 {
0286     struct crypto_aead *authenc = crypto_aead_reqtfm(req);
0287     unsigned int authsize = crypto_aead_authsize(authenc);
0288     struct aead_instance *inst = aead_alg_instance(authenc);
0289     struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
0290     struct authenc_instance_ctx *ictx = aead_instance_ctx(inst);
0291     struct crypto_ahash *auth = ctx->auth;
0292     struct authenc_request_ctx *areq_ctx = aead_request_ctx(req);
0293     struct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff);
0294     u8 *hash = areq_ctx->tail;
0295     int err;
0296 
0297     hash = (u8 *)ALIGN((unsigned long)hash + crypto_ahash_alignmask(auth),
0298                crypto_ahash_alignmask(auth) + 1);
0299 
0300     ahash_request_set_tfm(ahreq, auth);
0301     ahash_request_set_crypt(ahreq, req->src, hash,
0302                 req->assoclen + req->cryptlen - authsize);
0303     ahash_request_set_callback(ahreq, aead_request_flags(req),
0304                    authenc_verify_ahash_done, req);
0305 
0306     err = crypto_ahash_digest(ahreq);
0307     if (err)
0308         return err;
0309 
0310     return crypto_authenc_decrypt_tail(req, aead_request_flags(req));
0311 }
0312 
0313 static int crypto_authenc_init_tfm(struct crypto_aead *tfm)
0314 {
0315     struct aead_instance *inst = aead_alg_instance(tfm);
0316     struct authenc_instance_ctx *ictx = aead_instance_ctx(inst);
0317     struct crypto_authenc_ctx *ctx = crypto_aead_ctx(tfm);
0318     struct crypto_ahash *auth;
0319     struct crypto_skcipher *enc;
0320     struct crypto_skcipher *null;
0321     int err;
0322 
0323     auth = crypto_spawn_ahash(&ictx->auth);
0324     if (IS_ERR(auth))
0325         return PTR_ERR(auth);
0326 
0327     enc = crypto_spawn_skcipher(&ictx->enc);
0328     err = PTR_ERR(enc);
0329     if (IS_ERR(enc))
0330         goto err_free_ahash;
0331 
0332     null = crypto_get_default_null_skcipher2();
0333     err = PTR_ERR(null);
0334     if (IS_ERR(null))
0335         goto err_free_skcipher;
0336 
0337     ctx->auth = auth;
0338     ctx->enc = enc;
0339     ctx->null = null;
0340 
0341     crypto_aead_set_reqsize(
0342         tfm,
0343         sizeof(struct authenc_request_ctx) +
0344         ictx->reqoff +
0345         max_t(unsigned int,
0346               crypto_ahash_reqsize(auth) +
0347               sizeof(struct ahash_request),
0348               sizeof(struct skcipher_request) +
0349               crypto_skcipher_reqsize(enc)));
0350 
0351     return 0;
0352 
0353 err_free_skcipher:
0354     crypto_free_skcipher(enc);
0355 err_free_ahash:
0356     crypto_free_ahash(auth);
0357     return err;
0358 }
0359 
0360 static void crypto_authenc_exit_tfm(struct crypto_aead *tfm)
0361 {
0362     struct crypto_authenc_ctx *ctx = crypto_aead_ctx(tfm);
0363 
0364     crypto_free_ahash(ctx->auth);
0365     crypto_free_skcipher(ctx->enc);
0366     crypto_put_default_null_skcipher2();
0367 }
0368 
0369 static void crypto_authenc_free(struct aead_instance *inst)
0370 {
0371     struct authenc_instance_ctx *ctx = aead_instance_ctx(inst);
0372 
0373     crypto_drop_skcipher(&ctx->enc);
0374     crypto_drop_ahash(&ctx->auth);
0375     kfree(inst);
0376 }
0377 
0378 static int crypto_authenc_create(struct crypto_template *tmpl,
0379                  struct rtattr **tb)
0380 {
0381     struct crypto_attr_type *algt;
0382     struct aead_instance *inst;
0383     struct hash_alg_common *auth;
0384     struct crypto_alg *auth_base;
0385     struct skcipher_alg *enc;
0386     struct authenc_instance_ctx *ctx;
0387     const char *enc_name;
0388     int err;
0389 
0390     algt = crypto_get_attr_type(tb);
0391     if (IS_ERR(algt))
0392         return PTR_ERR(algt);
0393 
0394     if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
0395         return -EINVAL;
0396 
0397     auth = ahash_attr_alg(tb[1], CRYPTO_ALG_TYPE_HASH,
0398                   CRYPTO_ALG_TYPE_AHASH_MASK |
0399                   crypto_requires_sync(algt->type, algt->mask));
0400     if (IS_ERR(auth))
0401         return PTR_ERR(auth);
0402 
0403     auth_base = &auth->base;
0404 
0405     enc_name = crypto_attr_alg_name(tb[2]);
0406     err = PTR_ERR(enc_name);
0407     if (IS_ERR(enc_name))
0408         goto out_put_auth;
0409 
0410     inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
0411     err = -ENOMEM;
0412     if (!inst)
0413         goto out_put_auth;
0414 
0415     ctx = aead_instance_ctx(inst);
0416 
0417     err = crypto_init_ahash_spawn(&ctx->auth, auth,
0418                       aead_crypto_instance(inst));
0419     if (err)
0420         goto err_free_inst;
0421 
0422     crypto_set_skcipher_spawn(&ctx->enc, aead_crypto_instance(inst));
0423     err = crypto_grab_skcipher(&ctx->enc, enc_name, 0,
0424                    crypto_requires_sync(algt->type,
0425                             algt->mask));
0426     if (err)
0427         goto err_drop_auth;
0428 
0429     enc = crypto_spawn_skcipher_alg(&ctx->enc);
0430 
0431     ctx->reqoff = ALIGN(2 * auth->digestsize + auth_base->cra_alignmask,
0432                 auth_base->cra_alignmask + 1);
0433 
0434     err = -ENAMETOOLONG;
0435     if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
0436              "authenc(%s,%s)", auth_base->cra_name,
0437              enc->base.cra_name) >=
0438         CRYPTO_MAX_ALG_NAME)
0439         goto err_drop_enc;
0440 
0441     if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
0442              "authenc(%s,%s)", auth_base->cra_driver_name,
0443              enc->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
0444         goto err_drop_enc;
0445 
0446     inst->alg.base.cra_flags = (auth_base->cra_flags |
0447                     enc->base.cra_flags) & CRYPTO_ALG_ASYNC;
0448     inst->alg.base.cra_priority = enc->base.cra_priority * 10 +
0449                       auth_base->cra_priority;
0450     inst->alg.base.cra_blocksize = enc->base.cra_blocksize;
0451     inst->alg.base.cra_alignmask = auth_base->cra_alignmask |
0452                        enc->base.cra_alignmask;
0453     inst->alg.base.cra_ctxsize = sizeof(struct crypto_authenc_ctx);
0454 
0455     inst->alg.ivsize = crypto_skcipher_alg_ivsize(enc);
0456     inst->alg.chunksize = crypto_skcipher_alg_chunksize(enc);
0457     inst->alg.maxauthsize = auth->digestsize;
0458 
0459     inst->alg.init = crypto_authenc_init_tfm;
0460     inst->alg.exit = crypto_authenc_exit_tfm;
0461 
0462     inst->alg.setkey = crypto_authenc_setkey;
0463     inst->alg.encrypt = crypto_authenc_encrypt;
0464     inst->alg.decrypt = crypto_authenc_decrypt;
0465 
0466     inst->free = crypto_authenc_free;
0467 
0468     err = aead_register_instance(tmpl, inst);
0469     if (err)
0470         goto err_drop_enc;
0471 
0472 out:
0473     crypto_mod_put(auth_base);
0474     return err;
0475 
0476 err_drop_enc:
0477     crypto_drop_skcipher(&ctx->enc);
0478 err_drop_auth:
0479     crypto_drop_ahash(&ctx->auth);
0480 err_free_inst:
0481     kfree(inst);
0482 out_put_auth:
0483     goto out;
0484 }
0485 
0486 static struct crypto_template crypto_authenc_tmpl = {
0487     .name = "authenc",
0488     .create = crypto_authenc_create,
0489     .module = THIS_MODULE,
0490 };
0491 
0492 static int __init crypto_authenc_module_init(void)
0493 {
0494     return crypto_register_template(&crypto_authenc_tmpl);
0495 }
0496 
0497 static void __exit crypto_authenc_module_exit(void)
0498 {
0499     crypto_unregister_template(&crypto_authenc_tmpl);
0500 }
0501 
0502 module_init(crypto_authenc_module_init);
0503 module_exit(crypto_authenc_module_exit);
0504 
0505 MODULE_LICENSE("GPL");
0506 MODULE_DESCRIPTION("Simple AEAD wrapper for IPsec");
0507 MODULE_ALIAS_CRYPTO("authenc");