Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

crypto: hmac - Add ahash support

Add ahash support to hmac so that drivers that can't do hmac in
hardware do not have to implement duplicate copies of hmac.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

+345 -15
+9 -1
crypto/ahash.c
··· 846 846 } 847 847 EXPORT_SYMBOL_GPL(crypto_has_ahash); 848 848 849 - static bool crypto_hash_alg_has_setkey(struct hash_alg_common *halg) 849 + bool crypto_hash_alg_has_setkey(struct hash_alg_common *halg) 850 850 { 851 851 struct crypto_alg *alg = &halg->base; 852 852 ··· 855 855 856 856 return __crypto_ahash_alg(alg)->setkey != ahash_nosetkey; 857 857 } 858 + EXPORT_SYMBOL_GPL(crypto_hash_alg_has_setkey); 858 859 859 860 struct crypto_ahash *crypto_clone_ahash(struct crypto_ahash *hash) 860 861 { ··· 1077 1076 return err; 1078 1077 } 1079 1078 EXPORT_SYMBOL_GPL(crypto_hash_digest); 1079 + 1080 + void ahash_free_singlespawn_instance(struct ahash_instance *inst) 1081 + { 1082 + crypto_drop_spawn(ahash_instance_ctx(inst)); 1083 + kfree(inst); 1084 + } 1085 + EXPORT_SYMBOL_GPL(ahash_free_singlespawn_instance); 1080 1086 1081 1087 MODULE_LICENSE("GPL"); 1082 1088 MODULE_DESCRIPTION("Asynchronous cryptographic hash type");
+325 -13
crypto/hmac.c
··· 26 26 u8 pads[]; 27 27 }; 28 28 29 + struct ahash_hmac_ctx { 30 + struct crypto_ahash *hash; 31 + /* Contains 'u8 ipad[statesize];', then 'u8 opad[statesize];' */ 32 + u8 pads[]; 33 + }; 34 + 29 35 static int hmac_setkey(struct crypto_shash *parent, 30 36 const u8 *inkey, unsigned int keylen) 31 37 { ··· 179 173 crypto_free_shash(tctx->hash); 180 174 } 181 175 182 - static int hmac_create(struct crypto_template *tmpl, struct rtattr **tb) 176 + static int __hmac_create_shash(struct crypto_template *tmpl, 177 + struct rtattr **tb, u32 mask) 183 178 { 184 179 struct shash_instance *inst; 185 180 struct crypto_shash_spawn *spawn; 186 181 struct crypto_alg *alg; 187 182 struct shash_alg *salg; 188 - u32 mask; 189 183 int err; 190 184 int ds; 191 185 int ss; 192 - 193 - err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SHASH, &mask); 194 - if (err) 195 - return err; 196 186 197 187 inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); 198 188 if (!inst) ··· 214 212 ss < alg->cra_blocksize) 215 213 goto err_free_inst; 216 214 217 - err = crypto_inst_setname(shash_crypto_instance(inst), tmpl->name, alg); 215 + err = crypto_inst_setname(shash_crypto_instance(inst), "hmac", 216 + "hmac-shash", alg); 218 217 if (err) 219 218 goto err_free_inst; 220 219 ··· 248 245 return err; 249 246 } 250 247 251 - static struct crypto_template hmac_tmpl = { 252 - .name = "hmac", 253 - .create = hmac_create, 254 - .module = THIS_MODULE, 248 + static int hmac_setkey_ahash(struct crypto_ahash *parent, 249 + const u8 *inkey, unsigned int keylen) 250 + { 251 + struct ahash_hmac_ctx *tctx = crypto_ahash_ctx(parent); 252 + struct crypto_ahash *fb = crypto_ahash_fb(tctx->hash); 253 + int ds = crypto_ahash_digestsize(parent); 254 + int bs = crypto_ahash_blocksize(parent); 255 + int ss = crypto_ahash_statesize(parent); 256 + HASH_REQUEST_ON_STACK(req, fb); 257 + u8 *opad = &tctx->pads[ss]; 258 + u8 *ipad = &tctx->pads[0]; 259 + int err, i; 260 + 261 + if (fips_enabled && (keylen < 112 / 8)) 262 + return -EINVAL; 263 + 264 + ahash_request_set_callback(req, 0, NULL, NULL); 265 + 266 + if (keylen > bs) { 267 + ahash_request_set_virt(req, inkey, ipad, keylen); 268 + err = crypto_ahash_digest(req); 269 + if (err) 270 + goto out_zero_req; 271 + 272 + keylen = ds; 273 + } else 274 + memcpy(ipad, inkey, keylen); 275 + 276 + memset(ipad + keylen, 0, bs - keylen); 277 + memcpy(opad, ipad, bs); 278 + 279 + for (i = 0; i < bs; i++) { 280 + ipad[i] ^= HMAC_IPAD_VALUE; 281 + opad[i] ^= HMAC_OPAD_VALUE; 282 + } 283 + 284 + ahash_request_set_virt(req, ipad, NULL, bs); 285 + err = crypto_ahash_init(req) ?: 286 + crypto_ahash_update(req) ?: 287 + crypto_ahash_export(req, ipad); 288 + 289 + ahash_request_set_virt(req, opad, NULL, bs); 290 + err = err ?: 291 + crypto_ahash_init(req) ?: 292 + crypto_ahash_update(req) ?: 293 + crypto_ahash_export(req, opad); 294 + 295 + out_zero_req: 296 + HASH_REQUEST_ZERO(req); 297 + return err; 298 + } 299 + 300 + static int hmac_export_ahash(struct ahash_request *preq, void *out) 301 + { 302 + return crypto_ahash_export(ahash_request_ctx(preq), out); 303 + } 304 + 305 + static int hmac_import_ahash(struct ahash_request *preq, const void *in) 306 + { 307 + struct crypto_ahash *tfm = crypto_ahash_reqtfm(preq); 308 + struct ahash_hmac_ctx *tctx = crypto_ahash_ctx(tfm); 309 + struct ahash_request *req = ahash_request_ctx(preq); 310 + 311 + ahash_request_set_tfm(req, tctx->hash); 312 + return crypto_ahash_import(req, in); 313 + } 314 + 315 + static int hmac_export_core_ahash(struct ahash_request *preq, void *out) 316 + { 317 + return crypto_ahash_export_core(ahash_request_ctx(preq), out); 318 + } 319 + 320 + static int hmac_import_core_ahash(struct ahash_request *preq, const void *in) 321 + { 322 + struct crypto_ahash *tfm = crypto_ahash_reqtfm(preq); 323 + struct ahash_hmac_ctx *tctx = crypto_ahash_ctx(tfm); 324 + struct ahash_request *req = ahash_request_ctx(preq); 325 + 326 + ahash_request_set_tfm(req, tctx->hash); 327 + return crypto_ahash_import_core(req, in); 328 + } 329 + 330 + static int hmac_init_ahash(struct ahash_request *preq) 331 + { 332 + struct crypto_ahash *tfm = crypto_ahash_reqtfm(preq); 333 + struct ahash_hmac_ctx *tctx = crypto_ahash_ctx(tfm); 334 + 335 + return hmac_import_ahash(preq, &tctx->pads[0]); 336 + } 337 + 338 + static int hmac_update_ahash(struct ahash_request *preq) 339 + { 340 + struct ahash_request *req = ahash_request_ctx(preq); 341 + 342 + ahash_request_set_callback(req, ahash_request_flags(preq), 343 + preq->base.complete, preq->base.data); 344 + if (ahash_request_isvirt(preq)) 345 + ahash_request_set_virt(req, preq->svirt, NULL, preq->nbytes); 346 + else 347 + ahash_request_set_crypt(req, preq->src, NULL, preq->nbytes); 348 + return crypto_ahash_update(req); 349 + } 350 + 351 + static int hmac_finup_finish(struct ahash_request *preq, unsigned int mask) 352 + { 353 + struct crypto_ahash *tfm = crypto_ahash_reqtfm(preq); 354 + struct ahash_request *req = ahash_request_ctx(preq); 355 + struct ahash_hmac_ctx *tctx = crypto_ahash_ctx(tfm); 356 + int ds = crypto_ahash_digestsize(tfm); 357 + int ss = crypto_ahash_statesize(tfm); 358 + const u8 *opad = &tctx->pads[ss]; 359 + 360 + ahash_request_set_callback(req, ahash_request_flags(preq) & ~mask, 361 + preq->base.complete, preq->base.data); 362 + ahash_request_set_virt(req, preq->result, preq->result, ds); 363 + return crypto_ahash_import(req, opad) ?: 364 + crypto_ahash_finup(req); 365 + 366 + } 367 + 368 + static void hmac_finup_done(void *data, int err) 369 + { 370 + struct ahash_request *preq = data; 371 + 372 + if (err) 373 + goto out; 374 + 375 + err = hmac_finup_finish(preq, CRYPTO_TFM_REQ_MAY_SLEEP); 376 + if (err == -EINPROGRESS || err == -EBUSY) 377 + return; 378 + 379 + out: 380 + ahash_request_complete(preq, err); 381 + } 382 + 383 + static int hmac_finup_ahash(struct ahash_request *preq) 384 + { 385 + struct ahash_request *req = ahash_request_ctx(preq); 386 + 387 + ahash_request_set_callback(req, ahash_request_flags(preq), 388 + hmac_finup_done, preq); 389 + if (ahash_request_isvirt(preq)) 390 + ahash_request_set_virt(req, preq->svirt, preq->result, 391 + preq->nbytes); 392 + else 393 + ahash_request_set_crypt(req, preq->src, preq->result, 394 + preq->nbytes); 395 + return crypto_ahash_finup(req) ?: 396 + hmac_finup_finish(preq, 0); 397 + } 398 + 399 + static int hmac_digest_ahash(struct ahash_request *preq) 400 + { 401 + return hmac_init_ahash(preq) ?: 402 + hmac_finup_ahash(preq); 403 + } 404 + 405 + static int hmac_init_ahash_tfm(struct crypto_ahash *parent) 406 + { 407 + struct ahash_instance *inst = ahash_alg_instance(parent); 408 + struct ahash_hmac_ctx *tctx = crypto_ahash_ctx(parent); 409 + struct crypto_ahash *hash; 410 + 411 + hash = crypto_spawn_ahash(ahash_instance_ctx(inst)); 412 + if (IS_ERR(hash)) 413 + return PTR_ERR(hash); 414 + 415 + if (crypto_ahash_reqsize(parent) < sizeof(struct ahash_request) + 416 + crypto_ahash_reqsize(hash)) 417 + return -EINVAL; 418 + 419 + tctx->hash = hash; 420 + return 0; 421 + } 422 + 423 + static int hmac_clone_ahash_tfm(struct crypto_ahash *dst, 424 + struct crypto_ahash *src) 425 + { 426 + struct ahash_hmac_ctx *sctx = crypto_ahash_ctx(src); 427 + struct ahash_hmac_ctx *dctx = crypto_ahash_ctx(dst); 428 + struct crypto_ahash *hash; 429 + 430 + hash = crypto_clone_ahash(sctx->hash); 431 + if (IS_ERR(hash)) 432 + return PTR_ERR(hash); 433 + 434 + dctx->hash = hash; 435 + return 0; 436 + } 437 + 438 + static void hmac_exit_ahash_tfm(struct crypto_ahash *parent) 439 + { 440 + struct ahash_hmac_ctx *tctx = crypto_ahash_ctx(parent); 441 + 442 + crypto_free_ahash(tctx->hash); 443 + } 444 + 445 + static int hmac_create_ahash(struct crypto_template *tmpl, struct rtattr **tb, 446 + u32 mask) 447 + { 448 + struct crypto_ahash_spawn *spawn; 449 + struct ahash_instance *inst; 450 + struct crypto_alg *alg; 451 + struct hash_alg_common *halg; 452 + int ds, ss, err; 453 + 454 + inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); 455 + if (!inst) 456 + return -ENOMEM; 457 + spawn = ahash_instance_ctx(inst); 458 + 459 + mask |= CRYPTO_AHASH_ALG_NO_EXPORT_CORE; 460 + err = crypto_grab_ahash(spawn, ahash_crypto_instance(inst), 461 + crypto_attr_alg_name(tb[1]), 0, mask); 462 + if (err) 463 + goto err_free_inst; 464 + halg = crypto_spawn_ahash_alg(spawn); 465 + alg = &halg->base; 466 + 467 + /* The underlying hash algorithm must not require a key */ 468 + err = -EINVAL; 469 + if (crypto_hash_alg_needs_key(halg)) 470 + goto err_free_inst; 471 + 472 + ds = halg->digestsize; 473 + ss = halg->statesize; 474 + if (ds > alg->cra_blocksize || ss < alg->cra_blocksize) 475 + goto err_free_inst; 476 + 477 + err = crypto_inst_setname(ahash_crypto_instance(inst), tmpl->name, alg); 478 + if (err) 479 + goto err_free_inst; 480 + 481 + inst->alg.halg.base.cra_flags = alg->cra_flags & 482 + CRYPTO_ALG_INHERITED_FLAGS; 483 + inst->alg.halg.base.cra_flags |= CRYPTO_ALG_REQ_VIRT; 484 + inst->alg.halg.base.cra_priority = alg->cra_priority + 100; 485 + inst->alg.halg.base.cra_blocksize = alg->cra_blocksize; 486 + inst->alg.halg.base.cra_ctxsize = sizeof(struct ahash_hmac_ctx) + 487 + (ss * 2); 488 + inst->alg.halg.base.cra_reqsize = sizeof(struct ahash_request) + 489 + alg->cra_reqsize; 490 + 491 + inst->alg.halg.digestsize = ds; 492 + inst->alg.halg.statesize = ss; 493 + inst->alg.init = hmac_init_ahash; 494 + inst->alg.update = hmac_update_ahash; 495 + inst->alg.finup = hmac_finup_ahash; 496 + inst->alg.digest = hmac_digest_ahash; 497 + inst->alg.export = hmac_export_ahash; 498 + inst->alg.import = hmac_import_ahash; 499 + inst->alg.export_core = hmac_export_core_ahash; 500 + inst->alg.import_core = hmac_import_core_ahash; 501 + inst->alg.setkey = hmac_setkey_ahash; 502 + inst->alg.init_tfm = hmac_init_ahash_tfm; 503 + inst->alg.clone_tfm = hmac_clone_ahash_tfm; 504 + inst->alg.exit_tfm = hmac_exit_ahash_tfm; 505 + 506 + inst->free = ahash_free_singlespawn_instance; 507 + 508 + err = ahash_register_instance(tmpl, inst); 509 + if (err) { 510 + err_free_inst: 511 + ahash_free_singlespawn_instance(inst); 512 + } 513 + return err; 514 + } 515 + 516 + static int hmac_create(struct crypto_template *tmpl, struct rtattr **tb) 517 + { 518 + struct crypto_attr_type *algt; 519 + u32 mask; 520 + 521 + algt = crypto_get_attr_type(tb); 522 + if (IS_ERR(algt)) 523 + return PTR_ERR(algt); 524 + 525 + mask = crypto_algt_inherited_mask(algt); 526 + 527 + if (!((algt->type ^ CRYPTO_ALG_TYPE_AHASH) & 528 + algt->mask & CRYPTO_ALG_TYPE_MASK)) 529 + return hmac_create_ahash(tmpl, tb, mask); 530 + 531 + if ((algt->type ^ CRYPTO_ALG_TYPE_SHASH) & 532 + algt->mask & CRYPTO_ALG_TYPE_MASK) 533 + return -EINVAL; 534 + 535 + return __hmac_create_shash(tmpl, tb, mask); 536 + } 537 + 538 + static int hmac_create_shash(struct crypto_template *tmpl, struct rtattr **tb) 539 + { 540 + u32 mask; 541 + int err; 542 + 543 + err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SHASH, &mask); 544 + if (err) 545 + return err == -EINVAL ? -ENOENT : err; 546 + 547 + return __hmac_create_shash(tmpl, tb, mask); 548 + } 549 + 550 + static struct crypto_template hmac_tmpls[] = { 551 + { 552 + .name = "hmac", 553 + .create = hmac_create, 554 + .module = THIS_MODULE, 555 + }, 556 + { 557 + .name = "hmac-shash", 558 + .create = hmac_create_shash, 559 + .module = THIS_MODULE, 560 + }, 255 561 }; 256 562 257 563 static int __init hmac_module_init(void) 258 564 { 259 - return crypto_register_template(&hmac_tmpl); 565 + return crypto_register_templates(hmac_tmpls, ARRAY_SIZE(hmac_tmpls)); 260 566 } 261 567 262 568 static void __exit hmac_module_exit(void) 263 569 { 264 - crypto_unregister_template(&hmac_tmpl); 570 + crypto_unregister_templates(hmac_tmpls, ARRAY_SIZE(hmac_tmpls)); 265 571 } 266 572 267 573 module_init(hmac_module_init);
+2 -1
include/crypto/hash.h
··· 185 185 * containing a 'struct s390_sha_ctx'. 186 186 */ 187 187 #define HASH_MAX_DESCSIZE (sizeof(struct shash_desc) + 360) 188 - #define MAX_SYNC_HASH_REQSIZE HASH_MAX_DESCSIZE 188 + #define MAX_SYNC_HASH_REQSIZE (sizeof(struct ahash_request) + \ 189 + HASH_MAX_DESCSIZE) 189 190 190 191 #define SHASH_DESC_ON_STACK(shash, ctx) \ 191 192 char __##shash##_desc[sizeof(struct shash_desc) + HASH_MAX_DESCSIZE] \
+9
include/crypto/internal/hash.h
··· 67 67 void crypto_unregister_ahashes(struct ahash_alg *algs, int count); 68 68 int ahash_register_instance(struct crypto_template *tmpl, 69 69 struct ahash_instance *inst); 70 + void ahash_free_singlespawn_instance(struct ahash_instance *inst); 70 71 71 72 int shash_no_setkey(struct crypto_shash *tfm, const u8 *key, 72 73 unsigned int keylen); ··· 77 76 return alg->setkey != shash_no_setkey; 78 77 } 79 78 79 + bool crypto_hash_alg_has_setkey(struct hash_alg_common *halg); 80 + 80 81 static inline bool crypto_shash_alg_needs_key(struct shash_alg *alg) 81 82 { 82 83 return crypto_shash_alg_has_setkey(alg) && 84 + !(alg->base.cra_flags & CRYPTO_ALG_OPTIONAL_KEY); 85 + } 86 + 87 + static inline bool crypto_hash_alg_needs_key(struct hash_alg_common *alg) 88 + { 89 + return crypto_hash_alg_has_setkey(alg) && 83 90 !(alg->base.cra_flags & CRYPTO_ALG_OPTIONAL_KEY); 84 91 } 85 92