Subject: lib/4941: libskey broken on big-endian machines
To: None <gnats-bugs@gnats.netbsd.org>
From: None <oster@cs.usask.ca>
List: netbsd-bugs
Date: 02/05/1998 14:23:53
>Number:         4941
>Category:       lib
>Synopsis:       libskey broken on big-endian machines
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people (Library Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Feb  5 12:35:01 1998
>Last-Modified:
>Originator:     Greg Oster
>Organization:
University of Saskatchewan
>Release:        NetBSD-1.3
>Environment:

System 1: NetBSD scrooge.usask.ca 1.3 NetBSD 1.3 (SCROOGE) #0: Fri Jan 16 09:05:07 CST 1998 oster@scrooge.usask.ca:/dws/src/sys/arch/i386/compile/SCROOGE i386

System 2: NetBSD jimmy.usask.ca 1.3 NetBSD 1.3 (JIMMY) #0: Mon Jan 12 11:03:13 CST 1998     oster@jimmy.usask.ca:/usr/scrooge/sys/arch/hp300/compile/JIMMY hp300

>Description:

skey does not generate the same one-time password on i386 and m68k boxes.
As well, skey in 1.3 generates a different one-time password than it did
in 1.2 on m68k boxes.

Investigation revealed that the MD4 and MD5 routines in libc were
functioning consistently.  As well, a 1.3 skey executable would perform
correctly if used with a 1.2 libskey.a, indicating that libskey was
the source of the problem. 

>How-To-Repeat:

For example under NetBSD-1.3/hp300 or NetBSD-1.3/sun3 
(using "foo" as the secret password):
% skey 662 sa33031
Enter secret password: 
NOR LULU PUT KICK HI YAM
%
On a NetBSD-1.3/i386 box I get:
% skey 662 sa33031
Enter secret password: 
JIVE OUST AREA EVE SLAB SANG
%


>Fix:

The culprit appears to be a handful of lines in /usr/src/lib/libskey/skeysubr.c
which claim to do a conversion to little-endian byte ordering.  
This conversion is apparently not needed on either big nor little-endian
systems, as removing that code fixes the observed skey problem... 

The following diff does fix the skey problem, although I'm not sure if it 
manages to break something else in the process.  (Fix inspired by 
OpenBSD's skeysubr.c) 

*** skeysubr.c.orig     Thu Feb  5 13:18:45 1998
--- skeysubr.c  Thu Feb  5 13:30:17 1998
***************
*** 42,49 ****
        char *buf;
        MD4_CTX md;
        unsigned int buflen;
-       int i;
-       register int tmp;
        u_int32_t hash[4];
        
        buflen = strlen(seed) + strlen(passwd);
--- 42,47 ----
***************
*** 64,83 ****
        hash[0] ^= hash[2];
        hash[1] ^= hash[3];
  
!       /* Default (but slow) code that will convert to
!        * little-endian byte ordering on any machine
!        */
!       for (i=0; i<2; i++) {
!               tmp = hash[i];
!               *result++ = tmp;
!               tmp >>= 8;
!               *result++ = tmp;
!               tmp >>= 8;
!               *result++ = tmp;
!               tmp >>= 8;
!               *result++ = tmp;
!       }
! 
        return 0;
  }
  
--- 62,68 ----
        hash[0] ^= hash[2];
        hash[1] ^= hash[3];
  
!         memcpy(result,hash,8);
        return 0;
  }
  
***************
*** 87,93 ****
        char *x;
  {
        MD4_CTX md;
-       register int tmp;
        u_int32_t hash[4];
  
        MD4Init(&md);
--- 72,77 ----
***************
*** 98,123 ****
        hash[0] ^= hash[2];
        hash[1] ^= hash[3];
  
!       /* Default (but slow) code that will convert to
!        * little-endian byte ordering on any machine
!        */
!       tmp = hash[0];
!       *x++ = tmp;
!       tmp >>= 8;
!       *x++ = tmp;
!       tmp >>= 8;
!       *x++ = tmp;
!       tmp >>= 8;
!       *x++ = tmp;
! 
!       tmp = hash[1];
!       *x++ = tmp;
!       tmp >>= 8;
!       *x++ = tmp;
!       tmp >>= 8;
!       *x++ = tmp;
!       tmp >>= 8;
!       *x = tmp;
  }
  
  /* Strip trailing cr/lf from a line of text */
--- 82,88 ----
        hash[0] ^= hash[2];
        hash[1] ^= hash[3];
  
!       memcpy(x,hash,8);
  }
  
  /* Strip trailing cr/lf from a line of text */

>Audit-Trail:
>Unformatted: