vmac.c (73bf20ef3df262026c3470241ae4ac8196943ffa) | vmac.c (bb29648102335586e9a66289a1d98a0cb392b6e5) |
---|---|
1/* | 1/* |
2 * Modified to interface to the Linux kernel | 2 * VMAC: Message Authentication Code using Universal Hashing 3 * 4 * Reference: https://tools.ietf.org/html/draft-krovetz-vmac-01 5 * |
3 * Copyright (c) 2009, Intel Corporation. | 6 * Copyright (c) 2009, Intel Corporation. |
7 * Copyright (c) 2018, Google Inc. |
|
4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * You should have received a copy of the GNU General Public License along with 15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 16 * Place - Suite 330, Boston, MA 02111-1307 USA. 17 */ 18 | 8 * 9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms and conditions of the GNU General Public License, 11 * version 2, as published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope it will be useful, but WITHOUT 14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 16 * more details. 17 * 18 * You should have received a copy of the GNU General Public License along with 19 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 20 * Place - Suite 330, Boston, MA 02111-1307 USA. 21 */ 22 |
19/* -------------------------------------------------------------------------- 20 * VMAC and VHASH Implementation by Ted Krovetz (tdk@acm.org) and Wei Dai. 21 * This implementation is herby placed in the public domain. 22 * The authors offers no warranty. Use at your own risk. 23 * Please send bug reports to the authors. 24 * Last modified: 17 APR 08, 1700 PDT 25 * ----------------------------------------------------------------------- */ | 23/* 24 * Derived from: 25 * VMAC and VHASH Implementation by Ted Krovetz (tdk@acm.org) and Wei Dai. 26 * This implementation is herby placed in the public domain. 27 * The authors offers no warranty. Use at your own risk. 28 * Last modified: 17 APR 08, 1700 PDT 29 */ |
26 | 30 |
31#include <asm/unaligned.h> |
|
27#include <linux/init.h> 28#include <linux/types.h> 29#include <linux/crypto.h> 30#include <linux/module.h> 31#include <linux/scatterlist.h> 32#include <asm/byteorder.h> 33#include <crypto/scatterwalk.h> | 32#include <linux/init.h> 33#include <linux/types.h> 34#include <linux/crypto.h> 35#include <linux/module.h> 36#include <linux/scatterlist.h> 37#include <asm/byteorder.h> 38#include <crypto/scatterwalk.h> |
34#include <crypto/vmac.h> | |
35#include <crypto/internal/hash.h> 36 37/* | 39#include <crypto/internal/hash.h> 40 41/* |
42 * User definable settings. 43 */ 44#define VMAC_TAG_LEN 64 45#define VMAC_KEY_SIZE 128/* Must be 128, 192 or 256 */ 46#define VMAC_KEY_LEN (VMAC_KEY_SIZE/8) 47#define VMAC_NHBYTES 128/* Must 2^i for any 3 < i < 13 Standard = 128*/ 48 49/* per-transform (per-key) context */ 50struct vmac_tfm_ctx { 51 struct crypto_cipher *cipher; 52 u64 nhkey[(VMAC_NHBYTES/8)+2*(VMAC_TAG_LEN/64-1)]; 53 u64 polykey[2*VMAC_TAG_LEN/64]; 54 u64 l3key[2*VMAC_TAG_LEN/64]; 55}; 56 57/* per-request context */ 58struct vmac_desc_ctx { 59 union { 60 u8 partial[VMAC_NHBYTES]; /* partial block */ 61 __le64 partial_words[VMAC_NHBYTES / 8]; 62 }; 63 unsigned int partial_size; /* size of the partial block */ 64 bool first_block_processed; 65 u64 polytmp[2*VMAC_TAG_LEN/64]; /* running total of L2-hash */ 66}; 67 68/* |
|
38 * Constants and masks 39 */ 40#define UINT64_C(x) x##ULL 41static const u64 p64 = UINT64_C(0xfffffffffffffeff); /* 2^64 - 257 prime */ 42static const u64 m62 = UINT64_C(0x3fffffffffffffff); /* 62-bit mask */ 43static const u64 m63 = UINT64_C(0x7fffffffffffffff); /* 63-bit mask */ 44static const u64 m64 = UINT64_C(0xffffffffffffffff); /* 64-bit mask */ 45static const u64 mpoly = UINT64_C(0x1fffffff1fffffff); /* Poly key mask */ --- 267 unchanged lines hidden (view full) --- 313#ifndef nh_vmac_nhbytes_2 314#define nh_vmac_nhbytes_2(mp, kp, nw, rh, rl, rh2, rl2) \ 315 do { \ 316 nh_vmac_nhbytes(mp, kp, nw, rh, rl); \ 317 nh_vmac_nhbytes(mp, ((kp)+2), nw, rh2, rl2); \ 318 } while (0) 319#endif 320 | 69 * Constants and masks 70 */ 71#define UINT64_C(x) x##ULL 72static const u64 p64 = UINT64_C(0xfffffffffffffeff); /* 2^64 - 257 prime */ 73static const u64 m62 = UINT64_C(0x3fffffffffffffff); /* 62-bit mask */ 74static const u64 m63 = UINT64_C(0x7fffffffffffffff); /* 63-bit mask */ 75static const u64 m64 = UINT64_C(0xffffffffffffffff); /* 64-bit mask */ 76static const u64 mpoly = UINT64_C(0x1fffffff1fffffff); /* Poly key mask */ --- 267 unchanged lines hidden (view full) --- 344#ifndef nh_vmac_nhbytes_2 345#define nh_vmac_nhbytes_2(mp, kp, nw, rh, rl, rh2, rl2) \ 346 do { \ 347 nh_vmac_nhbytes(mp, kp, nw, rh, rl); \ 348 nh_vmac_nhbytes(mp, ((kp)+2), nw, rh2, rl2); \ 349 } while (0) 350#endif 351 |
321static void vhash_abort(struct vmac_ctx *ctx) 322{ 323 ctx->polytmp[0] = ctx->polykey[0] ; 324 ctx->polytmp[1] = ctx->polykey[1] ; 325 ctx->first_block_processed = 0; 326} 327 | |
328static u64 l3hash(u64 p1, u64 p2, u64 k1, u64 k2, u64 len) 329{ 330 u64 rh, rl, t, z = 0; 331 332 /* fully reduce (p1,p2)+(len,0) mod p127 */ 333 t = p1 >> 63; 334 p1 &= m63; 335 ADD128(p1, p2, len, t); --- 23 unchanged lines hidden (view full) --- 359 ADD128(t, rl, z, rh); 360 t += t << 8; 361 rl += t; 362 rl += (0 - (rl < t)) & 257; 363 rl += (0 - (rl > p64-1)) & 257; 364 return rl; 365} 366 | 352static u64 l3hash(u64 p1, u64 p2, u64 k1, u64 k2, u64 len) 353{ 354 u64 rh, rl, t, z = 0; 355 356 /* fully reduce (p1,p2)+(len,0) mod p127 */ 357 t = p1 >> 63; 358 p1 &= m63; 359 ADD128(p1, p2, len, t); --- 23 unchanged lines hidden (view full) --- 383 ADD128(t, rl, z, rh); 384 t += t << 8; 385 rl += t; 386 rl += (0 - (rl < t)) & 257; 387 rl += (0 - (rl > p64-1)) & 257; 388 return rl; 389} 390 |
367static void vhash_update(const unsigned char *m, 368 unsigned int mbytes, /* Pos multiple of VMAC_NHBYTES */ 369 struct vmac_ctx *ctx) | 391/* L1 and L2-hash one or more VMAC_NHBYTES-byte blocks */ 392static void vhash_blocks(const struct vmac_tfm_ctx *tctx, 393 struct vmac_desc_ctx *dctx, 394 const __le64 *mptr, unsigned int blocks) |
370{ | 395{ |
371 u64 rh, rl, *mptr; 372 const u64 *kptr = (u64 *)ctx->nhkey; 373 int i; 374 u64 ch, cl; 375 u64 pkh = ctx->polykey[0]; 376 u64 pkl = ctx->polykey[1]; | 396 const u64 *kptr = tctx->nhkey; 397 const u64 pkh = tctx->polykey[0]; 398 const u64 pkl = tctx->polykey[1]; 399 u64 ch = dctx->polytmp[0]; 400 u64 cl = dctx->polytmp[1]; 401 u64 rh, rl; |
377 | 402 |
378 if (!mbytes) 379 return; 380 381 BUG_ON(mbytes % VMAC_NHBYTES); 382 383 mptr = (u64 *)m; 384 i = mbytes / VMAC_NHBYTES; /* Must be non-zero */ 385 386 ch = ctx->polytmp[0]; 387 cl = ctx->polytmp[1]; 388 389 if (!ctx->first_block_processed) { 390 ctx->first_block_processed = 1; | 403 if (!dctx->first_block_processed) { 404 dctx->first_block_processed = true; |
391 nh_vmac_nhbytes(mptr, kptr, VMAC_NHBYTES/8, rh, rl); 392 rh &= m62; 393 ADD128(ch, cl, rh, rl); 394 mptr += (VMAC_NHBYTES/sizeof(u64)); | 405 nh_vmac_nhbytes(mptr, kptr, VMAC_NHBYTES/8, rh, rl); 406 rh &= m62; 407 ADD128(ch, cl, rh, rl); 408 mptr += (VMAC_NHBYTES/sizeof(u64)); |
395 i--; | 409 blocks--; |
396 } 397 | 410 } 411 |
398 while (i--) { | 412 while (blocks--) { |
399 nh_vmac_nhbytes(mptr, kptr, VMAC_NHBYTES/8, rh, rl); 400 rh &= m62; 401 poly_step(ch, cl, pkh, pkl, rh, rl); 402 mptr += (VMAC_NHBYTES/sizeof(u64)); 403 } 404 | 413 nh_vmac_nhbytes(mptr, kptr, VMAC_NHBYTES/8, rh, rl); 414 rh &= m62; 415 poly_step(ch, cl, pkh, pkl, rh, rl); 416 mptr += (VMAC_NHBYTES/sizeof(u64)); 417 } 418 |
405 ctx->polytmp[0] = ch; 406 ctx->polytmp[1] = cl; | 419 dctx->polytmp[0] = ch; 420 dctx->polytmp[1] = cl; |
407} 408 | 421} 422 |
409static u64 vhash(unsigned char m[], unsigned int mbytes, 410 u64 *tagl, struct vmac_ctx *ctx) | 423static int vmac_setkey(struct crypto_shash *tfm, 424 const u8 *key, unsigned int keylen) |
411{ | 425{ |
412 u64 rh, rl, *mptr; 413 const u64 *kptr = (u64 *)ctx->nhkey; 414 int i, remaining; 415 u64 ch, cl; 416 u64 pkh = ctx->polykey[0]; 417 u64 pkl = ctx->polykey[1]; | 426 struct vmac_tfm_ctx *tctx = crypto_shash_ctx(tfm); 427 __be64 out[2]; 428 u8 in[16] = { 0 }; 429 unsigned int i; 430 int err; |
418 | 431 |
419 mptr = (u64 *)m; 420 i = mbytes / VMAC_NHBYTES; 421 remaining = mbytes % VMAC_NHBYTES; 422 423 if (ctx->first_block_processed) { 424 ch = ctx->polytmp[0]; 425 cl = ctx->polytmp[1]; 426 } else if (i) { 427 nh_vmac_nhbytes(mptr, kptr, VMAC_NHBYTES/8, ch, cl); 428 ch &= m62; 429 ADD128(ch, cl, pkh, pkl); 430 mptr += (VMAC_NHBYTES/sizeof(u64)); 431 i--; 432 } else if (remaining) { 433 nh_16(mptr, kptr, 2*((remaining+15)/16), ch, cl); 434 ch &= m62; 435 ADD128(ch, cl, pkh, pkl); 436 mptr += (VMAC_NHBYTES/sizeof(u64)); 437 goto do_l3; 438 } else {/* Empty String */ 439 ch = pkh; cl = pkl; 440 goto do_l3; | 432 if (keylen != VMAC_KEY_LEN) { 433 crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 434 return -EINVAL; |
441 } 442 | 435 } 436 |
443 while (i--) { 444 nh_vmac_nhbytes(mptr, kptr, VMAC_NHBYTES/8, rh, rl); 445 rh &= m62; 446 poly_step(ch, cl, pkh, pkl, rh, rl); 447 mptr += (VMAC_NHBYTES/sizeof(u64)); 448 } 449 if (remaining) { 450 nh_16(mptr, kptr, 2*((remaining+15)/16), rh, rl); 451 rh &= m62; 452 poly_step(ch, cl, pkh, pkl, rh, rl); 453 } 454 455do_l3: 456 vhash_abort(ctx); 457 remaining *= 8; 458 return l3hash(ch, cl, ctx->l3key[0], ctx->l3key[1], remaining); 459} 460 461static u64 vmac(unsigned char m[], unsigned int mbytes, 462 const unsigned char n[16], u64 *tagl, 463 struct vmac_ctx_t *ctx) 464{ 465 u64 *in_n, *out_p; 466 u64 p, h; 467 int i; 468 469 in_n = ctx->__vmac_ctx.cached_nonce; 470 out_p = ctx->__vmac_ctx.cached_aes; 471 472 i = n[15] & 1; 473 if ((*(u64 *)(n+8) != in_n[1]) || (*(u64 *)(n) != in_n[0])) { 474 in_n[0] = *(u64 *)(n); 475 in_n[1] = *(u64 *)(n+8); 476 ((unsigned char *)in_n)[15] &= 0xFE; 477 crypto_cipher_encrypt_one(ctx->child, 478 (unsigned char *)out_p, (unsigned char *)in_n); 479 480 ((unsigned char *)in_n)[15] |= (unsigned char)(1-i); 481 } 482 p = be64_to_cpup(out_p + i); 483 h = vhash(m, mbytes, (u64 *)0, &ctx->__vmac_ctx); 484 return le64_to_cpu(p + h); 485} 486 487static int vmac_set_key(unsigned char user_key[], struct vmac_ctx_t *ctx) 488{ 489 u64 in[2] = {0}, out[2]; 490 unsigned i; 491 int err = 0; 492 493 err = crypto_cipher_setkey(ctx->child, user_key, VMAC_KEY_LEN); | 437 err = crypto_cipher_setkey(tctx->cipher, key, keylen); |
494 if (err) 495 return err; 496 497 /* Fill nh key */ | 438 if (err) 439 return err; 440 441 /* Fill nh key */ |
498 ((unsigned char *)in)[0] = 0x80; 499 for (i = 0; i < sizeof(ctx->__vmac_ctx.nhkey)/8; i += 2) { 500 crypto_cipher_encrypt_one(ctx->child, 501 (unsigned char *)out, (unsigned char *)in); 502 ctx->__vmac_ctx.nhkey[i] = be64_to_cpup(out); 503 ctx->__vmac_ctx.nhkey[i+1] = be64_to_cpup(out+1); 504 ((unsigned char *)in)[15] += 1; | 442 in[0] = 0x80; 443 for (i = 0; i < ARRAY_SIZE(tctx->nhkey); i += 2) { 444 crypto_cipher_encrypt_one(tctx->cipher, (u8 *)out, in); 445 tctx->nhkey[i] = be64_to_cpu(out[0]); 446 tctx->nhkey[i+1] = be64_to_cpu(out[1]); 447 in[15]++; |
505 } 506 507 /* Fill poly key */ | 448 } 449 450 /* Fill poly key */ |
508 ((unsigned char *)in)[0] = 0xC0; 509 in[1] = 0; 510 for (i = 0; i < sizeof(ctx->__vmac_ctx.polykey)/8; i += 2) { 511 crypto_cipher_encrypt_one(ctx->child, 512 (unsigned char *)out, (unsigned char *)in); 513 ctx->__vmac_ctx.polytmp[i] = 514 ctx->__vmac_ctx.polykey[i] = 515 be64_to_cpup(out) & mpoly; 516 ctx->__vmac_ctx.polytmp[i+1] = 517 ctx->__vmac_ctx.polykey[i+1] = 518 be64_to_cpup(out+1) & mpoly; 519 ((unsigned char *)in)[15] += 1; | 451 in[0] = 0xC0; 452 in[15] = 0; 453 for (i = 0; i < ARRAY_SIZE(tctx->polykey); i += 2) { 454 crypto_cipher_encrypt_one(tctx->cipher, (u8 *)out, in); 455 tctx->polykey[i] = be64_to_cpu(out[0]) & mpoly; 456 tctx->polykey[i+1] = be64_to_cpu(out[1]) & mpoly; 457 in[15]++; |
520 } 521 522 /* Fill ip key */ | 458 } 459 460 /* Fill ip key */ |
523 ((unsigned char *)in)[0] = 0xE0; 524 in[1] = 0; 525 for (i = 0; i < sizeof(ctx->__vmac_ctx.l3key)/8; i += 2) { | 461 in[0] = 0xE0; 462 in[15] = 0; 463 for (i = 0; i < ARRAY_SIZE(tctx->l3key); i += 2) { |
526 do { | 464 do { |
527 crypto_cipher_encrypt_one(ctx->child, 528 (unsigned char *)out, (unsigned char *)in); 529 ctx->__vmac_ctx.l3key[i] = be64_to_cpup(out); 530 ctx->__vmac_ctx.l3key[i+1] = be64_to_cpup(out+1); 531 ((unsigned char *)in)[15] += 1; 532 } while (ctx->__vmac_ctx.l3key[i] >= p64 533 || ctx->__vmac_ctx.l3key[i+1] >= p64); | 465 crypto_cipher_encrypt_one(tctx->cipher, (u8 *)out, in); 466 tctx->l3key[i] = be64_to_cpu(out[0]); 467 tctx->l3key[i+1] = be64_to_cpu(out[1]); 468 in[15]++; 469 } while (tctx->l3key[i] >= p64 || tctx->l3key[i+1] >= p64); |
534 } 535 | 470 } 471 |
536 /* Invalidate nonce/aes cache and reset other elements */ 537 ctx->__vmac_ctx.cached_nonce[0] = (u64)-1; /* Ensure illegal nonce */ 538 ctx->__vmac_ctx.cached_nonce[1] = (u64)0; /* Ensure illegal nonce */ 539 ctx->__vmac_ctx.first_block_processed = 0; 540 541 return err; | 472 return 0; |
542} 543 | 473} 474 |
544static int vmac_setkey(struct crypto_shash *parent, 545 const u8 *key, unsigned int keylen) | 475static int vmac_init(struct shash_desc *desc) |
546{ | 476{ |
547 struct vmac_ctx_t *ctx = crypto_shash_ctx(parent); | 477 const struct vmac_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); 478 struct vmac_desc_ctx *dctx = shash_desc_ctx(desc); |
548 | 479 |
549 if (keylen != VMAC_KEY_LEN) { 550 crypto_shash_set_flags(parent, CRYPTO_TFM_RES_BAD_KEY_LEN); 551 return -EINVAL; 552 } 553 554 return vmac_set_key((u8 *)key, ctx); 555} 556 557static int vmac_init(struct shash_desc *pdesc) 558{ | 480 dctx->partial_size = 0; 481 dctx->first_block_processed = false; 482 memcpy(dctx->polytmp, tctx->polykey, sizeof(dctx->polytmp)); |
559 return 0; 560} 561 | 483 return 0; 484} 485 |
562static int vmac_update(struct shash_desc *pdesc, const u8 *p, 563 unsigned int len) | 486static int vmac_update(struct shash_desc *desc, const u8 *p, unsigned int len) |
564{ | 487{ |
565 struct crypto_shash *parent = pdesc->tfm; 566 struct vmac_ctx_t *ctx = crypto_shash_ctx(parent); 567 int expand; 568 int min; | 488 const struct vmac_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); 489 struct vmac_desc_ctx *dctx = shash_desc_ctx(desc); 490 unsigned int n; |
569 | 491 |
570 expand = VMAC_NHBYTES - ctx->partial_size > 0 ? 571 VMAC_NHBYTES - ctx->partial_size : 0; | 492 if (dctx->partial_size) { 493 n = min(len, VMAC_NHBYTES - dctx->partial_size); 494 memcpy(&dctx->partial[dctx->partial_size], p, n); 495 dctx->partial_size += n; 496 p += n; 497 len -= n; 498 if (dctx->partial_size == VMAC_NHBYTES) { 499 vhash_blocks(tctx, dctx, dctx->partial_words, 1); 500 dctx->partial_size = 0; 501 } 502 } |
572 | 503 |
573 min = len < expand ? len : expand; | 504 if (len >= VMAC_NHBYTES) { 505 n = round_down(len, VMAC_NHBYTES); 506 /* TODO: 'p' may be misaligned here */ 507 vhash_blocks(tctx, dctx, (const __le64 *)p, n / VMAC_NHBYTES); 508 p += n; 509 len -= n; 510 } |
574 | 511 |
575 memcpy(ctx->partial + ctx->partial_size, p, min); 576 ctx->partial_size += min; | 512 if (len) { 513 memcpy(dctx->partial, p, len); 514 dctx->partial_size = len; 515 } |
577 | 516 |
578 if (len < expand) 579 return 0; | 517 return 0; 518} |
580 | 519 |
581 vhash_update(ctx->partial, VMAC_NHBYTES, &ctx->__vmac_ctx); 582 ctx->partial_size = 0; | 520static u64 vhash_final(const struct vmac_tfm_ctx *tctx, 521 struct vmac_desc_ctx *dctx) 522{ 523 unsigned int partial = dctx->partial_size; 524 u64 ch = dctx->polytmp[0]; 525 u64 cl = dctx->polytmp[1]; |
583 | 526 |
584 len -= expand; 585 p += expand; | 527 /* L1 and L2-hash the final block if needed */ 528 if (partial) { 529 /* Zero-pad to next 128-bit boundary */ 530 unsigned int n = round_up(partial, 16); 531 u64 rh, rl; |
586 | 532 |
587 if (len % VMAC_NHBYTES) { 588 memcpy(ctx->partial, p + len - (len % VMAC_NHBYTES), 589 len % VMAC_NHBYTES); 590 ctx->partial_size = len % VMAC_NHBYTES; | 533 memset(&dctx->partial[partial], 0, n - partial); 534 nh_16(dctx->partial_words, tctx->nhkey, n / 8, rh, rl); 535 rh &= m62; 536 if (dctx->first_block_processed) 537 poly_step(ch, cl, tctx->polykey[0], tctx->polykey[1], 538 rh, rl); 539 else 540 ADD128(ch, cl, rh, rl); |
591 } 592 | 541 } 542 |
593 vhash_update(p, len - len % VMAC_NHBYTES, &ctx->__vmac_ctx); 594 595 return 0; | 543 /* L3-hash the 128-bit output of L2-hash */ 544 return l3hash(ch, cl, tctx->l3key[0], tctx->l3key[1], partial * 8); |
596} 597 | 545} 546 |
598static int vmac_final(struct shash_desc *pdesc, u8 *out) | 547static int vmac_final(struct shash_desc *desc, u8 *out) |
599{ | 548{ |
600 struct crypto_shash *parent = pdesc->tfm; 601 struct vmac_ctx_t *ctx = crypto_shash_ctx(parent); 602 vmac_t mac; 603 u8 nonce[16] = {}; | 549 const struct vmac_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); 550 struct vmac_desc_ctx *dctx = shash_desc_ctx(desc); 551 static const u8 nonce[16] = {}; /* TODO: this is insecure */ 552 union { 553 u8 bytes[16]; 554 __be64 pads[2]; 555 } block; 556 int index; 557 u64 hash, pad; |
604 | 558 |
605 /* vmac() ends up accessing outside the array bounds that 606 * we specify. In appears to access up to the next 2-word 607 * boundary. We'll just be uber cautious and zero the 608 * unwritten bytes in the buffer. 609 */ 610 if (ctx->partial_size) { 611 memset(ctx->partial + ctx->partial_size, 0, 612 VMAC_NHBYTES - ctx->partial_size); 613 } 614 mac = vmac(ctx->partial, ctx->partial_size, nonce, NULL, ctx); 615 memcpy(out, &mac, sizeof(vmac_t)); 616 memzero_explicit(&mac, sizeof(vmac_t)); 617 memset(&ctx->__vmac_ctx, 0, sizeof(struct vmac_ctx)); 618 ctx->partial_size = 0; | 559 /* Finish calculating the VHASH of the message */ 560 hash = vhash_final(tctx, dctx); 561 562 /* Generate pseudorandom pad by encrypting the nonce */ 563 memcpy(&block, nonce, 16); 564 index = block.bytes[15] & 1; 565 block.bytes[15] &= ~1; 566 crypto_cipher_encrypt_one(tctx->cipher, block.bytes, block.bytes); 567 pad = be64_to_cpu(block.pads[index]); 568 569 /* The VMAC is the sum of VHASH and the pseudorandom pad */ 570 put_unaligned_le64(hash + pad, out); |
619 return 0; 620} 621 622static int vmac_init_tfm(struct crypto_tfm *tfm) 623{ | 571 return 0; 572} 573 574static int vmac_init_tfm(struct crypto_tfm *tfm) 575{ |
624 struct crypto_cipher *cipher; 625 struct crypto_instance *inst = (void *)tfm->__crt_alg; | 576 struct crypto_instance *inst = crypto_tfm_alg_instance(tfm); |
626 struct crypto_spawn *spawn = crypto_instance_ctx(inst); | 577 struct crypto_spawn *spawn = crypto_instance_ctx(inst); |
627 struct vmac_ctx_t *ctx = crypto_tfm_ctx(tfm); | 578 struct vmac_tfm_ctx *tctx = crypto_tfm_ctx(tfm); 579 struct crypto_cipher *cipher; |
628 629 cipher = crypto_spawn_cipher(spawn); 630 if (IS_ERR(cipher)) 631 return PTR_ERR(cipher); 632 | 580 581 cipher = crypto_spawn_cipher(spawn); 582 if (IS_ERR(cipher)) 583 return PTR_ERR(cipher); 584 |
633 ctx->child = cipher; | 585 tctx->cipher = cipher; |
634 return 0; 635} 636 637static void vmac_exit_tfm(struct crypto_tfm *tfm) 638{ | 586 return 0; 587} 588 589static void vmac_exit_tfm(struct crypto_tfm *tfm) 590{ |
639 struct vmac_ctx_t *ctx = crypto_tfm_ctx(tfm); 640 crypto_free_cipher(ctx->child); | 591 struct vmac_tfm_ctx *tctx = crypto_tfm_ctx(tfm); 592 593 crypto_free_cipher(tctx->cipher); |
641} 642 643static int vmac_create(struct crypto_template *tmpl, struct rtattr **tb) 644{ 645 struct shash_instance *inst; 646 struct crypto_alg *alg; 647 int err; 648 --- 20 unchanged lines hidden (view full) --- 669 CRYPTO_ALG_TYPE_MASK); 670 if (err) 671 goto out_free_inst; 672 673 inst->alg.base.cra_priority = alg->cra_priority; 674 inst->alg.base.cra_blocksize = alg->cra_blocksize; 675 inst->alg.base.cra_alignmask = alg->cra_alignmask; 676 | 594} 595 596static int vmac_create(struct crypto_template *tmpl, struct rtattr **tb) 597{ 598 struct shash_instance *inst; 599 struct crypto_alg *alg; 600 int err; 601 --- 20 unchanged lines hidden (view full) --- 622 CRYPTO_ALG_TYPE_MASK); 623 if (err) 624 goto out_free_inst; 625 626 inst->alg.base.cra_priority = alg->cra_priority; 627 inst->alg.base.cra_blocksize = alg->cra_blocksize; 628 inst->alg.base.cra_alignmask = alg->cra_alignmask; 629 |
677 inst->alg.digestsize = sizeof(vmac_t); 678 inst->alg.base.cra_ctxsize = sizeof(struct vmac_ctx_t); | 630 inst->alg.base.cra_ctxsize = sizeof(struct vmac_tfm_ctx); |
679 inst->alg.base.cra_init = vmac_init_tfm; 680 inst->alg.base.cra_exit = vmac_exit_tfm; 681 | 631 inst->alg.base.cra_init = vmac_init_tfm; 632 inst->alg.base.cra_exit = vmac_exit_tfm; 633 |
634 inst->alg.descsize = sizeof(struct vmac_desc_ctx); 635 inst->alg.digestsize = VMAC_TAG_LEN / 8; |
|
682 inst->alg.init = vmac_init; 683 inst->alg.update = vmac_update; 684 inst->alg.final = vmac_final; 685 inst->alg.setkey = vmac_setkey; 686 687 err = shash_register_instance(tmpl, inst); 688 if (err) { 689out_free_inst: --- 31 unchanged lines hidden --- | 636 inst->alg.init = vmac_init; 637 inst->alg.update = vmac_update; 638 inst->alg.final = vmac_final; 639 inst->alg.setkey = vmac_setkey; 640 641 err = shash_register_instance(tmpl, inst); 642 if (err) { 643out_free_inst: --- 31 unchanged lines hidden --- |