introduce the `special' encryption methods that are not like all other
encryption methods and implement arcfour-hmac-md5 git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@8560 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -65,6 +65,7 @@ struct krb5_crypto_data {
|
|||||||
#define F_DERIVED 4 /* uses derived keys */
|
#define F_DERIVED 4 /* uses derived keys */
|
||||||
#define F_VARIANT 8 /* uses `variant' keys (6.4.3) */
|
#define F_VARIANT 8 /* uses `variant' keys (6.4.3) */
|
||||||
#define F_PSEUDO 16 /* not a real protocol type */
|
#define F_PSEUDO 16 /* not a real protocol type */
|
||||||
|
#define F_SPECIAL 32 /* backwards */
|
||||||
|
|
||||||
struct salt_type {
|
struct salt_type {
|
||||||
krb5_salttype type;
|
krb5_salttype type;
|
||||||
@@ -93,9 +94,16 @@ struct checksum_type {
|
|||||||
size_t blocksize;
|
size_t blocksize;
|
||||||
size_t checksumsize;
|
size_t checksumsize;
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
void (*checksum)(krb5_context, struct key_data*, void*, size_t, Checksum*);
|
void (*checksum)(krb5_context context,
|
||||||
krb5_error_code (*verify)(krb5_context, struct key_data*,
|
struct key_data *key,
|
||||||
void*, size_t, Checksum*);
|
const void *buf, size_t len,
|
||||||
|
unsigned usage,
|
||||||
|
Checksum *csum);
|
||||||
|
krb5_error_code (*verify)(krb5_context context,
|
||||||
|
struct key_data *key,
|
||||||
|
const void *buf, size_t len,
|
||||||
|
unsigned usage,
|
||||||
|
Checksum *csum);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct encryption_type {
|
struct encryption_type {
|
||||||
@@ -107,7 +115,10 @@ struct encryption_type {
|
|||||||
struct checksum_type *cksumtype;
|
struct checksum_type *cksumtype;
|
||||||
struct checksum_type *keyed_checksum;
|
struct checksum_type *keyed_checksum;
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
void (*encrypt)(struct key_data *, void *, size_t, int);
|
krb5_error_code (*encrypt)(struct key_data *key,
|
||||||
|
void *data, size_t len,
|
||||||
|
krb5_boolean encrypt,
|
||||||
|
int usage);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ENCRYPTION_USAGE(U) (((U) << 8) | 0xAA)
|
#define ENCRYPTION_USAGE(U) (((U) << 8) | 0xAA)
|
||||||
@@ -228,14 +239,12 @@ DES_AFS3_Transarc_string_to_key (krb5_data pw,
|
|||||||
memcpy(&temp_key, "kerberos", 8);
|
memcpy(&temp_key, "kerberos", 8);
|
||||||
des_set_odd_parity (&temp_key);
|
des_set_odd_parity (&temp_key);
|
||||||
des_set_key (&temp_key, schedule);
|
des_set_key (&temp_key, schedule);
|
||||||
des_cbc_cksum ((const void *)password, &ivec, passlen,
|
des_cbc_cksum ((des_cblock *)password, &ivec, passlen, schedule, &ivec);
|
||||||
schedule, &ivec);
|
|
||||||
|
|
||||||
memcpy(&temp_key, &ivec, 8);
|
memcpy(&temp_key, &ivec, 8);
|
||||||
des_set_odd_parity (&temp_key);
|
des_set_odd_parity (&temp_key);
|
||||||
des_set_key (&temp_key, schedule);
|
des_set_key (&temp_key, schedule);
|
||||||
des_cbc_cksum ((const void *)password, key, passlen,
|
des_cbc_cksum ((des_cblock *)password, key, passlen, schedule, &ivec);
|
||||||
schedule, &ivec);
|
|
||||||
memset(&schedule, 0, sizeof(schedule));
|
memset(&schedule, 0, sizeof(schedule));
|
||||||
memset(&temp_key, 0, sizeof(temp_key));
|
memset(&temp_key, 0, sizeof(temp_key));
|
||||||
memset(&ivec, 0, sizeof(ivec));
|
memset(&ivec, 0, sizeof(ivec));
|
||||||
@@ -339,8 +348,8 @@ DES3_string_to_key(krb5_context context,
|
|||||||
des_set_key(keys + i, s[i]);
|
des_set_key(keys + i, s[i]);
|
||||||
}
|
}
|
||||||
memset(&ivec, 0, sizeof(ivec));
|
memset(&ivec, 0, sizeof(ivec));
|
||||||
des_ede3_cbc_encrypt((const void *)tmp,
|
des_ede3_cbc_encrypt((des_cblock *)tmp,
|
||||||
(void *)tmp, sizeof(tmp),
|
(des_cblock *)tmp, sizeof(tmp),
|
||||||
s[0], s[1], s[2], &ivec, DES_ENCRYPT);
|
s[0], s[1], s[2], &ivec, DES_ENCRYPT);
|
||||||
memset(s, 0, sizeof(s));
|
memset(s, 0, sizeof(s));
|
||||||
memset(&ivec, 0, sizeof(ivec));
|
memset(&ivec, 0, sizeof(ivec));
|
||||||
@@ -416,7 +425,7 @@ ARCFOUR_string_to_key(krb5_context context,
|
|||||||
int i;
|
int i;
|
||||||
MD4_CTX m;
|
MD4_CTX m;
|
||||||
|
|
||||||
len = 2 * (password.length + salt.saltvalue.length);
|
len = 2 * password.length;
|
||||||
s = malloc (len);
|
s = malloc (len);
|
||||||
if (len != 0 && s == NULL)
|
if (len != 0 && s == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
@@ -424,10 +433,6 @@ ARCFOUR_string_to_key(krb5_context context,
|
|||||||
*p++ = ((char *)password.data)[i];
|
*p++ = ((char *)password.data)[i];
|
||||||
*p++ = 0;
|
*p++ = 0;
|
||||||
}
|
}
|
||||||
for (i = 0; i < salt.saltvalue.length; ++i) {
|
|
||||||
*p++ = ((char *)salt.saltvalue.data)[i];
|
|
||||||
*p++ = 0;
|
|
||||||
}
|
|
||||||
MD4Init (&m);
|
MD4Init (&m);
|
||||||
MD4Update (&m, s, len);
|
MD4Update (&m, s, len);
|
||||||
key->keytype = enctype;
|
key->keytype = enctype;
|
||||||
@@ -670,6 +675,11 @@ krb5_string_to_key (krb5_context context,
|
|||||||
return krb5_string_to_key_data(context, enctype, pw, principal, key);
|
return krb5_string_to_key_data(context, enctype, pw, principal, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do a string -> key for encryption type `enctype' operation on
|
||||||
|
* `password' (with salt `salt'), returning the resulting key in `key'
|
||||||
|
*/
|
||||||
|
|
||||||
krb5_error_code
|
krb5_error_code
|
||||||
krb5_string_to_key_data_salt (krb5_context context,
|
krb5_string_to_key_data_salt (krb5_context context,
|
||||||
krb5_enctype enctype,
|
krb5_enctype enctype,
|
||||||
@@ -687,6 +697,12 @@ krb5_string_to_key_data_salt (krb5_context context,
|
|||||||
return HEIM_ERR_SALTTYPE_NOSUPP;
|
return HEIM_ERR_SALTTYPE_NOSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do a string -> key for encryption type `enctype' operation on the
|
||||||
|
* string `password' (with salt `salt'), returning the resulting key
|
||||||
|
* in `key'
|
||||||
|
*/
|
||||||
|
|
||||||
krb5_error_code
|
krb5_error_code
|
||||||
krb5_string_to_key_salt (krb5_context context,
|
krb5_string_to_key_salt (krb5_context context,
|
||||||
krb5_enctype enctype,
|
krb5_enctype enctype,
|
||||||
@@ -779,8 +795,9 @@ _key_schedule(krb5_context context,
|
|||||||
static void
|
static void
|
||||||
NONE_checksum(krb5_context context,
|
NONE_checksum(krb5_context context,
|
||||||
struct key_data *key,
|
struct key_data *key,
|
||||||
void *data,
|
const void *data,
|
||||||
size_t len,
|
size_t len,
|
||||||
|
unsigned usage,
|
||||||
Checksum *C)
|
Checksum *C)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -788,8 +805,9 @@ NONE_checksum(krb5_context context,
|
|||||||
static void
|
static void
|
||||||
CRC32_checksum(krb5_context context,
|
CRC32_checksum(krb5_context context,
|
||||||
struct key_data *key,
|
struct key_data *key,
|
||||||
void *data,
|
const void *data,
|
||||||
size_t len,
|
size_t len,
|
||||||
|
unsigned usage,
|
||||||
Checksum *C)
|
Checksum *C)
|
||||||
{
|
{
|
||||||
u_int32_t crc;
|
u_int32_t crc;
|
||||||
@@ -805,8 +823,9 @@ CRC32_checksum(krb5_context context,
|
|||||||
static void
|
static void
|
||||||
RSA_MD4_checksum(krb5_context context,
|
RSA_MD4_checksum(krb5_context context,
|
||||||
struct key_data *key,
|
struct key_data *key,
|
||||||
void *data,
|
const void *data,
|
||||||
size_t len,
|
size_t len,
|
||||||
|
unsigned usage,
|
||||||
Checksum *C)
|
Checksum *C)
|
||||||
{
|
{
|
||||||
MD4_CTX m;
|
MD4_CTX m;
|
||||||
@@ -819,8 +838,9 @@ RSA_MD4_checksum(krb5_context context,
|
|||||||
static void
|
static void
|
||||||
RSA_MD4_DES_checksum(krb5_context context,
|
RSA_MD4_DES_checksum(krb5_context context,
|
||||||
struct key_data *key,
|
struct key_data *key,
|
||||||
void *data,
|
const void *data,
|
||||||
size_t len,
|
size_t len,
|
||||||
|
unsigned usage,
|
||||||
Checksum *cksum)
|
Checksum *cksum)
|
||||||
{
|
{
|
||||||
MD4_CTX md4;
|
MD4_CTX md4;
|
||||||
@@ -833,8 +853,8 @@ RSA_MD4_DES_checksum(krb5_context context,
|
|||||||
MD4Update (&md4, data, len);
|
MD4Update (&md4, data, len);
|
||||||
MD4Final (p + 8, &md4);
|
MD4Final (p + 8, &md4);
|
||||||
memset (&ivec, 0, sizeof(ivec));
|
memset (&ivec, 0, sizeof(ivec));
|
||||||
des_cbc_encrypt((const void *)p,
|
des_cbc_encrypt((des_cblock*)p,
|
||||||
(void *)p,
|
(des_cblock*)p,
|
||||||
24,
|
24,
|
||||||
key->schedule->data,
|
key->schedule->data,
|
||||||
&ivec,
|
&ivec,
|
||||||
@@ -844,8 +864,9 @@ RSA_MD4_DES_checksum(krb5_context context,
|
|||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
RSA_MD4_DES_verify(krb5_context context,
|
RSA_MD4_DES_verify(krb5_context context,
|
||||||
struct key_data *key,
|
struct key_data *key,
|
||||||
void *data,
|
const void *data,
|
||||||
size_t len,
|
size_t len,
|
||||||
|
unsigned usage,
|
||||||
Checksum *C)
|
Checksum *C)
|
||||||
{
|
{
|
||||||
MD4_CTX md4;
|
MD4_CTX md4;
|
||||||
@@ -875,8 +896,9 @@ RSA_MD4_DES_verify(krb5_context context,
|
|||||||
static void
|
static void
|
||||||
RSA_MD5_checksum(krb5_context context,
|
RSA_MD5_checksum(krb5_context context,
|
||||||
struct key_data *key,
|
struct key_data *key,
|
||||||
void *data,
|
const void *data,
|
||||||
size_t len,
|
size_t len,
|
||||||
|
unsigned usage,
|
||||||
Checksum *C)
|
Checksum *C)
|
||||||
{
|
{
|
||||||
MD5_CTX m;
|
MD5_CTX m;
|
||||||
@@ -889,8 +911,9 @@ RSA_MD5_checksum(krb5_context context,
|
|||||||
static void
|
static void
|
||||||
RSA_MD5_DES_checksum(krb5_context context,
|
RSA_MD5_DES_checksum(krb5_context context,
|
||||||
struct key_data *key,
|
struct key_data *key,
|
||||||
void *data,
|
const void *data,
|
||||||
size_t len,
|
size_t len,
|
||||||
|
unsigned usage,
|
||||||
Checksum *C)
|
Checksum *C)
|
||||||
{
|
{
|
||||||
MD5_CTX md5;
|
MD5_CTX md5;
|
||||||
@@ -903,8 +926,8 @@ RSA_MD5_DES_checksum(krb5_context context,
|
|||||||
MD5Update (&md5, data, len);
|
MD5Update (&md5, data, len);
|
||||||
MD5Final (p + 8, &md5);
|
MD5Final (p + 8, &md5);
|
||||||
memset (&ivec, 0, sizeof(ivec));
|
memset (&ivec, 0, sizeof(ivec));
|
||||||
des_cbc_encrypt((const void *)p,
|
des_cbc_encrypt((des_cblock*)p,
|
||||||
(void *)p,
|
(des_cblock*)p,
|
||||||
24,
|
24,
|
||||||
key->schedule->data,
|
key->schedule->data,
|
||||||
&ivec,
|
&ivec,
|
||||||
@@ -914,8 +937,9 @@ RSA_MD5_DES_checksum(krb5_context context,
|
|||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
RSA_MD5_DES_verify(krb5_context context,
|
RSA_MD5_DES_verify(krb5_context context,
|
||||||
struct key_data *key,
|
struct key_data *key,
|
||||||
void *data,
|
const void *data,
|
||||||
size_t len,
|
size_t len,
|
||||||
|
unsigned usage,
|
||||||
Checksum *C)
|
Checksum *C)
|
||||||
{
|
{
|
||||||
MD5_CTX md5;
|
MD5_CTX md5;
|
||||||
@@ -946,8 +970,9 @@ RSA_MD5_DES_verify(krb5_context context,
|
|||||||
static void
|
static void
|
||||||
RSA_MD5_DES3_checksum(krb5_context context,
|
RSA_MD5_DES3_checksum(krb5_context context,
|
||||||
struct key_data *key,
|
struct key_data *key,
|
||||||
void *data,
|
const void *data,
|
||||||
size_t len,
|
size_t len,
|
||||||
|
unsigned usage,
|
||||||
Checksum *C)
|
Checksum *C)
|
||||||
{
|
{
|
||||||
MD5_CTX md5;
|
MD5_CTX md5;
|
||||||
@@ -961,8 +986,8 @@ RSA_MD5_DES3_checksum(krb5_context context,
|
|||||||
MD5Update (&md5, data, len);
|
MD5Update (&md5, data, len);
|
||||||
MD5Final (p + 8, &md5);
|
MD5Final (p + 8, &md5);
|
||||||
memset (&ivec, 0, sizeof(ivec));
|
memset (&ivec, 0, sizeof(ivec));
|
||||||
des_ede3_cbc_encrypt((const void *)p,
|
des_ede3_cbc_encrypt((des_cblock*)p,
|
||||||
(void *)p,
|
(des_cblock*)p,
|
||||||
24,
|
24,
|
||||||
sched[0], sched[1], sched[2],
|
sched[0], sched[1], sched[2],
|
||||||
&ivec,
|
&ivec,
|
||||||
@@ -972,8 +997,9 @@ RSA_MD5_DES3_checksum(krb5_context context,
|
|||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
RSA_MD5_DES3_verify(krb5_context context,
|
RSA_MD5_DES3_verify(krb5_context context,
|
||||||
struct key_data *key,
|
struct key_data *key,
|
||||||
void *data,
|
const void *data,
|
||||||
size_t len,
|
size_t len,
|
||||||
|
unsigned usage,
|
||||||
Checksum *C)
|
Checksum *C)
|
||||||
{
|
{
|
||||||
MD5_CTX md5;
|
MD5_CTX md5;
|
||||||
@@ -1004,8 +1030,9 @@ RSA_MD5_DES3_verify(krb5_context context,
|
|||||||
static void
|
static void
|
||||||
SHA1_checksum(krb5_context context,
|
SHA1_checksum(krb5_context context,
|
||||||
struct key_data *key,
|
struct key_data *key,
|
||||||
void *data,
|
const void *data,
|
||||||
size_t len,
|
size_t len,
|
||||||
|
unsigned usage,
|
||||||
Checksum *C)
|
Checksum *C)
|
||||||
{
|
{
|
||||||
SHA1_CTX m;
|
SHA1_CTX m;
|
||||||
@@ -1019,8 +1046,9 @@ SHA1_checksum(krb5_context context,
|
|||||||
static void
|
static void
|
||||||
hmac(krb5_context context,
|
hmac(krb5_context context,
|
||||||
struct checksum_type *cm,
|
struct checksum_type *cm,
|
||||||
void *data,
|
const void *data,
|
||||||
size_t len,
|
size_t len,
|
||||||
|
unsigned usage,
|
||||||
struct key_data *keyblock,
|
struct key_data *keyblock,
|
||||||
Checksum *result)
|
Checksum *result)
|
||||||
{
|
{
|
||||||
@@ -1034,6 +1062,7 @@ hmac(krb5_context context,
|
|||||||
keyblock,
|
keyblock,
|
||||||
keyblock->key->keyvalue.data,
|
keyblock->key->keyvalue.data,
|
||||||
keyblock->key->keyvalue.length,
|
keyblock->key->keyvalue.length,
|
||||||
|
usage,
|
||||||
result);
|
result);
|
||||||
key = result->checksum.data;
|
key = result->checksum.data;
|
||||||
key_len = result->checksum.length;
|
key_len = result->checksum.length;
|
||||||
@@ -1050,11 +1079,12 @@ hmac(krb5_context context,
|
|||||||
opad[i] ^= key[i];
|
opad[i] ^= key[i];
|
||||||
}
|
}
|
||||||
memcpy(ipad + cm->blocksize, data, len);
|
memcpy(ipad + cm->blocksize, data, len);
|
||||||
(*cm->checksum)(context, keyblock, ipad, cm->blocksize + len, result);
|
(*cm->checksum)(context, keyblock, ipad, cm->blocksize + len,
|
||||||
|
usage, result);
|
||||||
memcpy(opad + cm->blocksize, result->checksum.data,
|
memcpy(opad + cm->blocksize, result->checksum.data,
|
||||||
result->checksum.length);
|
result->checksum.length);
|
||||||
(*cm->checksum)(context, keyblock, opad,
|
(*cm->checksum)(context, keyblock, opad,
|
||||||
cm->blocksize + cm->checksumsize, result);
|
cm->blocksize + cm->checksumsize, usage, result);
|
||||||
memset(ipad, 0, cm->blocksize + len);
|
memset(ipad, 0, cm->blocksize + len);
|
||||||
free(ipad);
|
free(ipad);
|
||||||
memset(opad, 0, cm->blocksize + cm->checksumsize);
|
memset(opad, 0, cm->blocksize + cm->checksumsize);
|
||||||
@@ -1064,13 +1094,84 @@ hmac(krb5_context context,
|
|||||||
static void
|
static void
|
||||||
HMAC_SHA1_DES3_checksum(krb5_context context,
|
HMAC_SHA1_DES3_checksum(krb5_context context,
|
||||||
struct key_data *key,
|
struct key_data *key,
|
||||||
void *data,
|
const void *data,
|
||||||
size_t len,
|
size_t len,
|
||||||
|
unsigned usage,
|
||||||
Checksum *result)
|
Checksum *result)
|
||||||
{
|
{
|
||||||
struct checksum_type *c = _find_checksum(CKSUMTYPE_SHA1);
|
struct checksum_type *c = _find_checksum(CKSUMTYPE_SHA1);
|
||||||
|
|
||||||
hmac(context, c, data, len, key, result);
|
hmac(context, c, data, len, usage, key, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* checksum according to section 5. of draft-brezak-win2k-krb-rc4-hmac-03.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
HMAC_MD5_checksum(krb5_context context,
|
||||||
|
struct key_data *key,
|
||||||
|
const void *data,
|
||||||
|
size_t len,
|
||||||
|
unsigned usage,
|
||||||
|
Checksum *result)
|
||||||
|
{
|
||||||
|
MD5_CTX md5;
|
||||||
|
struct checksum_type *c = _find_checksum (CKSUMTYPE_RSA_MD5);
|
||||||
|
const char signature[] = "signaturekey";
|
||||||
|
Checksum ksign_c;
|
||||||
|
struct key_data ksign;
|
||||||
|
krb5_keyblock kb;
|
||||||
|
unsigned char t[4];
|
||||||
|
unsigned char tmp[16];
|
||||||
|
unsigned char ksign_c_data[16];
|
||||||
|
|
||||||
|
ksign_c.checksum.length = sizeof(ksign_c_data);
|
||||||
|
ksign_c.checksum.data = ksign_c_data;
|
||||||
|
hmac(context, c, signature, sizeof(signature), 0, key, &ksign_c);
|
||||||
|
ksign.key = &kb;
|
||||||
|
kb.keyvalue = ksign_c.checksum;
|
||||||
|
MD5Init (&md5);
|
||||||
|
t[0] = (usage >> 0) & 0xFF;
|
||||||
|
t[1] = (usage >> 8) & 0xFF;
|
||||||
|
t[2] = (usage >> 16) & 0xFF;
|
||||||
|
t[3] = (usage >> 24) & 0xFF;
|
||||||
|
MD5Update (&md5, t, 4);
|
||||||
|
MD5Update (&md5, data, len);
|
||||||
|
MD5Final (tmp, &md5);
|
||||||
|
hmac(context, c, tmp, sizeof(tmp), 0, &ksign, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* same as previous but being used while encrypting.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
HMAC_MD5_checksum_enc(krb5_context context,
|
||||||
|
struct key_data *key,
|
||||||
|
const void *data,
|
||||||
|
size_t len,
|
||||||
|
unsigned usage,
|
||||||
|
Checksum *result)
|
||||||
|
{
|
||||||
|
struct checksum_type *c = _find_checksum (CKSUMTYPE_RSA_MD5);
|
||||||
|
Checksum ksign_c;
|
||||||
|
struct key_data ksign;
|
||||||
|
krb5_keyblock kb;
|
||||||
|
unsigned char t[4];
|
||||||
|
unsigned char ksign_c_data[16];
|
||||||
|
|
||||||
|
t[0] = (usage >> 0) & 0xFF;
|
||||||
|
t[1] = (usage >> 8) & 0xFF;
|
||||||
|
t[2] = (usage >> 16) & 0xFF;
|
||||||
|
t[3] = (usage >> 24) & 0xFF;
|
||||||
|
|
||||||
|
ksign_c.checksum.length = sizeof(ksign_c_data);
|
||||||
|
ksign_c.checksum.data = ksign_c_data;
|
||||||
|
hmac(context, c, t, sizeof(t), 0, key, &ksign_c);
|
||||||
|
ksign.key = &kb;
|
||||||
|
kb.keyvalue = ksign_c.checksum;
|
||||||
|
hmac(context, c, data, len, 0, &ksign, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct checksum_type checksum_none = {
|
struct checksum_type checksum_none = {
|
||||||
@@ -1182,6 +1283,26 @@ struct checksum_type checksum_hmac_sha1_des3 = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct checksum_type checksum_hmac_md5 = {
|
||||||
|
CKSUMTYPE_HMAC_MD5,
|
||||||
|
"hmac-md5",
|
||||||
|
64,
|
||||||
|
16,
|
||||||
|
F_KEYED | F_CPROOF,
|
||||||
|
HMAC_MD5_checksum,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
struct checksum_type checksum_hmac_md5_enc = {
|
||||||
|
CKSUMTYPE_HMAC_MD5_ENC,
|
||||||
|
"hmac-md5-enc",
|
||||||
|
64,
|
||||||
|
16,
|
||||||
|
F_KEYED | F_CPROOF | F_PSEUDO,
|
||||||
|
HMAC_MD5_checksum_enc,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
struct checksum_type *checksum_types[] = {
|
struct checksum_type *checksum_types[] = {
|
||||||
&checksum_none,
|
&checksum_none,
|
||||||
&checksum_crc32,
|
&checksum_crc32,
|
||||||
@@ -1196,7 +1317,9 @@ struct checksum_type *checksum_types[] = {
|
|||||||
&checksum_rsa_md5_des,
|
&checksum_rsa_md5_des,
|
||||||
&checksum_rsa_md5_des3,
|
&checksum_rsa_md5_des3,
|
||||||
&checksum_sha1,
|
&checksum_sha1,
|
||||||
&checksum_hmac_sha1_des3
|
&checksum_hmac_sha1_des3,
|
||||||
|
&checksum_hmac_md5,
|
||||||
|
&checksum_hmac_md5_enc
|
||||||
};
|
};
|
||||||
|
|
||||||
static int num_checksums = sizeof(checksum_types) / sizeof(checksum_types[0]);
|
static int num_checksums = sizeof(checksum_types) / sizeof(checksum_types[0]);
|
||||||
@@ -1263,7 +1386,7 @@ do_checksum (krb5_context context,
|
|||||||
dkey = NULL;
|
dkey = NULL;
|
||||||
result->cksumtype = ct->type;
|
result->cksumtype = ct->type;
|
||||||
krb5_data_alloc(&result->checksum, ct->checksumsize);
|
krb5_data_alloc(&result->checksum, ct->checksumsize);
|
||||||
(*ct->checksum)(context, dkey, data, len, result);
|
(*ct->checksum)(context, dkey, data, len, usage, result);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1329,13 +1452,13 @@ verify_checksum(krb5_context context,
|
|||||||
else
|
else
|
||||||
dkey = NULL;
|
dkey = NULL;
|
||||||
if(ct->verify)
|
if(ct->verify)
|
||||||
return (*ct->verify)(context, dkey, data, len, cksum);
|
return (*ct->verify)(context, dkey, data, len, usage, cksum);
|
||||||
|
|
||||||
ret = krb5_data_alloc (&c.checksum, ct->checksumsize);
|
ret = krb5_data_alloc (&c.checksum, ct->checksumsize);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
(*ct->checksum)(context, dkey, data, len, &c);
|
(*ct->checksum)(context, dkey, data, len, usage, &c);
|
||||||
|
|
||||||
if(c.checksum.length != cksum->checksum.length ||
|
if(c.checksum.length != cksum->checksum.length ||
|
||||||
memcmp(c.checksum.data, cksum->checksum.data, c.checksum.length))
|
memcmp(c.checksum.data, cksum->checksum.data, c.checksum.length))
|
||||||
@@ -1394,55 +1517,64 @@ krb5_checksum_is_collision_proof(krb5_context context,
|
|||||||
* *
|
* *
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
static void
|
static krb5_error_code
|
||||||
NULL_encrypt(struct key_data *key,
|
NULL_encrypt(struct key_data *key,
|
||||||
void *data,
|
void *data,
|
||||||
size_t len,
|
size_t len,
|
||||||
krb5_boolean encrypt)
|
krb5_boolean encrypt,
|
||||||
|
int usage)
|
||||||
{
|
{
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static krb5_error_code
|
||||||
DES_CBC_encrypt_null_ivec(struct key_data *key,
|
DES_CBC_encrypt_null_ivec(struct key_data *key,
|
||||||
void *data,
|
void *data,
|
||||||
size_t len,
|
size_t len,
|
||||||
krb5_boolean encrypt)
|
krb5_boolean encrypt,
|
||||||
|
int usage)
|
||||||
{
|
{
|
||||||
des_cblock ivec;
|
des_cblock ivec;
|
||||||
des_key_schedule *s = key->schedule->data;
|
des_key_schedule *s = key->schedule->data;
|
||||||
memset(&ivec, 0, sizeof(ivec));
|
memset(&ivec, 0, sizeof(ivec));
|
||||||
des_cbc_encrypt(data, data, len, *s, &ivec, encrypt);
|
des_cbc_encrypt(data, data, len, *s, &ivec, encrypt);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static krb5_error_code
|
||||||
DES_CBC_encrypt_key_ivec(struct key_data *key,
|
DES_CBC_encrypt_key_ivec(struct key_data *key,
|
||||||
void *data,
|
void *data,
|
||||||
size_t len,
|
size_t len,
|
||||||
krb5_boolean encrypt)
|
krb5_boolean encrypt,
|
||||||
|
int usage)
|
||||||
{
|
{
|
||||||
des_cblock ivec;
|
des_cblock ivec;
|
||||||
des_key_schedule *s = key->schedule->data;
|
des_key_schedule *s = key->schedule->data;
|
||||||
memcpy(&ivec, key->key->keyvalue.data, sizeof(ivec));
|
memcpy(&ivec, key->key->keyvalue.data, sizeof(ivec));
|
||||||
des_cbc_encrypt(data, data, len, *s, &ivec, encrypt);
|
des_cbc_encrypt(data, data, len, *s, &ivec, encrypt);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static krb5_error_code
|
||||||
DES3_CBC_encrypt(struct key_data *key,
|
DES3_CBC_encrypt(struct key_data *key,
|
||||||
void *data,
|
void *data,
|
||||||
size_t len,
|
size_t len,
|
||||||
krb5_boolean encrypt)
|
krb5_boolean encrypt,
|
||||||
|
int usage)
|
||||||
{
|
{
|
||||||
des_cblock ivec;
|
des_cblock ivec;
|
||||||
des_key_schedule *s = key->schedule->data;
|
des_key_schedule *s = key->schedule->data;
|
||||||
memset(&ivec, 0, sizeof(ivec));
|
memset(&ivec, 0, sizeof(ivec));
|
||||||
des_ede3_cbc_encrypt(data, data, len, s[0], s[1], s[2], &ivec, encrypt);
|
des_ede3_cbc_encrypt(data, data, len, s[0], s[1], s[2], &ivec, encrypt);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static krb5_error_code
|
||||||
DES_CFB64_encrypt_null_ivec(struct key_data *key,
|
DES_CFB64_encrypt_null_ivec(struct key_data *key,
|
||||||
void *data,
|
void *data,
|
||||||
size_t len,
|
size_t len,
|
||||||
krb5_boolean encrypt)
|
krb5_boolean encrypt,
|
||||||
|
int usage)
|
||||||
{
|
{
|
||||||
des_cblock ivec;
|
des_cblock ivec;
|
||||||
int num = 0;
|
int num = 0;
|
||||||
@@ -1450,34 +1582,209 @@ DES_CFB64_encrypt_null_ivec(struct key_data *key,
|
|||||||
memset(&ivec, 0, sizeof(ivec));
|
memset(&ivec, 0, sizeof(ivec));
|
||||||
|
|
||||||
des_cfb64_encrypt(data, data, len, *s, &ivec, &num, encrypt);
|
des_cfb64_encrypt(data, data, len, *s, &ivec, &num, encrypt);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static krb5_error_code
|
||||||
DES_PCBC_encrypt_key_ivec(struct key_data *key,
|
DES_PCBC_encrypt_key_ivec(struct key_data *key,
|
||||||
void *data,
|
void *data,
|
||||||
size_t len,
|
size_t len,
|
||||||
krb5_boolean encrypt)
|
krb5_boolean encrypt,
|
||||||
|
int usage)
|
||||||
{
|
{
|
||||||
des_cblock ivec;
|
des_cblock ivec;
|
||||||
des_key_schedule *s = key->schedule->data;
|
des_key_schedule *s = key->schedule->data;
|
||||||
memcpy(&ivec, key->key->keyvalue.data, sizeof(ivec));
|
memcpy(&ivec, key->key->keyvalue.data, sizeof(ivec));
|
||||||
|
|
||||||
des_pcbc_encrypt(data, data, len, *s, &ivec, encrypt);
|
des_pcbc_encrypt(data, data, len, *s, &ivec, encrypt);
|
||||||
}
|
return 0;
|
||||||
|
|
||||||
static void
|
|
||||||
ARCFOUR_encrypt(struct key_data *key,
|
|
||||||
void *data,
|
|
||||||
size_t len,
|
|
||||||
krb5_boolean encrypt)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* these should currently be in reverse preference order.
|
* section 6 of draft-brezak-win2k-krb-rc4-hmac-03
|
||||||
|
*
|
||||||
|
* warning: not for small children
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static krb5_error_code
|
||||||
|
ARCFOUR_subencrypt(struct key_data *key,
|
||||||
|
void *data,
|
||||||
|
size_t len,
|
||||||
|
int usage)
|
||||||
|
{
|
||||||
|
struct checksum_type *c = _find_checksum (CKSUMTYPE_RSA_MD5);
|
||||||
|
Checksum k1_c, k2_c, k3_c, cksum;
|
||||||
|
struct key_data ke;
|
||||||
|
krb5_keyblock kb;
|
||||||
|
unsigned char t[4];
|
||||||
|
RC4_KEY rc4_key;
|
||||||
|
char *cdata = (char *)data;
|
||||||
|
unsigned char k1_c_data[16], k2_c_data[16], k3_c_data[16];
|
||||||
|
|
||||||
|
t[0] = (usage >> 0) & 0xFF;
|
||||||
|
t[1] = (usage >> 8) & 0xFF;
|
||||||
|
t[2] = (usage >> 16) & 0xFF;
|
||||||
|
t[3] = (usage >> 24) & 0xFF;
|
||||||
|
|
||||||
|
k1_c.checksum.length = sizeof(k1_c_data);
|
||||||
|
k1_c.checksum.data = k1_c_data;
|
||||||
|
|
||||||
|
hmac(NULL, c, t, sizeof(t), 0, key, &k1_c);
|
||||||
|
|
||||||
|
memcpy (k2_c_data, k1_c_data, sizeof(k1_c_data));
|
||||||
|
|
||||||
|
k2_c.checksum.length = sizeof(k2_c_data);
|
||||||
|
k2_c.checksum.data = k2_c_data;
|
||||||
|
|
||||||
|
ke.key = &kb;
|
||||||
|
kb.keyvalue = k2_c.checksum;
|
||||||
|
|
||||||
|
cksum.checksum.length = 16;
|
||||||
|
cksum.checksum.data = data;
|
||||||
|
|
||||||
|
hmac(NULL, c, cdata + 16, len - 16, 0, &ke, &cksum);
|
||||||
|
|
||||||
|
ke.key = &kb;
|
||||||
|
kb.keyvalue = k1_c.checksum;
|
||||||
|
|
||||||
|
k3_c.checksum.length = sizeof(k3_c_data);
|
||||||
|
k3_c.checksum.data = k3_c_data;
|
||||||
|
|
||||||
|
hmac(NULL, c, data, 16, 0, &ke, &k3_c);
|
||||||
|
|
||||||
|
RC4_set_key (&rc4_key, k3_c.checksum.length, k3_c.checksum.data);
|
||||||
|
RC4 (&rc4_key, len - 16, cdata + 16, cdata + 16);
|
||||||
|
memset (k1_c_data, 0, sizeof(k1_c_data));
|
||||||
|
memset (k2_c_data, 0, sizeof(k2_c_data));
|
||||||
|
memset (k3_c_data, 0, sizeof(k3_c_data));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static krb5_error_code
|
||||||
|
ARCFOUR_subdecrypt(struct key_data *key,
|
||||||
|
void *data,
|
||||||
|
size_t len,
|
||||||
|
int usage)
|
||||||
|
{
|
||||||
|
struct checksum_type *c = _find_checksum (CKSUMTYPE_RSA_MD5);
|
||||||
|
Checksum k1_c, k2_c, k3_c, cksum;
|
||||||
|
struct key_data ke;
|
||||||
|
krb5_keyblock kb;
|
||||||
|
unsigned char t[4];
|
||||||
|
RC4_KEY rc4_key;
|
||||||
|
char *cdata = (char *)data;
|
||||||
|
unsigned char k1_c_data[16], k2_c_data[16], k3_c_data[16];
|
||||||
|
unsigned char cksum_data[16];
|
||||||
|
|
||||||
|
t[0] = (usage >> 0) & 0xFF;
|
||||||
|
t[1] = (usage >> 8) & 0xFF;
|
||||||
|
t[2] = (usage >> 16) & 0xFF;
|
||||||
|
t[3] = (usage >> 24) & 0xFF;
|
||||||
|
|
||||||
|
k1_c.checksum.length = sizeof(k1_c_data);
|
||||||
|
k1_c.checksum.data = k1_c_data;
|
||||||
|
|
||||||
|
hmac(NULL, c, t, sizeof(t), 0, key, &k1_c);
|
||||||
|
|
||||||
|
memcpy (k2_c_data, k1_c_data, sizeof(k1_c_data));
|
||||||
|
|
||||||
|
k2_c.checksum.length = sizeof(k2_c_data);
|
||||||
|
k2_c.checksum.data = k2_c_data;
|
||||||
|
|
||||||
|
ke.key = &kb;
|
||||||
|
kb.keyvalue = k1_c.checksum;
|
||||||
|
|
||||||
|
k3_c.checksum.length = sizeof(k3_c_data);
|
||||||
|
k3_c.checksum.data = k3_c_data;
|
||||||
|
|
||||||
|
hmac(NULL, c, cdata, 16, 0, &ke, &k3_c);
|
||||||
|
|
||||||
|
RC4_set_key (&rc4_key, k3_c.checksum.length, k3_c.checksum.data);
|
||||||
|
RC4 (&rc4_key, len - 16, cdata + 16, cdata + 16);
|
||||||
|
|
||||||
|
ke.key = &kb;
|
||||||
|
kb.keyvalue = k2_c.checksum;
|
||||||
|
|
||||||
|
cksum.checksum.length = 16;
|
||||||
|
cksum.checksum.data = cksum_data;
|
||||||
|
|
||||||
|
hmac(NULL, c, cdata + 16, len - 16, 0, &ke, &cksum);
|
||||||
|
|
||||||
|
memset (k1_c_data, 0, sizeof(k1_c_data));
|
||||||
|
memset (k2_c_data, 0, sizeof(k2_c_data));
|
||||||
|
memset (k3_c_data, 0, sizeof(k3_c_data));
|
||||||
|
|
||||||
|
if (memcmp (cksum.checksum.data, data, 16) != 0)
|
||||||
|
return KRB5KRB_AP_ERR_BAD_INTEGRITY;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* convert the usage numbers used in
|
||||||
|
* draft-ietf-cat-kerb-key-derivation-00.txt to the ones in
|
||||||
|
* draft-brezak-win2k-krb-rc4-hmac-03.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
usage2arcfour (int usage)
|
||||||
|
{
|
||||||
|
switch (usage) {
|
||||||
|
case KRB5_KU_PA_ENC_TIMESTAMP :
|
||||||
|
return 1;
|
||||||
|
case KRB5_KU_TICKET :
|
||||||
|
return 8;
|
||||||
|
case KRB5_KU_AS_REP_ENC_PART :
|
||||||
|
return 8;
|
||||||
|
case KRB5_KU_TGS_REQ_AUTH_DAT_SESSION :
|
||||||
|
case KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY :
|
||||||
|
case KRB5_KU_TGS_REQ_AUTH_CKSUM :
|
||||||
|
case KRB5_KU_TGS_REQ_AUTH :
|
||||||
|
return 7;
|
||||||
|
case KRB5_KU_TGS_REP_ENC_PART_SESSION :
|
||||||
|
case KRB5_KU_TGS_REP_ENC_PART_SUB_KEY :
|
||||||
|
return 8;
|
||||||
|
case KRB5_KU_AP_REQ_AUTH_CKSUM :
|
||||||
|
case KRB5_KU_AP_REQ_AUTH :
|
||||||
|
case KRB5_KU_AP_REQ_ENC_PART :
|
||||||
|
return 11;
|
||||||
|
case KRB5_KU_KRB_PRIV :
|
||||||
|
case KRB5_KU_KRB_CRED :
|
||||||
|
case KRB5_KU_KRB_SAFE_CKSUM :
|
||||||
|
case KRB5_KU_OTHER_ENCRYPTED :
|
||||||
|
case KRB5_KU_OTHER_CKSUM :
|
||||||
|
case KRB5_KU_KRB_ERROR :
|
||||||
|
case KRB5_KU_AD_KDC_ISSUED :
|
||||||
|
case KRB5_KU_MANDATORY_TICKET_EXTENSION :
|
||||||
|
case KRB5_KU_AUTH_DATA_TICKET_EXTENSION :
|
||||||
|
case KRB5_KU_USAGE_SEAL :
|
||||||
|
case KRB5_KU_USAGE_SIGN :
|
||||||
|
case KRB5_KU_USAGE_MIC :
|
||||||
|
default :
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static krb5_error_code
|
||||||
|
ARCFOUR_encrypt(struct key_data *key,
|
||||||
|
void *data,
|
||||||
|
size_t len,
|
||||||
|
krb5_boolean encrypt,
|
||||||
|
int usage)
|
||||||
|
{
|
||||||
|
usage = usage2arcfour (usage);
|
||||||
|
|
||||||
|
if (encrypt)
|
||||||
|
return ARCFOUR_subencrypt (key, data, len, usage);
|
||||||
|
else
|
||||||
|
return ARCFOUR_subdecrypt (key, data, len, usage);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* these should currently be in reverse preference order.
|
||||||
|
* (only relevant for !F_PSEUDO) */
|
||||||
|
|
||||||
static struct encryption_type etypes[] = {
|
static struct encryption_type etypes[] = {
|
||||||
{
|
{
|
||||||
ETYPE_NULL,
|
ETYPE_NULL,
|
||||||
@@ -1523,6 +1830,17 @@ static struct encryption_type etypes[] = {
|
|||||||
0,
|
0,
|
||||||
DES_CBC_encrypt_null_ivec,
|
DES_CBC_encrypt_null_ivec,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
ETYPE_ARCFOUR_HMAC_MD5,
|
||||||
|
"arcfour-hmac-md5",
|
||||||
|
1,
|
||||||
|
8,
|
||||||
|
&keytype_arcfour,
|
||||||
|
&checksum_hmac_md5_enc,
|
||||||
|
&checksum_hmac_md5_enc,
|
||||||
|
F_SPECIAL,
|
||||||
|
ARCFOUR_encrypt
|
||||||
|
},
|
||||||
{
|
{
|
||||||
ETYPE_DES3_CBC_MD5,
|
ETYPE_DES3_CBC_MD5,
|
||||||
"des3-cbc-md5",
|
"des3-cbc-md5",
|
||||||
@@ -1755,6 +2073,12 @@ derived_crypto(krb5_context context,
|
|||||||
return (crypto->et->flags & F_DERIVED) != 0;
|
return (crypto->et->flags & F_DERIVED) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static krb5_boolean
|
||||||
|
special_crypto(krb5_context context,
|
||||||
|
krb5_crypto crypto)
|
||||||
|
{
|
||||||
|
return (crypto->et->flags & F_SPECIAL) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
#define CHECKSUMSIZE(C) ((C)->checksumsize)
|
#define CHECKSUMSIZE(C) ((C)->checksumsize)
|
||||||
#define CHECKSUMTYPE(C) ((C)->type)
|
#define CHECKSUMTYPE(C) ((C)->type)
|
||||||
@@ -1817,7 +2141,7 @@ encrypt_internal_derived(krb5_context context,
|
|||||||
#ifdef CRYPTO_DEBUG
|
#ifdef CRYPTO_DEBUG
|
||||||
krb5_crypto_debug(context, 1, block_sz, dkey->key);
|
krb5_crypto_debug(context, 1, block_sz, dkey->key);
|
||||||
#endif
|
#endif
|
||||||
(*et->encrypt)(dkey, p, block_sz, 1);
|
(*et->encrypt)(dkey, p, block_sz, 1, usage);
|
||||||
result->data = p;
|
result->data = p;
|
||||||
result->length = block_sz + checksum_sz;
|
result->length = block_sz + checksum_sz;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1879,12 +2203,40 @@ encrypt_internal(krb5_context context,
|
|||||||
#ifdef CRYPTO_DEBUG
|
#ifdef CRYPTO_DEBUG
|
||||||
krb5_crypto_debug(context, 1, block_sz, crypto->key.key);
|
krb5_crypto_debug(context, 1, block_sz, crypto->key.key);
|
||||||
#endif
|
#endif
|
||||||
(*et->encrypt)(&crypto->key, p, block_sz, 1);
|
(*et->encrypt)(&crypto->key, p, block_sz, 1, 0);
|
||||||
result->data = p;
|
result->data = p;
|
||||||
result->length = block_sz;
|
result->length = block_sz;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static krb5_error_code
|
||||||
|
encrypt_internal_special(krb5_context context,
|
||||||
|
krb5_crypto crypto,
|
||||||
|
int usage,
|
||||||
|
void *data,
|
||||||
|
size_t len,
|
||||||
|
krb5_data *result)
|
||||||
|
{
|
||||||
|
struct encryption_type *et = crypto->et;
|
||||||
|
size_t cksum_sz = CHECKSUMSIZE(et->cksumtype);
|
||||||
|
size_t sz = len + cksum_sz + et->confoundersize;
|
||||||
|
char *tmp, *p;
|
||||||
|
|
||||||
|
tmp = malloc (sz);
|
||||||
|
if (tmp == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
p = tmp;
|
||||||
|
memset (p, 0, cksum_sz);
|
||||||
|
p += cksum_sz;
|
||||||
|
krb5_generate_random_block(p, et->confoundersize);
|
||||||
|
p += et->confoundersize;
|
||||||
|
memcpy (p, data, len);
|
||||||
|
(*et->encrypt)(&crypto->key, tmp, sz, TRUE, usage);
|
||||||
|
result->data = tmp;
|
||||||
|
result->length = sz;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
decrypt_internal_derived(krb5_context context,
|
decrypt_internal_derived(krb5_context context,
|
||||||
krb5_crypto crypto,
|
krb5_crypto crypto,
|
||||||
@@ -1922,7 +2274,7 @@ decrypt_internal_derived(krb5_context context,
|
|||||||
#ifdef CRYPTO_DEBUG
|
#ifdef CRYPTO_DEBUG
|
||||||
krb5_crypto_debug(context, 0, len, dkey->key);
|
krb5_crypto_debug(context, 0, len, dkey->key);
|
||||||
#endif
|
#endif
|
||||||
(*et->encrypt)(dkey, p, len, 0);
|
(*et->encrypt)(dkey, p, len, 0, usage);
|
||||||
|
|
||||||
cksum.checksum.data = p + len;
|
cksum.checksum.data = p + len;
|
||||||
cksum.checksum.length = checksum_sz;
|
cksum.checksum.length = checksum_sz;
|
||||||
@@ -1976,7 +2328,7 @@ decrypt_internal(krb5_context context,
|
|||||||
#ifdef CRYPTO_DEBUG
|
#ifdef CRYPTO_DEBUG
|
||||||
krb5_crypto_debug(context, 0, len, crypto->key.key);
|
krb5_crypto_debug(context, 0, len, crypto->key.key);
|
||||||
#endif
|
#endif
|
||||||
(*et->encrypt)(&crypto->key, p, len, 0);
|
(*et->encrypt)(&crypto->key, p, len, 0, 0);
|
||||||
ret = krb5_data_copy(&cksum.checksum, p + et->confoundersize, checksum_sz);
|
ret = krb5_data_copy(&cksum.checksum, p + et->confoundersize, checksum_sz);
|
||||||
if(ret) {
|
if(ret) {
|
||||||
free(p);
|
free(p);
|
||||||
@@ -2001,6 +2353,34 @@ decrypt_internal(krb5_context context,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static krb5_error_code
|
||||||
|
decrypt_internal_special(krb5_context context,
|
||||||
|
krb5_crypto crypto,
|
||||||
|
int usage,
|
||||||
|
void *data,
|
||||||
|
size_t len,
|
||||||
|
krb5_data *result)
|
||||||
|
{
|
||||||
|
struct encryption_type *et = crypto->et;
|
||||||
|
size_t cksum_sz = CHECKSUMSIZE(et->cksumtype);
|
||||||
|
size_t sz = len - cksum_sz - et->confoundersize;
|
||||||
|
char *cdata = (char *)data;
|
||||||
|
char *tmp;
|
||||||
|
|
||||||
|
tmp = malloc (sz);
|
||||||
|
if (tmp == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
|
||||||
|
(*et->encrypt)(&crypto->key, data, len, FALSE, usage);
|
||||||
|
|
||||||
|
memcpy (tmp, cdata + cksum_sz + et->confoundersize, sz);
|
||||||
|
|
||||||
|
result->data = tmp;
|
||||||
|
result->length = sz;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
krb5_error_code
|
krb5_error_code
|
||||||
krb5_encrypt(krb5_context context,
|
krb5_encrypt(krb5_context context,
|
||||||
krb5_crypto crypto,
|
krb5_crypto crypto,
|
||||||
@@ -2012,6 +2392,9 @@ krb5_encrypt(krb5_context context,
|
|||||||
if(derived_crypto(context, crypto))
|
if(derived_crypto(context, crypto))
|
||||||
return encrypt_internal_derived(context, crypto, usage,
|
return encrypt_internal_derived(context, crypto, usage,
|
||||||
data, len, result);
|
data, len, result);
|
||||||
|
else if (special_crypto(context, crypto))
|
||||||
|
return encrypt_internal_special (context, crypto, usage,
|
||||||
|
data, len, result);
|
||||||
else
|
else
|
||||||
return encrypt_internal(context, crypto, data, len, result);
|
return encrypt_internal(context, crypto, data, len, result);
|
||||||
}
|
}
|
||||||
@@ -2045,6 +2428,9 @@ krb5_decrypt(krb5_context context,
|
|||||||
if(derived_crypto(context, crypto))
|
if(derived_crypto(context, crypto))
|
||||||
return decrypt_internal_derived(context, crypto, usage,
|
return decrypt_internal_derived(context, crypto, usage,
|
||||||
data, len, result);
|
data, len, result);
|
||||||
|
else if (special_crypto (context, crypto))
|
||||||
|
return decrypt_internal_special(context, crypto, usage,
|
||||||
|
data, len, result);
|
||||||
else
|
else
|
||||||
return decrypt_internal(context, crypto, data, len, result);
|
return decrypt_internal(context, crypto, data, len, result);
|
||||||
}
|
}
|
||||||
@@ -2152,7 +2538,7 @@ derive_key(krb5_context context,
|
|||||||
memcpy(k + i * et->blocksize,
|
memcpy(k + i * et->blocksize,
|
||||||
k + (i - 1) * et->blocksize,
|
k + (i - 1) * et->blocksize,
|
||||||
et->blocksize);
|
et->blocksize);
|
||||||
(*et->encrypt)(key, k + i * et->blocksize, et->blocksize, 1);
|
(*et->encrypt)(key, k + i * et->blocksize, et->blocksize, 1, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* this case is probably broken, but won't be run anyway */
|
/* this case is probably broken, but won't be run anyway */
|
||||||
@@ -2162,7 +2548,7 @@ derive_key(krb5_context context,
|
|||||||
if(len != 0 && c == NULL)
|
if(len != 0 && c == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
memcpy(c, constant, len);
|
memcpy(c, constant, len);
|
||||||
(*et->encrypt)(key, c, len, 1);
|
(*et->encrypt)(key, c, len, 1, 0);
|
||||||
k = malloc(res_len);
|
k = malloc(res_len);
|
||||||
if(res_len != 0 && k == NULL)
|
if(res_len != 0 && k == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
Reference in New Issue
Block a user