1/* 2 * Authenc: Simple AEAD wrapper for IPsec 3 * 4 * Copyright (c) 2007-2015 Herbert Xu <herbert@gondor.apana.org.au> 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the Free 8 * Software Foundation; either version 2 of the License, or (at your option) 9 * any later version. 10 * 11 */ 12 13#include <crypto/internal/aead.h> 14#include <crypto/internal/hash.h> 15#include <crypto/internal/skcipher.h> 16#include <crypto/authenc.h> 17#include <crypto/null.h> 18#include <crypto/scatterwalk.h> 19#include <linux/err.h> 20#include <linux/init.h> 21#include <linux/kernel.h> 22#include <linux/module.h> 23#include <linux/rtnetlink.h> 24#include <linux/slab.h> 25#include <linux/spinlock.h> 26 27struct authenc_instance_ctx { 28 struct crypto_ahash_spawn auth; 29 struct crypto_skcipher_spawn enc; 30 unsigned int reqoff; 31}; 32 33struct crypto_authenc_ctx { 34 struct crypto_ahash *auth; 35 struct crypto_ablkcipher *enc; 36 struct crypto_blkcipher *null; 37}; 38 39struct authenc_request_ctx { 40 struct scatterlist src[2]; 41 struct scatterlist dst[2]; 42 char tail[]; 43}; 44 45static void authenc_request_complete(struct aead_request *req, int err) 46{ 47 if (err != -EINPROGRESS) 48 aead_request_complete(req, err); 49} 50 51int crypto_authenc_extractkeys(struct crypto_authenc_keys *keys, const u8 *key, 52 unsigned int keylen) 53{ 54 struct rtattr *rta = (struct rtattr *)key; 55 struct crypto_authenc_key_param *param; 56 57 if (!RTA_OK(rta, keylen)) 58 return -EINVAL; 59 if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM) 60 return -EINVAL; 61 if (RTA_PAYLOAD(rta) < sizeof(*param)) 62 return -EINVAL; 63 64 param = RTA_DATA(rta); 65 keys->enckeylen = be32_to_cpu(param->enckeylen); 66 67 key += RTA_ALIGN(rta->rta_len); 68 keylen -= RTA_ALIGN(rta->rta_len); 69 70 if (keylen < keys->enckeylen) 71 return -EINVAL; 72 73 keys->authkeylen = keylen - keys->enckeylen; 74 keys->authkey = key; 75 keys->enckey = key + keys->authkeylen; 76 77 return 0; 78} 79EXPORT_SYMBOL_GPL(crypto_authenc_extractkeys); 80 81static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key, 82 unsigned int keylen) 83{ 84 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); 85 struct crypto_ahash *auth = ctx->auth; 86 struct crypto_ablkcipher *enc = ctx->enc; 87 struct crypto_authenc_keys keys; 88 int err = -EINVAL; 89 90 if (crypto_authenc_extractkeys(&keys, key, keylen) != 0) 91 goto badkey; 92 93 crypto_ahash_clear_flags(auth, CRYPTO_TFM_REQ_MASK); 94 crypto_ahash_set_flags(auth, crypto_aead_get_flags(authenc) & 95 CRYPTO_TFM_REQ_MASK); 96 err = crypto_ahash_setkey(auth, keys.authkey, keys.authkeylen); 97 crypto_aead_set_flags(authenc, crypto_ahash_get_flags(auth) & 98 CRYPTO_TFM_RES_MASK); 99 100 if (err) 101 goto out; 102 103 crypto_ablkcipher_clear_flags(enc, CRYPTO_TFM_REQ_MASK); 104 crypto_ablkcipher_set_flags(enc, crypto_aead_get_flags(authenc) & 105 CRYPTO_TFM_REQ_MASK); 106 err = crypto_ablkcipher_setkey(enc, keys.enckey, keys.enckeylen); 107 crypto_aead_set_flags(authenc, crypto_ablkcipher_get_flags(enc) & 108 CRYPTO_TFM_RES_MASK); 109 110out: 111 return err; 112 113badkey: 114 crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN); 115 goto out; 116} 117 118static void authenc_geniv_ahash_done(struct crypto_async_request *areq, int err) 119{ 120 struct aead_request *req = areq->data; 121 struct crypto_aead *authenc = crypto_aead_reqtfm(req); 122 struct aead_instance *inst = aead_alg_instance(authenc); 123 struct authenc_instance_ctx *ictx = aead_instance_ctx(inst); 124 struct authenc_request_ctx *areq_ctx = aead_request_ctx(req); 125 struct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff); 126 127 if (err) 128 goto out; 129 130 scatterwalk_map_and_copy(ahreq->result, req->dst, 131 req->assoclen + req->cryptlen, 132 crypto_aead_authsize(authenc), 1); 133 134out: 135 aead_request_complete(req, err); 136} 137 138static int crypto_authenc_genicv(struct aead_request *req, unsigned int flags) 139{ 140 struct crypto_aead *authenc = crypto_aead_reqtfm(req); 141 struct aead_instance *inst = aead_alg_instance(authenc); 142 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); 143 struct authenc_instance_ctx *ictx = aead_instance_ctx(inst); 144 struct crypto_ahash *auth = ctx->auth; 145 struct authenc_request_ctx *areq_ctx = aead_request_ctx(req); 146 struct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff); 147 u8 *hash = areq_ctx->tail; 148 int err; 149 150 hash = (u8 *)ALIGN((unsigned long)hash + crypto_ahash_alignmask(auth), 151 crypto_ahash_alignmask(auth) + 1); 152 153 ahash_request_set_tfm(ahreq, auth); 154 ahash_request_set_crypt(ahreq, req->dst, hash, 155 req->assoclen + req->cryptlen); 156 ahash_request_set_callback(ahreq, flags, 157 authenc_geniv_ahash_done, req); 158 159 err = crypto_ahash_digest(ahreq); 160 if (err) 161 return err; 162 163 scatterwalk_map_and_copy(hash, req->dst, req->assoclen + req->cryptlen, 164 crypto_aead_authsize(authenc), 1); 165 166 return 0; 167} 168 169static void crypto_authenc_encrypt_done(struct crypto_async_request *req, 170 int err) 171{ 172 struct aead_request *areq = req->data; 173 174 if (err) 175 goto out; 176 177 err = crypto_authenc_genicv(areq, 0); 178 179out: 180 authenc_request_complete(areq, err); 181} 182 183static int crypto_authenc_copy_assoc(struct aead_request *req) 184{ 185 struct crypto_aead *authenc = crypto_aead_reqtfm(req); 186 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); 187 struct blkcipher_desc desc = { 188 .tfm = ctx->null, 189 }; 190 191 return crypto_blkcipher_encrypt(&desc, req->dst, req->src, 192 req->assoclen); 193} 194 195static int crypto_authenc_encrypt(struct aead_request *req) 196{ 197 struct crypto_aead *authenc = crypto_aead_reqtfm(req); 198 struct aead_instance *inst = aead_alg_instance(authenc); 199 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); 200 struct authenc_instance_ctx *ictx = aead_instance_ctx(inst); 201 struct authenc_request_ctx *areq_ctx = aead_request_ctx(req); 202 struct crypto_ablkcipher *enc = ctx->enc; 203 unsigned int cryptlen = req->cryptlen; 204 struct ablkcipher_request *abreq = (void *)(areq_ctx->tail + 205 ictx->reqoff); 206 struct scatterlist *src, *dst; 207 int err; 208 209 sg_init_table(areq_ctx->src, 2); 210 src = scatterwalk_ffwd(areq_ctx->src, req->src, req->assoclen); 211 dst = src; 212 213 if (req->src != req->dst) { 214 err = crypto_authenc_copy_assoc(req); 215 if (err) 216 return err; 217 218 sg_init_table(areq_ctx->dst, 2); 219 dst = scatterwalk_ffwd(areq_ctx->dst, req->dst, req->assoclen); 220 } 221 222 ablkcipher_request_set_tfm(abreq, enc); 223 ablkcipher_request_set_callback(abreq, aead_request_flags(req), 224 crypto_authenc_encrypt_done, req); 225 ablkcipher_request_set_crypt(abreq, src, dst, cryptlen, req->iv); 226 227 err = crypto_ablkcipher_encrypt(abreq); 228 if (err) 229 return err; 230 231 return crypto_authenc_genicv(req, aead_request_flags(req)); 232} 233 234static int crypto_authenc_decrypt_tail(struct aead_request *req, 235 unsigned int flags) 236{ 237 struct crypto_aead *authenc = crypto_aead_reqtfm(req); 238 struct aead_instance *inst = aead_alg_instance(authenc); 239 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); 240 struct authenc_instance_ctx *ictx = aead_instance_ctx(inst); 241 struct authenc_request_ctx *areq_ctx = aead_request_ctx(req); 242 struct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff); 243 struct ablkcipher_request *abreq = (void *)(areq_ctx->tail + 244 ictx->reqoff); 245 unsigned int authsize = crypto_aead_authsize(authenc); 246 u8 *ihash = ahreq->result + authsize; 247 struct scatterlist *src, *dst; 248 249 scatterwalk_map_and_copy(ihash, req->src, ahreq->nbytes, authsize, 0); 250 251 if (crypto_memneq(ihash, ahreq->result, authsize)) 252 return -EBADMSG; 253 254 sg_init_table(areq_ctx->src, 2); 255 src = scatterwalk_ffwd(areq_ctx->src, req->src, req->assoclen); 256 dst = src; 257 258 if (req->src != req->dst) { 259 sg_init_table(areq_ctx->dst, 2); 260 dst = scatterwalk_ffwd(areq_ctx->dst, req->dst, req->assoclen); 261 } 262 263 ablkcipher_request_set_tfm(abreq, ctx->enc); 264 ablkcipher_request_set_callback(abreq, aead_request_flags(req), 265 req->base.complete, req->base.data); 266 ablkcipher_request_set_crypt(abreq, src, dst, 267 req->cryptlen - authsize, req->iv); 268 269 return crypto_ablkcipher_decrypt(abreq); 270} 271 272static void authenc_verify_ahash_done(struct crypto_async_request *areq, 273 int err) 274{ 275 struct aead_request *req = areq->data; 276 277 if (err) 278 goto out; 279 280 err = crypto_authenc_decrypt_tail(req, 0); 281 282out: 283 authenc_request_complete(req, err); 284} 285 286static int crypto_authenc_decrypt(struct aead_request *req) 287{ 288 struct crypto_aead *authenc = crypto_aead_reqtfm(req); 289 unsigned int authsize = crypto_aead_authsize(authenc); 290 struct aead_instance *inst = aead_alg_instance(authenc); 291 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); 292 struct authenc_instance_ctx *ictx = aead_instance_ctx(inst); 293 struct crypto_ahash *auth = ctx->auth; 294 struct authenc_request_ctx *areq_ctx = aead_request_ctx(req); 295 struct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff); 296 u8 *hash = areq_ctx->tail; 297 int err; 298 299 hash = (u8 *)ALIGN((unsigned long)hash + crypto_ahash_alignmask(auth), 300 crypto_ahash_alignmask(auth) + 1); 301 302 ahash_request_set_tfm(ahreq, auth); 303 ahash_request_set_crypt(ahreq, req->src, hash, 304 req->assoclen + req->cryptlen - authsize); 305 ahash_request_set_callback(ahreq, aead_request_flags(req), 306 authenc_verify_ahash_done, req); 307 308 err = crypto_ahash_digest(ahreq); 309 if (err) 310 return err; 311 312 return crypto_authenc_decrypt_tail(req, aead_request_flags(req)); 313} 314 315static int crypto_authenc_init_tfm(struct crypto_aead *tfm) 316{ 317 struct aead_instance *inst = aead_alg_instance(tfm); 318 struct authenc_instance_ctx *ictx = aead_instance_ctx(inst); 319 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(tfm); 320 struct crypto_ahash *auth; 321 struct crypto_ablkcipher *enc; 322 struct crypto_blkcipher *null; 323 int err; 324 325 auth = crypto_spawn_ahash(&ictx->auth); 326 if (IS_ERR(auth)) 327 return PTR_ERR(auth); 328 329 enc = crypto_spawn_skcipher(&ictx->enc); 330 err = PTR_ERR(enc); 331 if (IS_ERR(enc)) 332 goto err_free_ahash; 333 334 null = crypto_get_default_null_skcipher(); 335 err = PTR_ERR(null); 336 if (IS_ERR(null)) 337 goto err_free_skcipher; 338 339 ctx->auth = auth; 340 ctx->enc = enc; 341 ctx->null = null; 342 343 crypto_aead_set_reqsize( 344 tfm, 345 sizeof(struct authenc_request_ctx) + 346 ictx->reqoff + 347 max_t(unsigned int, 348 crypto_ahash_reqsize(auth) + 349 sizeof(struct ahash_request), 350 sizeof(struct ablkcipher_request) + 351 crypto_ablkcipher_reqsize(enc))); 352 353 return 0; 354 355err_free_skcipher: 356 crypto_free_ablkcipher(enc); 357err_free_ahash: 358 crypto_free_ahash(auth); 359 return err; 360} 361 362static void crypto_authenc_exit_tfm(struct crypto_aead *tfm) 363{ 364 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(tfm); 365 366 crypto_free_ahash(ctx->auth); 367 crypto_free_ablkcipher(ctx->enc); 368 crypto_put_default_null_skcipher(); 369} 370 371static void crypto_authenc_free(struct aead_instance *inst) 372{ 373 struct authenc_instance_ctx *ctx = aead_instance_ctx(inst); 374 375 crypto_drop_skcipher(&ctx->enc); 376 crypto_drop_ahash(&ctx->auth); 377 kfree(inst); 378} 379 380static int crypto_authenc_create(struct crypto_template *tmpl, 381 struct rtattr **tb) 382{ 383 struct crypto_attr_type *algt; 384 struct aead_instance *inst; 385 struct hash_alg_common *auth; 386 struct crypto_alg *auth_base; 387 struct crypto_alg *enc; 388 struct authenc_instance_ctx *ctx; 389 const char *enc_name; 390 int err; 391 392 algt = crypto_get_attr_type(tb); 393 if (IS_ERR(algt)) 394 return PTR_ERR(algt); 395 396 if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask) 397 return -EINVAL; 398 399 auth = ahash_attr_alg(tb[1], CRYPTO_ALG_TYPE_HASH, 400 CRYPTO_ALG_TYPE_AHASH_MASK); 401 if (IS_ERR(auth)) 402 return PTR_ERR(auth); 403 404 auth_base = &auth->base; 405 406 enc_name = crypto_attr_alg_name(tb[2]); 407 err = PTR_ERR(enc_name); 408 if (IS_ERR(enc_name)) 409 goto out_put_auth; 410 411 inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); 412 err = -ENOMEM; 413 if (!inst) 414 goto out_put_auth; 415 416 ctx = aead_instance_ctx(inst); 417 418 err = crypto_init_ahash_spawn(&ctx->auth, auth, 419 aead_crypto_instance(inst)); 420 if (err) 421 goto err_free_inst; 422 423 crypto_set_skcipher_spawn(&ctx->enc, aead_crypto_instance(inst)); 424 err = crypto_grab_skcipher(&ctx->enc, enc_name, 0, 425 crypto_requires_sync(algt->type, 426 algt->mask)); 427 if (err) 428 goto err_drop_auth; 429 430 enc = crypto_skcipher_spawn_alg(&ctx->enc); 431 432 ctx->reqoff = ALIGN(2 * auth->digestsize + auth_base->cra_alignmask, 433 auth_base->cra_alignmask + 1); 434 435 err = -ENAMETOOLONG; 436 if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, 437 "authenc(%s,%s)", auth_base->cra_name, enc->cra_name) >= 438 CRYPTO_MAX_ALG_NAME) 439 goto err_drop_enc; 440 441 if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME, 442 "authenc(%s,%s)", auth_base->cra_driver_name, 443 enc->cra_driver_name) >= CRYPTO_MAX_ALG_NAME) 444 goto err_drop_enc; 445 446 inst->alg.base.cra_flags = enc->cra_flags & CRYPTO_ALG_ASYNC; 447 inst->alg.base.cra_priority = enc->cra_priority * 10 + 448 auth_base->cra_priority; 449 inst->alg.base.cra_blocksize = enc->cra_blocksize; 450 inst->alg.base.cra_alignmask = auth_base->cra_alignmask | 451 enc->cra_alignmask; 452 inst->alg.base.cra_ctxsize = sizeof(struct crypto_authenc_ctx); 453 454 inst->alg.ivsize = enc->cra_ablkcipher.ivsize; 455 inst->alg.maxauthsize = auth->digestsize; 456 457 inst->alg.init = crypto_authenc_init_tfm; 458 inst->alg.exit = crypto_authenc_exit_tfm; 459 460 inst->alg.setkey = crypto_authenc_setkey; 461 inst->alg.encrypt = crypto_authenc_encrypt; 462 inst->alg.decrypt = crypto_authenc_decrypt; 463 464 inst->free = crypto_authenc_free; 465 466 err = aead_register_instance(tmpl, inst); 467 if (err) 468 goto err_drop_enc; 469 470out: 471 crypto_mod_put(auth_base); 472 return err; 473 474err_drop_enc: 475 crypto_drop_skcipher(&ctx->enc); 476err_drop_auth: 477 crypto_drop_ahash(&ctx->auth); 478err_free_inst: 479 kfree(inst); 480out_put_auth: 481 goto out; 482} 483 484static struct crypto_template crypto_authenc_tmpl = { 485 .name = "authenc", 486 .create = crypto_authenc_create, 487 .module = THIS_MODULE, 488}; 489 490static int __init crypto_authenc_module_init(void) 491{ 492 return crypto_register_template(&crypto_authenc_tmpl); 493} 494 495static void __exit crypto_authenc_module_exit(void) 496{ 497 crypto_unregister_template(&crypto_authenc_tmpl); 498} 499 500module_init(crypto_authenc_module_init); 501module_exit(crypto_authenc_module_exit); 502 503MODULE_LICENSE("GPL"); 504MODULE_DESCRIPTION("Simple AEAD wrapper for IPsec"); 505MODULE_ALIAS_CRYPTO("authenc"); 506