Changeset View
Changeset View
Standalone View
Standalone View
head/secure/lib/libcrypt/crypt-des.c
Show First 20 Lines • Show All 582 Lines • ▼ Show 20 Lines | des_cipher(const char *in, char *out, u_long salt, int count) | ||||
retval = do_des(rawl, rawr, &l_out, &r_out, count); | retval = do_des(rawl, rawr, &l_out, &r_out, count); | ||||
trans.c = out; | trans.c = out; | ||||
*trans.ui32++ = htonl(l_out); | *trans.ui32++ = htonl(l_out); | ||||
*trans.ui32 = htonl(r_out); | *trans.ui32 = htonl(r_out); | ||||
return(retval); | return(retval); | ||||
} | } | ||||
char * | int | ||||
crypt_des(const char *key, const char *setting) | crypt_des(const char *key, const char *setting, char *buffer) | ||||
{ | { | ||||
int i; | int i; | ||||
u_int32_t count, salt, l, r0, r1, keybuf[2]; | u_int32_t count, salt, l, r0, r1, keybuf[2]; | ||||
u_char *p, *q; | u_char *q; | ||||
static char output[21]; | |||||
if (!des_initialised) | if (!des_initialised) | ||||
des_init(); | des_init(); | ||||
/* | /* | ||||
* Copy the key, shifting each character up by one bit | * Copy the key, shifting each character up by one bit | ||||
* and padding with zeros. | * and padding with zeros. | ||||
*/ | */ | ||||
q = (u_char *)keybuf; | q = (u_char *)keybuf; | ||||
while (q - (u_char *)keybuf - 8) { | while (q - (u_char *)keybuf - 8) { | ||||
*q++ = *key << 1; | *q++ = *key << 1; | ||||
if (*key != '\0') | if (*key != '\0') | ||||
key++; | key++; | ||||
} | } | ||||
if (des_setkey((char *)keybuf)) | if (des_setkey((char *)keybuf)) | ||||
return(NULL); | return (-1); | ||||
if (*setting == _PASSWORD_EFMT1) { | if (*setting == _PASSWORD_EFMT1) { | ||||
/* | /* | ||||
* "new"-style: | * "new"-style: | ||||
* setting - underscore, 4 bytes of count, 4 bytes of salt | * setting - underscore, 4 bytes of count, 4 bytes of salt | ||||
* key - unlimited characters | * key - unlimited characters | ||||
*/ | */ | ||||
for (i = 1, count = 0L; i < 5; i++) | for (i = 1, count = 0L; i < 5; i++) | ||||
count |= ascii_to_bin(setting[i]) << ((i - 1) * 6); | count |= ascii_to_bin(setting[i]) << ((i - 1) * 6); | ||||
for (i = 5, salt = 0L; i < 9; i++) | for (i = 5, salt = 0L; i < 9; i++) | ||||
salt |= ascii_to_bin(setting[i]) << ((i - 5) * 6); | salt |= ascii_to_bin(setting[i]) << ((i - 5) * 6); | ||||
while (*key) { | while (*key) { | ||||
/* | /* | ||||
* Encrypt the key with itself. | * Encrypt the key with itself. | ||||
*/ | */ | ||||
if (des_cipher((char *)keybuf, (char *)keybuf, 0L, 1)) | if (des_cipher((char *)keybuf, (char *)keybuf, 0L, 1)) | ||||
return(NULL); | return (-1); | ||||
/* | /* | ||||
* And XOR with the next 8 characters of the key. | * And XOR with the next 8 characters of the key. | ||||
*/ | */ | ||||
q = (u_char *)keybuf; | q = (u_char *)keybuf; | ||||
while (q - (u_char *)keybuf - 8 && *key) | while (q - (u_char *)keybuf - 8 && *key) | ||||
*q++ ^= *key++ << 1; | *q++ ^= *key++ << 1; | ||||
if (des_setkey((char *)keybuf)) | if (des_setkey((char *)keybuf)) | ||||
return(NULL); | return (-1); | ||||
} | } | ||||
strncpy(output, setting, 9); | buffer = stpncpy(buffer, setting, 9); | ||||
/* | |||||
* Double check that we weren't given a short setting. | |||||
* If we were, the above code will probably have created | |||||
* wierd values for count and salt, but we don't really care. | |||||
* Just make sure the output string doesn't have an extra | |||||
* NUL in it. | |||||
*/ | |||||
output[9] = '\0'; | |||||
p = (u_char *)output + strlen(output); | |||||
} else { | } else { | ||||
/* | /* | ||||
* "old"-style: | * "old"-style: | ||||
* setting - 2 bytes of salt | * setting - 2 bytes of salt | ||||
* key - up to 8 characters | * key - up to 8 characters | ||||
*/ | */ | ||||
count = 25; | count = 25; | ||||
salt = (ascii_to_bin(setting[1]) << 6) | salt = (ascii_to_bin(setting[1]) << 6) | ||||
| ascii_to_bin(setting[0]); | | ascii_to_bin(setting[0]); | ||||
output[0] = setting[0]; | *buffer++ = setting[0]; | ||||
/* | /* | ||||
* If the encrypted password that the salt was extracted from | * If the encrypted password that the salt was extracted from | ||||
* is only 1 character long, the salt will be corrupted. We | * is only 1 character long, the salt will be corrupted. We | ||||
* need to ensure that the output string doesn't have an extra | * need to ensure that the output string doesn't have an extra | ||||
* NUL in it! | * NUL in it! | ||||
*/ | */ | ||||
output[1] = setting[1] ? setting[1] : output[0]; | *buffer++ = setting[1] ? setting[1] : setting[0]; | ||||
p = (u_char *)output + 2; | |||||
} | } | ||||
setup_salt(salt); | setup_salt(salt); | ||||
/* | /* | ||||
* Do it. | * Do it. | ||||
*/ | */ | ||||
if (do_des(0L, 0L, &r0, &r1, (int)count)) | if (do_des(0L, 0L, &r0, &r1, (int)count)) | ||||
return(NULL); | return (-1); | ||||
/* | /* | ||||
* Now encode the result... | * Now encode the result... | ||||
*/ | */ | ||||
l = (r0 >> 8); | l = (r0 >> 8); | ||||
*p++ = ascii64[(l >> 18) & 0x3f]; | *buffer++ = ascii64[(l >> 18) & 0x3f]; | ||||
*p++ = ascii64[(l >> 12) & 0x3f]; | *buffer++ = ascii64[(l >> 12) & 0x3f]; | ||||
*p++ = ascii64[(l >> 6) & 0x3f]; | *buffer++ = ascii64[(l >> 6) & 0x3f]; | ||||
*p++ = ascii64[l & 0x3f]; | *buffer++ = ascii64[l & 0x3f]; | ||||
l = (r0 << 16) | ((r1 >> 16) & 0xffff); | l = (r0 << 16) | ((r1 >> 16) & 0xffff); | ||||
*p++ = ascii64[(l >> 18) & 0x3f]; | *buffer++ = ascii64[(l >> 18) & 0x3f]; | ||||
*p++ = ascii64[(l >> 12) & 0x3f]; | *buffer++ = ascii64[(l >> 12) & 0x3f]; | ||||
*p++ = ascii64[(l >> 6) & 0x3f]; | *buffer++ = ascii64[(l >> 6) & 0x3f]; | ||||
*p++ = ascii64[l & 0x3f]; | *buffer++ = ascii64[l & 0x3f]; | ||||
l = r1 << 2; | l = r1 << 2; | ||||
*p++ = ascii64[(l >> 12) & 0x3f]; | *buffer++ = ascii64[(l >> 12) & 0x3f]; | ||||
*p++ = ascii64[(l >> 6) & 0x3f]; | *buffer++ = ascii64[(l >> 6) & 0x3f]; | ||||
*p++ = ascii64[l & 0x3f]; | *buffer++ = ascii64[l & 0x3f]; | ||||
*p = 0; | *buffer = '\0'; | ||||
return(output); | return (0); | ||||
} | } |