summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjsing <>2025-05-22 12:44:14 +0000
committerjsing <>2025-05-22 12:44:14 +0000
commitd6d6b23a49d21d2881e12b770fba4750c19047db (patch)
treeaff434ad99536294ad81c25eca1582bc97da8441 /src
parent782008a26462e3082fdd7e188156e7d0374cf81d (diff)
downloadopenbsd-d6d6b23a49d21d2881e12b770fba4750c19047db.tar.gz
openbsd-d6d6b23a49d21d2881e12b770fba4750c19047db.tar.bz2
openbsd-d6d6b23a49d21d2881e12b770fba4750c19047db.zip
Do a clean up pass over the GCM code.
Rework some logic, add explicit numerical checks, move assignment out of variable declaration and use post-increment/post-decrement unless there is a specific reason to do pre-increment. ok kenjiro@ tb@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/modes/gcm128.c178
1 files changed, 86 insertions, 92 deletions
diff --git a/src/lib/libcrypto/modes/gcm128.c b/src/lib/libcrypto/modes/gcm128.c
index 5ac00b0b48..7c69a5afc9 100644
--- a/src/lib/libcrypto/modes/gcm128.c
+++ b/src/lib/libcrypto/modes/gcm128.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: gcm128.c,v 1.46 2025/05/22 12:33:36 jsing Exp $ */ 1/* $OpenBSD: gcm128.c,v 1.47 2025/05/22 12:44:14 jsing Exp $ */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 2010 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 2010 The OpenSSL Project. All rights reserved.
4 * 4 *
@@ -336,12 +336,14 @@ LCRYPTO_ALIAS(CRYPTO_gcm128_init);
336GCM128_CONTEXT * 336GCM128_CONTEXT *
337CRYPTO_gcm128_new(void *key, block128_f block) 337CRYPTO_gcm128_new(void *key, block128_f block)
338{ 338{
339 GCM128_CONTEXT *ret; 339 GCM128_CONTEXT *ctx;
340 340
341 if ((ret = malloc(sizeof(GCM128_CONTEXT)))) 341 if ((ctx = calloc(1, sizeof(*ctx))) == NULL)
342 CRYPTO_gcm128_init(ret, key, block); 342 return NULL;
343 343
344 return ret; 344 CRYPTO_gcm128_init(ctx, key, block);
345
346 return ctx;
345} 347}
346LCRYPTO_ALIAS(CRYPTO_gcm128_new); 348LCRYPTO_ALIAS(CRYPTO_gcm128_new);
347 349
@@ -403,45 +405,43 @@ LCRYPTO_ALIAS(CRYPTO_gcm128_setiv);
403int 405int
404CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad, size_t len) 406CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad, size_t len)
405{ 407{
406 size_t i;
407 unsigned int n; 408 unsigned int n;
408 uint64_t alen = ctx->len.u[0]; 409 uint64_t alen;
410 size_t i;
409 411
410 if (ctx->len.u[1]) 412 if (ctx->len.u[1] != 0)
411 return -2; 413 return -2;
412 414
413 alen += len; 415 alen = ctx->len.u[0] + len;
414 if (alen > (U64(1) << 61) || (sizeof(len) == 8 && alen < len)) 416 if (alen > (U64(1) << 61) || (sizeof(len) == 8 && alen < len))
415 return -1; 417 return -1;
416 ctx->len.u[0] = alen; 418 ctx->len.u[0] = alen;
417 419
418 n = ctx->ares; 420 if ((n = ctx->ares) > 0) {
419 if (n) { 421 while (n > 0 && len > 0) {
420 while (n && len) {
421 ctx->Xi.c[n] ^= *(aad++); 422 ctx->Xi.c[n] ^= *(aad++);
422 --len;
423 n = (n + 1) % 16; 423 n = (n + 1) % 16;
424 len--;
424 } 425 }
425 if (n == 0) 426 if (n > 0) {
426 gcm_mul(ctx, ctx->Xi.u);
427 else {
428 ctx->ares = n; 427 ctx->ares = n;
429 return 0; 428 return 0;
430 } 429 }
430 gcm_mul(ctx, ctx->Xi.u);
431 } 431 }
432 432
433 if ((i = (len & (size_t)-16))) { 433 if ((i = (len & (size_t)-16)) > 0) {
434 gcm_ghash(ctx, aad, i); 434 gcm_ghash(ctx, aad, i);
435 aad += i; 435 aad += i;
436 len -= i; 436 len -= i;
437 } 437 }
438 if (len) { 438 if (len > 0) {
439 n = (unsigned int)len; 439 n = (unsigned int)len;
440 for (i = 0; i < len; ++i) 440 for (i = 0; i < len; ++i)
441 ctx->Xi.c[i] ^= aad[i]; 441 ctx->Xi.c[i] ^= aad[i];
442 } 442 }
443
444 ctx->ares = n; 443 ctx->ares = n;
444
445 return 0; 445 return 0;
446} 446}
447LCRYPTO_ALIAS(CRYPTO_gcm128_aad); 447LCRYPTO_ALIAS(CRYPTO_gcm128_aad);
@@ -451,17 +451,15 @@ CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const unsigned char *in,
451 unsigned char *out, size_t len) 451 unsigned char *out, size_t len)
452{ 452{
453 unsigned int n, ctr; 453 unsigned int n, ctr;
454 uint64_t mlen;
454 size_t i; 455 size_t i;
455 uint64_t mlen = ctx->len.u[1];
456 block128_f block = ctx->block;
457 void *key = ctx->key;
458 456
459 mlen += len; 457 mlen = ctx->len.u[1] + len;
460 if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) 458 if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len))
461 return -1; 459 return -1;
462 ctx->len.u[1] = mlen; 460 ctx->len.u[1] = mlen;
463 461
464 if (ctx->ares) { 462 if (ctx->ares > 0) {
465 /* First call to encrypt finalizes GHASH(AAD) */ 463 /* First call to encrypt finalizes GHASH(AAD) */
466 gcm_mul(ctx, ctx->Xi.u); 464 gcm_mul(ctx, ctx->Xi.u);
467 ctx->ares = 0; 465 ctx->ares = 0;
@@ -473,9 +471,8 @@ CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const unsigned char *in,
473 471
474 for (i = 0; i < len; ++i) { 472 for (i = 0; i < len; ++i) {
475 if (n == 0) { 473 if (n == 0) {
476 (*block)(ctx->Yi.c, ctx->EKi.c, key); 474 ctx->block(ctx->Yi.c, ctx->EKi.c, ctx->key);
477 ++ctr; 475 ctx->Yi.d[3] = htobe32(++ctr);
478 ctx->Yi.d[3] = htobe32(ctr);
479 } 476 }
480 ctx->Xi.c[n] ^= out[i] = in[i] ^ ctx->EKi.c[n]; 477 ctx->Xi.c[n] ^= out[i] = in[i] ^ ctx->EKi.c[n];
481 n = (n + 1) % 16; 478 n = (n + 1) % 16;
@@ -484,6 +481,7 @@ CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const unsigned char *in,
484 } 481 }
485 482
486 ctx->mres = n; 483 ctx->mres = n;
484
487 return 0; 485 return 0;
488} 486}
489LCRYPTO_ALIAS(CRYPTO_gcm128_encrypt); 487LCRYPTO_ALIAS(CRYPTO_gcm128_encrypt);
@@ -493,12 +491,11 @@ CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const unsigned char *in,
493 unsigned char *out, size_t len) 491 unsigned char *out, size_t len)
494{ 492{
495 unsigned int n, ctr; 493 unsigned int n, ctr;
494 uint64_t mlen;
495 uint8_t c;
496 size_t i; 496 size_t i;
497 uint64_t mlen = ctx->len.u[1];
498 block128_f block = ctx->block;
499 void *key = ctx->key;
500 497
501 mlen += len; 498 mlen = ctx->len.u[1] + len;
502 if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) 499 if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len))
503 return -1; 500 return -1;
504 ctx->len.u[1] = mlen; 501 ctx->len.u[1] = mlen;
@@ -514,11 +511,9 @@ CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const unsigned char *in,
514 n = ctx->mres; 511 n = ctx->mres;
515 512
516 for (i = 0; i < len; ++i) { 513 for (i = 0; i < len; ++i) {
517 uint8_t c;
518 if (n == 0) { 514 if (n == 0) {
519 (*block)(ctx->Yi.c, ctx->EKi.c, key); 515 ctx->block(ctx->Yi.c, ctx->EKi.c, ctx->key);
520 ++ctr; 516 ctx->Yi.d[3] = htobe32(++ctr);
521 ctx->Yi.d[3] = htobe32(ctr);
522 } 517 }
523 c = in[i]; 518 c = in[i];
524 out[i] = c ^ ctx->EKi.c[n]; 519 out[i] = c ^ ctx->EKi.c[n];
@@ -529,6 +524,7 @@ CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const unsigned char *in,
529 } 524 }
530 525
531 ctx->mres = n; 526 ctx->mres = n;
527
532 return 0; 528 return 0;
533} 529}
534LCRYPTO_ALIAS(CRYPTO_gcm128_decrypt); 530LCRYPTO_ALIAS(CRYPTO_gcm128_decrypt);
@@ -538,16 +534,15 @@ CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const unsigned char *in,
538 unsigned char *out, size_t len, ctr128_f stream) 534 unsigned char *out, size_t len, ctr128_f stream)
539{ 535{
540 unsigned int n, ctr; 536 unsigned int n, ctr;
541 size_t i; 537 uint64_t mlen;
542 uint64_t mlen = ctx->len.u[1]; 538 size_t i, j;
543 void *key = ctx->key;
544 539
545 mlen += len; 540 mlen = ctx->len.u[1] + len;
546 if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) 541 if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len))
547 return -1; 542 return -1;
548 ctx->len.u[1] = mlen; 543 ctx->len.u[1] = mlen;
549 544
550 if (ctx->ares) { 545 if (ctx->ares > 0) {
551 /* First call to encrypt finalizes GHASH(AAD) */ 546 /* First call to encrypt finalizes GHASH(AAD) */
552 gcm_mul(ctx, ctx->Xi.u); 547 gcm_mul(ctx, ctx->Xi.u);
553 ctx->ares = 0; 548 ctx->ares = 0;
@@ -555,42 +550,39 @@ CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const unsigned char *in,
555 550
556 ctr = be32toh(ctx->Yi.d[3]); 551 ctr = be32toh(ctx->Yi.d[3]);
557 552
558 n = ctx->mres; 553 if ((n = ctx->mres) > 0) {
559 if (n) { 554 while (n > 0 && len > 0) {
560 while (n && len) {
561 ctx->Xi.c[n] ^= *(out++) = *(in++) ^ ctx->EKi.c[n]; 555 ctx->Xi.c[n] ^= *(out++) = *(in++) ^ ctx->EKi.c[n];
562 --len;
563 n = (n + 1) % 16; 556 n = (n + 1) % 16;
557 len--;
564 } 558 }
565 if (n == 0) 559 if (n > 0) {
566 gcm_mul(ctx, ctx->Xi.u);
567 else {
568 ctx->mres = n; 560 ctx->mres = n;
569 return 0; 561 return 0;
570 } 562 }
563 gcm_mul(ctx, ctx->Xi.u);
571 } 564 }
572 if ((i = (len & (size_t)-16))) { 565 if ((i = (len & (size_t)-16)) > 0) {
573 size_t j = i/16; 566 j = i / 16;
574 567 stream(in, out, j, ctx->key, ctx->Yi.c);
575 (*stream)(in, out, j, key, ctx->Yi.c);
576 ctr += (unsigned int)j; 568 ctr += (unsigned int)j;
577 ctx->Yi.d[3] = htobe32(ctr); 569 ctx->Yi.d[3] = htobe32(ctr);
578 in += i;
579 len -= i;
580 gcm_ghash(ctx, out, i); 570 gcm_ghash(ctx, out, i);
571 in += i;
581 out += i; 572 out += i;
573 len -= i;
582 } 574 }
583 if (len) { 575 if (len > 0) {
584 (*ctx->block)(ctx->Yi.c, ctx->EKi.c, key); 576 ctx->block(ctx->Yi.c, ctx->EKi.c, ctx->key);
585 ++ctr; 577 ctx->Yi.d[3] = htobe32(++ctr);
586 ctx->Yi.d[3] = htobe32(ctr); 578 while (len-- > 0) {
587 while (len--) {
588 ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n]; 579 ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n];
589 ++n; 580 n++;
590 } 581 }
591 } 582 }
592 583
593 ctx->mres = n; 584 ctx->mres = n;
585
594 return 0; 586 return 0;
595} 587}
596LCRYPTO_ALIAS(CRYPTO_gcm128_encrypt_ctr32); 588LCRYPTO_ALIAS(CRYPTO_gcm128_encrypt_ctr32);
@@ -600,16 +592,16 @@ CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const unsigned char *in,
600 unsigned char *out, size_t len, ctr128_f stream) 592 unsigned char *out, size_t len, ctr128_f stream)
601{ 593{
602 unsigned int n, ctr; 594 unsigned int n, ctr;
603 size_t i; 595 uint64_t mlen;
604 uint64_t mlen = ctx->len.u[1]; 596 size_t i, j;
605 void *key = ctx->key; 597 uint8_t c;
606 598
607 mlen += len; 599 mlen = ctx->len.u[1] + len;
608 if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) 600 if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len))
609 return -1; 601 return -1;
610 ctx->len.u[1] = mlen; 602 ctx->len.u[1] = mlen;
611 603
612 if (ctx->ares) { 604 if (ctx->ares > 0) {
613 /* First call to decrypt finalizes GHASH(AAD) */ 605 /* First call to decrypt finalizes GHASH(AAD) */
614 gcm_mul(ctx, ctx->Xi.u); 606 gcm_mul(ctx, ctx->Xi.u);
615 ctx->ares = 0; 607 ctx->ares = 0;
@@ -617,46 +609,43 @@ CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const unsigned char *in,
617 609
618 ctr = be32toh(ctx->Yi.d[3]); 610 ctr = be32toh(ctx->Yi.d[3]);
619 611
620 n = ctx->mres; 612 if ((n = ctx->mres) > 0) {
621 if (n) { 613 while (n > 0 && len > 0) {
622 while (n && len) { 614 c = *(in++);
623 uint8_t c = *(in++);
624 *(out++) = c ^ ctx->EKi.c[n]; 615 *(out++) = c ^ ctx->EKi.c[n];
625 ctx->Xi.c[n] ^= c; 616 ctx->Xi.c[n] ^= c;
626 --len;
627 n = (n + 1) % 16; 617 n = (n + 1) % 16;
618 len--;
628 } 619 }
629 if (n == 0) 620 if (n > 0) {
630 gcm_mul(ctx, ctx->Xi.u);
631 else {
632 ctx->mres = n; 621 ctx->mres = n;
633 return 0; 622 return 0;
634 } 623 }
624 gcm_mul(ctx, ctx->Xi.u);
635 } 625 }
636 if ((i = (len & (size_t)-16))) { 626 if ((i = (len & (size_t)-16)) > 0) {
637 size_t j = i/16; 627 j = i / 16;
638
639 gcm_ghash(ctx, in, i); 628 gcm_ghash(ctx, in, i);
640 (*stream)(in, out, j, key, ctx->Yi.c); 629 stream(in, out, j, ctx->key, ctx->Yi.c);
641 ctr += (unsigned int)j; 630 ctr += (unsigned int)j;
642 ctx->Yi.d[3] = htobe32(ctr); 631 ctx->Yi.d[3] = htobe32(ctr);
643 out += i;
644 in += i; 632 in += i;
633 out += i;
645 len -= i; 634 len -= i;
646 } 635 }
647 if (len) { 636 if (len > 0) {
648 (*ctx->block)(ctx->Yi.c, ctx->EKi.c, key); 637 ctx->block(ctx->Yi.c, ctx->EKi.c, ctx->key);
649 ++ctr; 638 ctx->Yi.d[3] = htobe32(++ctr);
650 ctx->Yi.d[3] = htobe32(ctr); 639 while (len-- > 0) {
651 while (len--) { 640 c = in[n];
652 uint8_t c = in[n];
653 ctx->Xi.c[n] ^= c; 641 ctx->Xi.c[n] ^= c;
654 out[n] = c ^ ctx->EKi.c[n]; 642 out[n] = c ^ ctx->EKi.c[n];
655 ++n; 643 n++;
656 } 644 }
657 } 645 }
658 646
659 ctx->mres = n; 647 ctx->mres = n;
648
660 return 0; 649 return 0;
661} 650}
662LCRYPTO_ALIAS(CRYPTO_gcm128_decrypt_ctr32); 651LCRYPTO_ALIAS(CRYPTO_gcm128_decrypt_ctr32);
@@ -665,10 +654,12 @@ int
665CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag, 654CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag,
666 size_t len) 655 size_t len)
667{ 656{
668 uint64_t alen = ctx->len.u[0] << 3; 657 uint64_t alen, clen;
669 uint64_t clen = ctx->len.u[1] << 3;
670 658
671 if (ctx->mres || ctx->ares) 659 alen = ctx->len.u[0] << 3;
660 clen = ctx->len.u[1] << 3;
661
662 if (ctx->ares > 0 || ctx->mres > 0)
672 gcm_mul(ctx, ctx->Xi.u); 663 gcm_mul(ctx, ctx->Xi.u);
673 664
674 ctx->Xi.u[0] ^= htobe64(alen); 665 ctx->Xi.u[0] ^= htobe64(alen);
@@ -678,10 +669,10 @@ CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag,
678 ctx->Xi.u[0] ^= ctx->EK0.u[0]; 669 ctx->Xi.u[0] ^= ctx->EK0.u[0];
679 ctx->Xi.u[1] ^= ctx->EK0.u[1]; 670 ctx->Xi.u[1] ^= ctx->EK0.u[1];
680 671
681 if (tag && len <= sizeof(ctx->Xi)) 672 if (tag == NULL || len > sizeof(ctx->Xi))
682 return timingsafe_memcmp(ctx->Xi.c, tag, len);
683 else
684 return -1; 673 return -1;
674
675 return timingsafe_memcmp(ctx->Xi.c, tag, len);
685} 676}
686LCRYPTO_ALIAS(CRYPTO_gcm128_finish); 677LCRYPTO_ALIAS(CRYPTO_gcm128_finish);
687 678
@@ -689,7 +680,10 @@ void
689CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len) 680CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len)
690{ 681{
691 CRYPTO_gcm128_finish(ctx, NULL, 0); 682 CRYPTO_gcm128_finish(ctx, NULL, 0);
692 memcpy(tag, ctx->Xi.c, 683
693 len <= sizeof(ctx->Xi.c) ? len : sizeof(ctx->Xi.c)); 684 if (len > sizeof(ctx->Xi.c))
685 len = sizeof(ctx->Xi.c);
686
687 memcpy(tag, ctx->Xi.c, len);
694} 688}
695LCRYPTO_ALIAS(CRYPTO_gcm128_tag); 689LCRYPTO_ALIAS(CRYPTO_gcm128_tag);