[2961] in Kerberos-V5-bugs

home help back first fref pref prev next nref lref last post

krb5-libs/626: shsUpdate, shsFinalize can trash core or produce bad results.

daemon@ATHENA.MIT.EDU (Marcus D Watts)
Tue Sep 1 19:05:15 1998

Resent-From: gnats@rt-11.MIT.EDU (GNATS Management)
Resent-To: krb5-unassigned@RT-11.MIT.EDU
Resent-Reply-To: krb5-bugs@MIT.EDU, mdw@quince.ifs.umich.edu
Date: Tue, 1 Sep 1998 18:57:54 -0400
From: Marcus D Watts <mdw@quince.ifs.umich.edu>
Reply-To: mdw@quince.ifs.umich.edu
To: krb5-bugs@MIT.EDU


>Number:         626
>Category:       krb5-libs
>Synopsis:       shsUpdate, shsFinalize can trash core or produce bad results.
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    krb5-unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   unknown
>Arrival-Date:   Tue Sep 01 18:59:01 EDT 1998
>Last-Modified:
>Originator:     Marcus D Watts
>Organization:
University of Michigan
>Release:        krb5-current-19980804
>Environment:
	
System: SunOS pepper-pot 5.6 Generic_105181-03 sun4u sparc SUNW,Ultra-5_10
Architecture: sun4
>Description:
	If the first call to shsUpdate has left some data, and the 2nd call
	to shsUpdate passes too little data to make up a complete block,
	shsTransform may still be called in certain circumstances.

	If the sum of counts to previous calls to shsUpdate is not a
	multiple of 4, the first 1-3 bytes of data supplied is or'd into
	the wrong part of a word.

	If shsUpdate is given a very small count (1-6 bytes), it can under
	certain conditions fetch and mis-use an extra word of data.

	If the byte count of the total amount of data supplied is 60-63 mod
	64, shsFinalize will zero an extra word of storage immediately past
	the end of the SHS_INFO structure passed to it.

	See 
		http://web.mit.edu/afs/umich.edu/user/m/d/mdw/src/shs/
	for more information including test programs.
>How-To-Repeat:
	The file /afs/umich.edu/user/m/d/mdw/src/shs/t_shs3.c contains
	a program will exercise the bugs.
>Fix:
	
--- shs_old.c	Tue Sep  1 18:13:26 1998
+++ shs_n.c	Tue Sep  1 18:13:25 1998
@@ -272,25 +272,21 @@
     /* Handle any leading odd-sized chunks */
     if (dataCount) {
 	lp = shsInfo->data + dataCount / 4;
-	canfill = (count >= dataCount);
 	dataCount = SHS_DATASIZE - dataCount;
+	canfill = (count >= dataCount);
 
 	if (dataCount % 4) {
 	    /* Fill out a full 32 bit word first if needed -- this
 	       is not very efficient (computed shift amount),
 	       but it shouldn't happen often. */
 	    while (dataCount % 4 && count > 0) {
-		*lp |= (LONG) *buffer++ << ((3 - dataCount++ % 4) * 8);
+		*lp |= (LONG) *buffer++ << ((--dataCount % 4) * 8);
 		count--;
 	    }
 	    lp++;
 	}
 	while (lp < shsInfo->data + 16) {
-	    *lp = (LONG) *buffer++ << 24;
-	    *lp |= (LONG) *buffer++ << 16;
-	    *lp |= (LONG) *buffer++ << 8;
-	    *lp++ |= (LONG) *buffer++;
-	    if ((count -= 4) < 4 && lp < shsInfo->data + 16) {
+	    if (count < 4) {
 		*lp = 0;
 		switch (count % 4) {
 		case 3:
@@ -300,9 +296,14 @@
 		case 1:
 		    *lp |= (LONG) buffer[0] << 24;
 		}
-		break;
 		count = 0;
+		break;
 	    }
+	    *lp = (LONG) *buffer++ << 24;
+	    *lp |= (LONG) *buffer++ << 16;
+	    *lp |= (LONG) *buffer++ << 8;
+	    *lp++ |= (LONG) *buffer++;
+	    count -= 4;
 	}
 	if (canfill) {
 	    SHSTransform(shsInfo->digest, shsInfo->data);
@@ -378,7 +379,8 @@
 
     if (lp > shsInfo->data + 14) {
 	/* Pad out to 64 bytes if not enough room for length words */
-	*lp = 0;
+	if (count < 60)
+	    *lp = 0;
 	SHSTransform(shsInfo->digest, shsInfo->data);
 	lp = shsInfo->data;
     }
>Audit-Trail:
>Unformatted:

home help back first fref pref prev next nref lref last post