1 /* 2 * Authenc: Simple AEAD wrapper for IPsec 3 * 4 * Copyright (c) 2007 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/aead.h> 14 #include <crypto/internal/hash.h> 15 #include <crypto/internal/skcipher.h> 16 #include <crypto/authenc.h> 17 #include <crypto/scatterwalk.h> 18 #include <linux/err.h> 19 #include <linux/init.h> 20 #include <linux/kernel.h> 21 #include <linux/module.h> 22 #include <linux/rtnetlink.h> 23 #include <linux/slab.h> 24 #include <linux/spinlock.h> 25 26 struct authenc_instance_ctx { 27 struct crypto_spawn auth; 28 struct crypto_skcipher_spawn enc; 29 }; 30 31 struct crypto_authenc_ctx { 32 spinlock_t auth_lock; 33 struct crypto_hash *auth; 34 struct crypto_ablkcipher *enc; 35 }; 36 37 static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key, 38 unsigned int keylen) 39 { 40 unsigned int authkeylen; 41 unsigned int enckeylen; 42 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); 43 struct crypto_hash *auth = ctx->auth; 44 struct crypto_ablkcipher *enc = ctx->enc; 45 struct rtattr *rta = (void *)key; 46 struct crypto_authenc_key_param *param; 47 int err = -EINVAL; 48 49 if (!RTA_OK(rta, keylen)) 50 goto badkey; 51 if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM) 52 goto badkey; 53 if (RTA_PAYLOAD(rta) < sizeof(*param)) 54 goto badkey; 55 56 param = RTA_DATA(rta); 57 enckeylen = be32_to_cpu(param->enckeylen); 58 59 key += RTA_ALIGN(rta->rta_len); 60 keylen -= RTA_ALIGN(rta->rta_len); 61 62 if (keylen < enckeylen) 63 goto badkey; 64 65 authkeylen = keylen - enckeylen; 66 67 crypto_hash_clear_flags(auth, CRYPTO_TFM_REQ_MASK); 68 crypto_hash_set_flags(auth, crypto_aead_get_flags(authenc) & 69 CRYPTO_TFM_REQ_MASK); 70 err = crypto_hash_setkey(auth, key, authkeylen); 71 crypto_aead_set_flags(authenc, crypto_hash_get_flags(auth) & 72 CRYPTO_TFM_RES_MASK); 73 74 if (err) 75 goto out; 76 77 crypto_ablkcipher_clear_flags(enc, CRYPTO_TFM_REQ_MASK); 78 crypto_ablkcipher_set_flags(enc, crypto_aead_get_flags(authenc) & 79 CRYPTO_TFM_REQ_MASK); 80 err = crypto_ablkcipher_setkey(enc, key + authkeylen, enckeylen); 81 crypto_aead_set_flags(authenc, crypto_ablkcipher_get_flags(enc) & 82 CRYPTO_TFM_RES_MASK); 83 84 out: 85 return err; 86 87 badkey: 88 crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN); 89 goto out; 90 } 91 92 static void authenc_chain(struct scatterlist *head, struct scatterlist *sg, 93 int chain) 94 { 95 if (chain) { 96 head->length += sg->length; 97 sg = scatterwalk_sg_next(sg); 98 } 99 100 if (sg) 101 scatterwalk_sg_chain(head, 2, sg); 102 else 103 sg_mark_end(head); 104 } 105 106 static u8 *crypto_authenc_hash(struct aead_request *req, unsigned int flags, 107 struct scatterlist *cipher, 108 unsigned int cryptlen) 109 { 110 struct crypto_aead *authenc = crypto_aead_reqtfm(req); 111 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); 112 struct crypto_hash *auth = ctx->auth; 113 struct hash_desc desc = { 114 .tfm = auth, 115 .flags = aead_request_flags(req) & flags, 116 }; 117 u8 *hash = aead_request_ctx(req); 118 int err; 119 120 hash = (u8 *)ALIGN((unsigned long)hash + crypto_hash_alignmask(auth), 121 crypto_hash_alignmask(auth) + 1); 122 123 spin_lock_bh(&ctx->auth_lock); 124 err = crypto_hash_init(&desc); 125 if (err) 126 goto auth_unlock; 127 128 err = crypto_hash_update(&desc, req->assoc, req->assoclen); 129 if (err) 130 goto auth_unlock; 131 132 err = crypto_hash_update(&desc, cipher, cryptlen); 133 if (err) 134 goto auth_unlock; 135 136 err = crypto_hash_final(&desc, hash); 137 auth_unlock: 138 spin_unlock_bh(&ctx->auth_lock); 139 140 if (err) 141 return ERR_PTR(err); 142 143 return hash; 144 } 145 146 static int crypto_authenc_genicv(struct aead_request *req, u8 *iv, 147 unsigned int flags) 148 { 149 struct crypto_aead *authenc = crypto_aead_reqtfm(req); 150 struct scatterlist *dst = req->dst; 151 struct scatterlist cipher[2]; 152 struct page *dstp; 153 unsigned int ivsize = crypto_aead_ivsize(authenc); 154 unsigned int cryptlen; 155 u8 *vdst; 156 u8 *hash; 157 158 dstp = sg_page(dst); 159 vdst = PageHighMem(dstp) ? NULL : page_address(dstp) + dst->offset; 160 161 sg_init_table(cipher, 2); 162 sg_set_buf(cipher, iv, ivsize); 163 authenc_chain(cipher, dst, vdst == iv + ivsize); 164 165 cryptlen = req->cryptlen + ivsize; 166 hash = crypto_authenc_hash(req, flags, cipher, cryptlen); 167 if (IS_ERR(hash)) 168 return PTR_ERR(hash); 169 170 scatterwalk_map_and_copy(hash, cipher, cryptlen, 171 crypto_aead_authsize(authenc), 1); 172 return 0; 173 } 174 175 static void crypto_authenc_encrypt_done(struct crypto_async_request *req, 176 int err) 177 { 178 struct aead_request *areq = req->data; 179 180 if (!err) { 181 struct crypto_aead *authenc = crypto_aead_reqtfm(areq); 182 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); 183 struct ablkcipher_request *abreq = aead_request_ctx(areq); 184 u8 *iv = (u8 *)(abreq + 1) + 185 crypto_ablkcipher_reqsize(ctx->enc); 186 187 err = crypto_authenc_genicv(areq, iv, 0); 188 } 189 190 aead_request_complete(areq, err); 191 } 192 193 static int crypto_authenc_encrypt(struct aead_request *req) 194 { 195 struct crypto_aead *authenc = crypto_aead_reqtfm(req); 196 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); 197 struct ablkcipher_request *abreq = aead_request_ctx(req); 198 struct crypto_ablkcipher *enc = ctx->enc; 199 struct scatterlist *dst = req->dst; 200 unsigned int cryptlen = req->cryptlen; 201 u8 *iv = (u8 *)(abreq + 1) + crypto_ablkcipher_reqsize(enc); 202 int err; 203 204 ablkcipher_request_set_tfm(abreq, enc); 205 ablkcipher_request_set_callback(abreq, aead_request_flags(req), 206 crypto_authenc_encrypt_done, req); 207 ablkcipher_request_set_crypt(abreq, req->src, dst, cryptlen, req->iv); 208 209 memcpy(iv, req->iv, crypto_aead_ivsize(authenc)); 210 211 err = crypto_ablkcipher_encrypt(abreq); 212 if (err) 213 return err; 214 215 return crypto_authenc_genicv(req, iv, CRYPTO_TFM_REQ_MAY_SLEEP); 216 } 217 218 static void crypto_authenc_givencrypt_done(struct crypto_async_request *req, 219 int err) 220 { 221 struct aead_request *areq = req->data; 222 223 if (!err) { 224 struct skcipher_givcrypt_request *greq = aead_request_ctx(areq); 225 226 err = crypto_authenc_genicv(areq, greq->giv, 0); 227 } 228 229 aead_request_complete(areq, err); 230 } 231 232 static int crypto_authenc_givencrypt(struct aead_givcrypt_request *req) 233 { 234 struct crypto_aead *authenc = aead_givcrypt_reqtfm(req); 235 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); 236 struct aead_request *areq = &req->areq; 237 struct skcipher_givcrypt_request *greq = aead_request_ctx(areq); 238 u8 *iv = req->giv; 239 int err; 240 241 skcipher_givcrypt_set_tfm(greq, ctx->enc); 242 skcipher_givcrypt_set_callback(greq, aead_request_flags(areq), 243 crypto_authenc_givencrypt_done, areq); 244 skcipher_givcrypt_set_crypt(greq, areq->src, areq->dst, areq->cryptlen, 245 areq->iv); 246 skcipher_givcrypt_set_giv(greq, iv, req->seq); 247 248 err = crypto_skcipher_givencrypt(greq); 249 if (err) 250 return err; 251 252 return crypto_authenc_genicv(areq, iv, CRYPTO_TFM_REQ_MAY_SLEEP); 253 } 254 255 static int crypto_authenc_verify(struct aead_request *req, 256 struct scatterlist *cipher, 257 unsigned int cryptlen) 258 { 259 struct crypto_aead *authenc = crypto_aead_reqtfm(req); 260 u8 *ohash; 261 u8 *ihash; 262 unsigned int authsize; 263 264 ohash = crypto_authenc_hash(req, CRYPTO_TFM_REQ_MAY_SLEEP, cipher, 265 cryptlen); 266 if (IS_ERR(ohash)) 267 return PTR_ERR(ohash); 268 269 authsize = crypto_aead_authsize(authenc); 270 ihash = ohash + authsize; 271 scatterwalk_map_and_copy(ihash, cipher, cryptlen, authsize, 0); 272 return memcmp(ihash, ohash, authsize) ? -EBADMSG: 0; 273 } 274 275 static int crypto_authenc_iverify(struct aead_request *req, u8 *iv, 276 unsigned int cryptlen) 277 { 278 struct crypto_aead *authenc = crypto_aead_reqtfm(req); 279 struct scatterlist *src = req->src; 280 struct scatterlist cipher[2]; 281 struct page *srcp; 282 unsigned int ivsize = crypto_aead_ivsize(authenc); 283 u8 *vsrc; 284 285 srcp = sg_page(src); 286 vsrc = PageHighMem(srcp) ? NULL : page_address(srcp) + src->offset; 287 288 sg_init_table(cipher, 2); 289 sg_set_buf(cipher, iv, ivsize); 290 authenc_chain(cipher, src, vsrc == iv + ivsize); 291 292 return crypto_authenc_verify(req, cipher, cryptlen + ivsize); 293 } 294 295 static int crypto_authenc_decrypt(struct aead_request *req) 296 { 297 struct crypto_aead *authenc = crypto_aead_reqtfm(req); 298 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); 299 struct ablkcipher_request *abreq = aead_request_ctx(req); 300 unsigned int cryptlen = req->cryptlen; 301 unsigned int authsize = crypto_aead_authsize(authenc); 302 u8 *iv = req->iv; 303 int err; 304 305 if (cryptlen < authsize) 306 return -EINVAL; 307 cryptlen -= authsize; 308 309 err = crypto_authenc_iverify(req, iv, cryptlen); 310 if (err) 311 return err; 312 313 ablkcipher_request_set_tfm(abreq, ctx->enc); 314 ablkcipher_request_set_callback(abreq, aead_request_flags(req), 315 req->base.complete, req->base.data); 316 ablkcipher_request_set_crypt(abreq, req->src, req->dst, cryptlen, iv); 317 318 return crypto_ablkcipher_decrypt(abreq); 319 } 320 321 static int crypto_authenc_init_tfm(struct crypto_tfm *tfm) 322 { 323 struct crypto_instance *inst = (void *)tfm->__crt_alg; 324 struct authenc_instance_ctx *ictx = crypto_instance_ctx(inst); 325 struct crypto_authenc_ctx *ctx = crypto_tfm_ctx(tfm); 326 struct crypto_hash *auth; 327 struct crypto_ablkcipher *enc; 328 int err; 329 330 auth = crypto_spawn_hash(&ictx->auth); 331 if (IS_ERR(auth)) 332 return PTR_ERR(auth); 333 334 enc = crypto_spawn_skcipher(&ictx->enc); 335 err = PTR_ERR(enc); 336 if (IS_ERR(enc)) 337 goto err_free_hash; 338 339 ctx->auth = auth; 340 ctx->enc = enc; 341 tfm->crt_aead.reqsize = max_t(unsigned int, 342 (crypto_hash_alignmask(auth) & 343 ~(crypto_tfm_ctx_alignment() - 1)) + 344 crypto_hash_digestsize(auth) * 2, 345 sizeof(struct skcipher_givcrypt_request) + 346 crypto_ablkcipher_reqsize(enc) + 347 crypto_ablkcipher_ivsize(enc)); 348 349 spin_lock_init(&ctx->auth_lock); 350 351 return 0; 352 353 err_free_hash: 354 crypto_free_hash(auth); 355 return err; 356 } 357 358 static void crypto_authenc_exit_tfm(struct crypto_tfm *tfm) 359 { 360 struct crypto_authenc_ctx *ctx = crypto_tfm_ctx(tfm); 361 362 crypto_free_hash(ctx->auth); 363 crypto_free_ablkcipher(ctx->enc); 364 } 365 366 static struct crypto_instance *crypto_authenc_alloc(struct rtattr **tb) 367 { 368 struct crypto_attr_type *algt; 369 struct crypto_instance *inst; 370 struct crypto_alg *auth; 371 struct crypto_alg *enc; 372 struct authenc_instance_ctx *ctx; 373 const char *enc_name; 374 int err; 375 376 algt = crypto_get_attr_type(tb); 377 err = PTR_ERR(algt); 378 if (IS_ERR(algt)) 379 return ERR_PTR(err); 380 381 if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask) 382 return ERR_PTR(-EINVAL); 383 384 auth = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_HASH, 385 CRYPTO_ALG_TYPE_HASH_MASK); 386 if (IS_ERR(auth)) 387 return ERR_PTR(PTR_ERR(auth)); 388 389 enc_name = crypto_attr_alg_name(tb[2]); 390 err = PTR_ERR(enc_name); 391 if (IS_ERR(enc_name)) 392 goto out_put_auth; 393 394 inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); 395 err = -ENOMEM; 396 if (!inst) 397 goto out_put_auth; 398 399 ctx = crypto_instance_ctx(inst); 400 401 err = crypto_init_spawn(&ctx->auth, auth, inst, CRYPTO_ALG_TYPE_MASK); 402 if (err) 403 goto err_free_inst; 404 405 crypto_set_skcipher_spawn(&ctx->enc, inst); 406 err = crypto_grab_skcipher(&ctx->enc, enc_name, 0, 407 crypto_requires_sync(algt->type, 408 algt->mask)); 409 if (err) 410 goto err_drop_auth; 411 412 enc = crypto_skcipher_spawn_alg(&ctx->enc); 413 414 err = -ENAMETOOLONG; 415 if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, 416 "authenc(%s,%s)", auth->cra_name, enc->cra_name) >= 417 CRYPTO_MAX_ALG_NAME) 418 goto err_drop_enc; 419 420 if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, 421 "authenc(%s,%s)", auth->cra_driver_name, 422 enc->cra_driver_name) >= CRYPTO_MAX_ALG_NAME) 423 goto err_drop_enc; 424 425 inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD; 426 inst->alg.cra_flags |= enc->cra_flags & CRYPTO_ALG_ASYNC; 427 inst->alg.cra_priority = enc->cra_priority * 10 + auth->cra_priority; 428 inst->alg.cra_blocksize = enc->cra_blocksize; 429 inst->alg.cra_alignmask = auth->cra_alignmask | enc->cra_alignmask; 430 inst->alg.cra_type = &crypto_aead_type; 431 432 inst->alg.cra_aead.ivsize = enc->cra_ablkcipher.ivsize; 433 inst->alg.cra_aead.maxauthsize = auth->cra_type == &crypto_hash_type ? 434 auth->cra_hash.digestsize : 435 auth->cra_type ? 436 __crypto_shash_alg(auth)->digestsize : 437 auth->cra_digest.dia_digestsize; 438 439 inst->alg.cra_ctxsize = sizeof(struct crypto_authenc_ctx); 440 441 inst->alg.cra_init = crypto_authenc_init_tfm; 442 inst->alg.cra_exit = crypto_authenc_exit_tfm; 443 444 inst->alg.cra_aead.setkey = crypto_authenc_setkey; 445 inst->alg.cra_aead.encrypt = crypto_authenc_encrypt; 446 inst->alg.cra_aead.decrypt = crypto_authenc_decrypt; 447 inst->alg.cra_aead.givencrypt = crypto_authenc_givencrypt; 448 449 out: 450 crypto_mod_put(auth); 451 return inst; 452 453 err_drop_enc: 454 crypto_drop_skcipher(&ctx->enc); 455 err_drop_auth: 456 crypto_drop_spawn(&ctx->auth); 457 err_free_inst: 458 kfree(inst); 459 out_put_auth: 460 inst = ERR_PTR(err); 461 goto out; 462 } 463 464 static void crypto_authenc_free(struct crypto_instance *inst) 465 { 466 struct authenc_instance_ctx *ctx = crypto_instance_ctx(inst); 467 468 crypto_drop_skcipher(&ctx->enc); 469 crypto_drop_spawn(&ctx->auth); 470 kfree(inst); 471 } 472 473 static struct crypto_template crypto_authenc_tmpl = { 474 .name = "authenc", 475 .alloc = crypto_authenc_alloc, 476 .free = crypto_authenc_free, 477 .module = THIS_MODULE, 478 }; 479 480 static int __init crypto_authenc_module_init(void) 481 { 482 return crypto_register_template(&crypto_authenc_tmpl); 483 } 484 485 static void __exit crypto_authenc_module_exit(void) 486 { 487 crypto_unregister_template(&crypto_authenc_tmpl); 488 } 489 490 module_init(crypto_authenc_module_init); 491 module_exit(crypto_authenc_module_exit); 492 493 MODULE_LICENSE("GPL"); 494 MODULE_DESCRIPTION("Simple AEAD wrapper for IPsec"); 495