Add des3 string-to-key. Add ktype argument to krb5_string_to_key().

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@3524 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Johan Danielsson
1997-09-22 16:20:02 +00:00
parent bdf8b7934a
commit 5a3f3a4382

View File

@@ -97,16 +97,17 @@ q = (tbl[q & 0x0F] << 4) | (tbl[q >> 4])
*/ */
static void static void
xor (unsigned char *a, unsigned char *b) xor (des_cblock *key, unsigned char *b)
{ {
a[0] ^= b[0]; unsigned char *a = (unsigned char*)key;
a[1] ^= b[1]; a[0] ^= b[0];
a[2] ^= b[2]; a[1] ^= b[1];
a[3] ^= b[3]; a[2] ^= b[2];
a[4] ^= b[4]; a[3] ^= b[3];
a[5] ^= b[5]; a[4] ^= b[4];
a[6] ^= b[6]; a[5] ^= b[5];
a[7] ^= b[7]; a[6] ^= b[6];
a[7] ^= b[7];
} }
/* /*
@@ -126,18 +127,141 @@ init (unsigned char *a, unsigned char *b)
a[7] = b[7] << 1; a[7] = b[7] << 1;
} }
static void
DES_string_to_key(char *str, size_t len, des_cblock *key)
{
int odd, i;
des_key_schedule sched;
memset (key, 0, sizeof(des_cblock));
odd = 1;
for (i = 0; i < len; i += 8) {
unsigned char tmp[8];
init (tmp, (unsigned char*)&str[i]);
if (odd == 0) {
odd = 1;
reverse (tmp);
init (tmp, tmp);
} else
odd = 0;
xor (key, tmp);
}
des_set_odd_parity (key);
des_set_key (key, sched);
des_cbc_cksum ((des_cblock *)str, key, len, sched, key);
des_set_odd_parity (key);
if (des_is_weak_key (key))
xor (key, (unsigned char*)"\0\0\0\0\0\0\0\xf0");
}
static int
gcd(int a, int b)
{
do{
int r = a % b;
a = b;
b = r;
}while(b);
return a;
}
static void
rr13(unsigned char *buf, size_t len)
{
unsigned char *tmp = malloc(len);
int i;
for(i = 0; i < len; i++){
int x = (buf[i] << 8) | buf[(i + 1) % len];
x >>= 5;
tmp[(i + 2) % len] = x & 0xff;
}
memcpy(buf, tmp, len);
free(tmp);
}
static void
add1(unsigned char *a, unsigned char *b, size_t len)
{
int i;
int carry = 0;
for(i = len - 1; i >= 0; i--){
int x = a[i] + b[i];
carry = x > 0xff;
a[i] = x & 0xff;
}
for(i = len - 1; carry && i >= 0; i--){
int x = a[i] + carry;
carry = x > 0xff;
a[i] = carry & 0xff;
}
}
static void
fold(const unsigned char *str, size_t len, unsigned char *out)
{
const int size = 24;
unsigned char key[24];
int num = 0;
int i;
int lcm = size * len / gcd(size, len);
unsigned char *tmp = malloc(lcm);
unsigned char *buf = malloc(len);
memcpy(buf, str, len);
for(; num < lcm; num += len){
memcpy(tmp + num, buf, len);
rr13(buf, len);
}
free(buf);
memset(key, 0, sizeof(key));
for(i = 0; i < lcm; i += size)
add1(key, tmp + i, size);
memcpy(out, key, size);
}
void
DES3_string_to_key(char *str, size_t len, des_cblock *keys)
{
unsigned char tmp[24];
des_cblock ivec;
des_key_schedule s[3];
int i;
fold(str, len, tmp);
for(i = 0; i < 3; i++){
memcpy(keys + i, tmp + 8 * i, 8);
des_set_odd_parity(keys + i);
if(des_is_weak_key(keys + i))
xor(keys + i, (unsigned char*)"\0\0\0\0\0\0\0\xf0");
des_set_key(keys + i, s + i);
}
memset(&ivec, 0, sizeof(ivec));
des_ede3_cbc_encrypt((void*)tmp, (void*)tmp, sizeof(tmp),
s[0], s[1], s[2], &ivec, 1);
memset(s, 0, sizeof(s));
for(i = 0; i < 3; i++){
memcpy(keys + i, tmp + 8 * i, 8);
des_set_odd_parity(keys + i);
if(des_is_weak_key(keys + i))
xor(keys + i, (unsigned char*)"\0\0\0\0\0\0\0\xf0");
}
memset(tmp, 0, sizeof(tmp));
}
static krb5_error_code static krb5_error_code
string_to_key_internal (char *str, string_to_key_internal (char *str,
size_t str_len, size_t str_len,
krb5_data *salt, krb5_data *salt,
krb5_keytype ktype,
krb5_keyblock *key) krb5_keyblock *key)
{ {
int odd, i;
size_t len; size_t len;
char *s, *p; char *s, *p;
des_cblock tempkey; krb5_error_code ret;
des_key_schedule sched;
krb5_error_code err;
len = str_len + salt->length; len = str_len + salt->length;
#if 1 #if 1
@@ -146,57 +270,54 @@ string_to_key_internal (char *str,
p = s = malloc (len); p = s = malloc (len);
if (p == NULL) if (p == NULL)
return ENOMEM; return ENOMEM;
err = krb5_data_alloc (&key->keyvalue, sizeof(des_cblock));
if (err) {
free (p);
return err;
}
memset (s, 0, len); memset (s, 0, len);
strncpy (p, str, str_len); strncpy (p, str, str_len);
p += str_len; p += str_len;
memcpy (p, salt->data, salt->length); memcpy (p, salt->data, salt->length);
odd = 1;
memset (tempkey, 0, sizeof(tempkey));
for (i = 0; i < len; i += 8) {
unsigned char tmp[8];
init (tmp, (unsigned char*)&s[i]); switch(ktype){
case KEYTYPE_DES:{
if (odd == 0) { des_cblock tmpkey;
odd = 1; DES_string_to_key(s, len, &tmpkey);
reverse (tmp); ret = krb5_data_copy(&key->keyvalue, tmpkey, sizeof(des_cblock));
init (tmp, tmp); memset(&tmpkey, 0, sizeof(tmpkey));
} else break;
odd = 0;
xor (tempkey, tmp);
} }
des_set_odd_parity (&tempkey); case KEYTYPE_DES3:{
des_set_key (&tempkey, sched); des_cblock keys[3];
des_cbc_cksum ((des_cblock *)s, &tempkey, len, sched, &tempkey); DES3_string_to_key(s, len, keys);
free (s); ret = krb5_data_copy(&key->keyvalue, keys, sizeof(keys));
des_set_odd_parity (&tempkey); memset(keys, 0, sizeof(keys));
if (des_is_weak_key (&tempkey)) break;
xor ((unsigned char *)&tempkey, (unsigned char*)"\0\0\0\0\0\0\0\xf0"); }
memcpy (key->keyvalue.data, &tempkey, sizeof(tempkey)); default:
key->keytype = KEYTYPE_DES; abort();
key->keyvalue.length = sizeof(tempkey); break;
}
if(ret)
return ret;
memset(s, 0, len);
free(s);
key->keytype = ktype;
return 0; return 0;
} }
krb5_error_code krb5_error_code
krb5_string_to_key (char *str, krb5_string_to_key (char *str,
krb5_data *salt, krb5_data *salt,
krb5_keytype ktype,
krb5_keyblock *key) krb5_keyblock *key)
{ {
return string_to_key_internal (str, strlen(str), salt, key); return string_to_key_internal (str, strlen(str), salt, ktype, key);
} }
krb5_error_code krb5_error_code
krb5_string_to_key_data (krb5_data *str, krb5_string_to_key_data (krb5_data *str,
krb5_data *salt, krb5_data *salt,
krb5_keytype ktype,
krb5_keyblock *key) krb5_keyblock *key)
{ {
return string_to_key_internal (str->data, str->length, salt, key); return string_to_key_internal (str->data, str->length, salt, ktype, key);
} }
krb5_error_code krb5_error_code