misc/120075: Incompatible EOS of key in crypt(3)

Takumi Nakamura chapuni at hf.rim.or.jp
Mon Jan 28 07:30:01 UTC 2008


>Number:         120075
>Category:       misc
>Synopsis:       Incompatible EOS of key in crypt(3)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jan 28 07:30:00 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator:     Takumi Nakamura
>Release:        FreeBSD 6.2-RELEASE-p9
>Organization:
>Environment:
FreeBSD ***** 6.2-RELEASE-p9 FreeBSD 6.2-RELEASE-p9 #4: Mon Dec  3 15:31:44 JST 2007 *****:/usr/obj/usr/src/sys/GENERIC  i386
>Description:
In, crypt_des(key,salt)
0x80(not \0) in key is treated as end of string.

I expect the result below differs;

crypt("\x8B\xAE\xAE\xE4\x9a\x9F\x80\x82", "..")
and
crypt("\x8B\xAE\xAE\xE4\x9a\x9F", "..")

It is imcompatibility among other OSes, GNU/Linux(glibc), NetBSD, Darwin, &c.
There is no way for kludge to keep compatibility on FreeBSD.
>How-To-Repeat:
/*

FreeBSD 6.2-RELEASE-p9
crypt( 8B AE AE E4 9A 9F 80 82 )=..cSVY0lhu7BA
crypt( 8B AE AE E4 9A 9F 80 00 )=..cSVY0lhu7BA
crypt( 8B AE AE E4 9A 9F 00 82 )=..cSVY0lhu7BA
crypt( 8B AE AE E4 9A 9F 00 80 )=..cSVY0lhu7BA

GNU/Linux glibc x86
crypt( 8B AE AE E4 9A 9F 80 82 )=..riUAaAAAAAA
crypt( 8B AE AE E4 9A 9F 80 00 )=..cSVY0lhu7BA
crypt( 8B AE AE E4 9A 9F 00 82 )=..cSVY0lhu7BA
crypt( 8B AE AE E4 9A 9F 00 80 )=..cSVY0lhu7BA

Cygwin
crypt( 8B AE AE E4 9A 9F 80 82 )=..riUAaAAAAAA
crypt( 8B AE AE E4 9A 9F 80 00 )=..cSVY0lhu7BA
crypt( 8B AE AE E4 9A 9F 00 82 )=..cSVY0lhu7BA
crypt( 8B AE AE E4 9A 9F 00 80 )=..cSVY0lhu7BA

Darwin 8.11.0 (MacOSX PPC)
crypt( 8B AE AE E4 9A 9F 80 82 )=..riUAaAAAAAA
crypt( 8B AE AE E4 9A 9F 80 00 )=..cSVY0lhu7BA
crypt( 8B AE AE E4 9A 9F 00 82 )=..cSVY0lhu7BA
crypt( 8B AE AE E4 9A 9F 00 80 )=..cSVY0lhu7BA

*/

#include <stdio.h>
#include <unistd.h>

static void report(char const *key)
{
        int i;
        printf("crypt(");
        for (i = 0; i < 8; i++) printf(" %02X", key[i] & 0xFF);
        printf(" )=%s\n", crypt(key, ".."));
}

int main()
{
	report("\x8B\xAE\xAE\xE4\x9a\x9F\x80\x82");	/* Incompatible */
        report("\x8B\xAE\xAE\xE4\x9a\x9F\x80\x00");
        report("\x8B\xAE\xAE\xE4\x9a\x9F\x00\x82");
        report("\x8B\xAE\xAE\xE4\x9a\x9F\x00\x80");
        return 0;
}

>Fix:
quoted from crypt_des(), /src/secure/lib/libcrypt/crypt-des.c

	/*
	 * Copy the key, shifting each character up by one bit
	 * and padding with zeros.
	 */
	q = (u_char *)keybuf;
	while (q - (u_char *)keybuf - 8) {
		*q++ = *key << 1;
		if (*(q - 1))
			key++;
	}

for example with minimal modification;

	q = (u_char *)keybuf;
	while (q - (u_char *)keybuf - 8) {
		*q++ = *key << 1;
		if (*key)
			key++;
	}

(I guess it will be also bad code because it is not aliasing-safe)



Or, refer the specific limitation of EOS in the manpage.
(I don't hope)

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list