implement rsa-md4-des and rsa-md5-des
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@2252 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
		@@ -5,16 +5,18 @@ RCSID("$Id$");
 | 
				
			|||||||
struct checksum_type {
 | 
					struct checksum_type {
 | 
				
			||||||
    int type;
 | 
					    int type;
 | 
				
			||||||
    size_t checksumsize;
 | 
					    size_t checksumsize;
 | 
				
			||||||
    void (*checksum)(void *, size_t, void *);
 | 
					    krb5_keytype keytype;
 | 
				
			||||||
 | 
					    void (*checksum)(void *, size_t, const krb5_keyblock *, void *);
 | 
				
			||||||
 | 
					    int (*verify)(void *, size_t, const krb5_keyblock *, void *);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
NULL_checksum(void *p, size_t len, void *result)
 | 
					NULL_checksum(void *p, size_t len, const krb5_keyblock *k, void *result)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
MD4_checksum(void *p, size_t len, void *result)
 | 
					MD4_checksum(void *p, size_t len, const krb5_keyblock *k, void *result)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    struct md4 m;
 | 
					    struct md4 m;
 | 
				
			||||||
    md4_init(&m);
 | 
					    md4_init(&m);
 | 
				
			||||||
@@ -23,7 +25,7 @@ MD4_checksum(void *p, size_t len, void *result)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
MD5_checksum(void *p, size_t len, void *result)
 | 
					MD5_checksum(void *p, size_t len, const krb5_keyblock *k, void *result)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    struct md5 m;
 | 
					    struct md5 m;
 | 
				
			||||||
    md5_init(&m);
 | 
					    md5_init(&m);
 | 
				
			||||||
@@ -32,7 +34,7 @@ MD5_checksum(void *p, size_t len, void *result)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
SHA1_checksum(void *p, size_t len, void *result)
 | 
					SHA1_checksum(void *p, size_t len, const krb5_keyblock *k, void *result)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    struct sha m;
 | 
					    struct sha m;
 | 
				
			||||||
    sha_init(&m);
 | 
					    sha_init(&m);
 | 
				
			||||||
@@ -41,7 +43,7 @@ SHA1_checksum(void *p, size_t len, void *result)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
CRC_checksum(void *p, size_t len, void *result)
 | 
					CRC_checksum(void *p, size_t len, const krb5_keyblock *k, void *result)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    u_int32_t crc;
 | 
					    u_int32_t crc;
 | 
				
			||||||
    unsigned char *r = result;
 | 
					    unsigned char *r = result;
 | 
				
			||||||
@@ -53,11 +55,113 @@ CRC_checksum(void *p, size_t len, void *result)
 | 
				
			|||||||
    r[3] = (crc >> 24) & 0xff;
 | 
					    r[3] = (crc >> 24) & 0xff;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					MD4_DES_checksum (void *p, size_t len, const krb5_keyblock *keyblock,
 | 
				
			||||||
 | 
							  void *result)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    struct md4 md4;
 | 
				
			||||||
 | 
					    des_cblock ivec;
 | 
				
			||||||
 | 
					    des_cblock key;
 | 
				
			||||||
 | 
					    des_key_schedule schedule;
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    u_char *r = result;
 | 
				
			||||||
 | 
					    u_char *orig_key = (u_char *)keyblock->keyvalue.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    md4_init(&md4);
 | 
				
			||||||
 | 
					    krb5_generate_random_block(r, 8);
 | 
				
			||||||
 | 
					    md4_update(&md4, r, 8);
 | 
				
			||||||
 | 
					    md4_update(&md4, p, len);
 | 
				
			||||||
 | 
					    md4_finito(&md4, r + 8);
 | 
				
			||||||
 | 
					    for (i = 0; i < 8; ++i)
 | 
				
			||||||
 | 
						key[i] = orig_key[i] ^ 0xF0;
 | 
				
			||||||
 | 
					    des_set_key(&key, schedule);
 | 
				
			||||||
 | 
					    memset (&ivec, 0, sizeof(ivec));
 | 
				
			||||||
 | 
					    des_cbc_encrypt(result, result, 24, schedule, &ivec, DES_ENCRYPT);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					MD4_DES_verify (void *p, size_t len, const krb5_keyblock *keyblock,
 | 
				
			||||||
 | 
							void *other)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    des_cblock ivec;
 | 
				
			||||||
 | 
					    des_cblock key;
 | 
				
			||||||
 | 
					    des_key_schedule schedule;
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    u_char res[16];
 | 
				
			||||||
 | 
					    u_char *orig_key = (u_char *)keyblock->keyvalue.data;
 | 
				
			||||||
 | 
					    struct md4 md4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < 8; ++i)
 | 
				
			||||||
 | 
						key[i] = orig_key[i] ^ 0xF0;
 | 
				
			||||||
 | 
					    des_set_key(&key, schedule);
 | 
				
			||||||
 | 
					    memset (&ivec, 0, sizeof(ivec));
 | 
				
			||||||
 | 
					    des_cbc_encrypt(other, other, 24, schedule, &ivec, DES_DECRYPT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    md4_init(&md4);
 | 
				
			||||||
 | 
					    md4_update(&md4, other, 8);
 | 
				
			||||||
 | 
					    md4_update(&md4, p, len);
 | 
				
			||||||
 | 
					    md4_finito(&md4, res);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return memcmp (res, other + 8, 16);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					MD5_DES_checksum (void *p, size_t len, const krb5_keyblock *keyblock,
 | 
				
			||||||
 | 
							  void *result)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    struct md5 md5;
 | 
				
			||||||
 | 
					    des_cblock ivec;
 | 
				
			||||||
 | 
					    des_cblock key;
 | 
				
			||||||
 | 
					    des_key_schedule schedule;
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    u_char *r = result;
 | 
				
			||||||
 | 
					    u_char *orig_key = (u_char *)keyblock->keyvalue.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    md5_init(&md5);
 | 
				
			||||||
 | 
					    krb5_generate_random_block(r, 8);
 | 
				
			||||||
 | 
					    md5_update(&md5, r, 8);
 | 
				
			||||||
 | 
					    md5_update(&md5, p, len);
 | 
				
			||||||
 | 
					    md5_finito(&md5, r + 8);
 | 
				
			||||||
 | 
					    for (i = 0; i < 8; ++i)
 | 
				
			||||||
 | 
						key[i] = orig_key[i] ^ 0xF0;
 | 
				
			||||||
 | 
					    des_set_key(&key, schedule);
 | 
				
			||||||
 | 
					    memset (&ivec, 0, sizeof(ivec));
 | 
				
			||||||
 | 
					    des_cbc_encrypt(result, result, 24, schedule, &ivec, DES_ENCRYPT);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					MD5_DES_verify (void *p, size_t len, const krb5_keyblock *keyblock,
 | 
				
			||||||
 | 
							void *other)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    des_cblock ivec;
 | 
				
			||||||
 | 
					    des_cblock key;
 | 
				
			||||||
 | 
					    des_key_schedule schedule;
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    u_char res[16];
 | 
				
			||||||
 | 
					    u_char *orig_key = (u_char *)keyblock->keyvalue.data;
 | 
				
			||||||
 | 
					    struct md5 md5;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < 8; ++i)
 | 
				
			||||||
 | 
						key[i] = orig_key[i] ^ 0xF0;
 | 
				
			||||||
 | 
					    des_set_key(&key, schedule);
 | 
				
			||||||
 | 
					    memset (&ivec, 0, sizeof(ivec));
 | 
				
			||||||
 | 
					    des_cbc_encrypt(other, other, 24, schedule, &ivec, DES_DECRYPT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    md5_init(&md5);
 | 
				
			||||||
 | 
					    md5_update(&md5, other, 8);
 | 
				
			||||||
 | 
					    md5_update(&md5, p, len);
 | 
				
			||||||
 | 
					    md5_finito(&md5, res);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return memcmp (res, other + 8, 16);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct checksum_type cm[] = {
 | 
					static struct checksum_type cm[] = {
 | 
				
			||||||
  { CKSUMTYPE_NONE,		 0,	NULL_checksum},
 | 
					  { CKSUMTYPE_NONE,		 0,	KEYTYPE_NULL, NULL_checksum,    NULL},
 | 
				
			||||||
  { CKSUMTYPE_CRC32,		 4,	CRC_checksum},
 | 
					  { CKSUMTYPE_CRC32,		 4,	KEYTYPE_NULL, CRC_checksum,     NULL},
 | 
				
			||||||
  { CKSUMTYPE_RSA_MD4,		16,	MD4_checksum},
 | 
					  { CKSUMTYPE_RSA_MD4,		16,	KEYTYPE_NULL, MD4_checksum,     NULL},
 | 
				
			||||||
  { CKSUMTYPE_RSA_MD5,		16,	MD5_checksum}
 | 
					  { CKSUMTYPE_RSA_MD5,		16,	KEYTYPE_NULL, MD5_checksum,     NULL},
 | 
				
			||||||
 | 
					  { CKSUMTYPE_RSA_MD4_DES,	24,	KEYTYPE_DES,  MD4_DES_checksum, MD4_DES_verify},
 | 
				
			||||||
 | 
					  { CKSUMTYPE_RSA_MD5_DES,	24,	KEYTYPE_DES,  MD5_DES_checksum, MD5_DES_verify}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int num_ctypes = sizeof(cm) / sizeof(cm[0]);
 | 
					static int num_ctypes = sizeof(cm) / sizeof(cm[0]);
 | 
				
			||||||
@@ -90,6 +194,7 @@ krb5_create_checksum (krb5_context context,
 | 
				
			|||||||
		      krb5_cksumtype type,
 | 
							      krb5_cksumtype type,
 | 
				
			||||||
		      void *ptr,
 | 
							      void *ptr,
 | 
				
			||||||
		      size_t len,
 | 
							      size_t len,
 | 
				
			||||||
 | 
							      const krb5_keyblock *keyblock,
 | 
				
			||||||
		      Checksum *result)
 | 
							      Checksum *result)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    struct checksum_type *c;
 | 
					    struct checksum_type *c;
 | 
				
			||||||
@@ -97,13 +202,15 @@ krb5_create_checksum (krb5_context context,
 | 
				
			|||||||
    c = find_checksum_type (type);
 | 
					    c = find_checksum_type (type);
 | 
				
			||||||
    if (c == NULL)
 | 
					    if (c == NULL)
 | 
				
			||||||
	return KRB5_PROG_SUMTYPE_NOSUPP;
 | 
						return KRB5_PROG_SUMTYPE_NOSUPP;
 | 
				
			||||||
 | 
					    if (c->keytype != KEYTYPE_NULL && c->keytype != keyblock->keytype)
 | 
				
			||||||
 | 
						return KRB5_PROG_KEYTYPE_NOSUPP;
 | 
				
			||||||
    result->cksumtype = type;
 | 
					    result->cksumtype = type;
 | 
				
			||||||
    result->checksum.length = c->checksumsize;
 | 
					    result->checksum.length = c->checksumsize;
 | 
				
			||||||
    result->checksum.data   = malloc(result->checksum.length);
 | 
					    result->checksum.data   = malloc(result->checksum.length);
 | 
				
			||||||
    if(result->checksum.data == NULL)
 | 
					    if(result->checksum.data == NULL)
 | 
				
			||||||
	return ENOMEM;
 | 
						return ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    (*c->checksum)(ptr, len, result->checksum.data);
 | 
					    (*c->checksum)(ptr, len, keyblock, result->checksum.data);
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -111,6 +218,7 @@ krb5_error_code
 | 
				
			|||||||
krb5_verify_checksum (krb5_context context,
 | 
					krb5_verify_checksum (krb5_context context,
 | 
				
			||||||
		      void *ptr,
 | 
							      void *ptr,
 | 
				
			||||||
		      size_t len,
 | 
							      size_t len,
 | 
				
			||||||
 | 
							      const krb5_keyblock *keyblock,
 | 
				
			||||||
		      Checksum *cksum)
 | 
							      Checksum *cksum)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    void *tmp;
 | 
					    void *tmp;
 | 
				
			||||||
@@ -120,14 +228,20 @@ krb5_verify_checksum (krb5_context context,
 | 
				
			|||||||
    c = find_checksum_type (cksum->cksumtype);
 | 
					    c = find_checksum_type (cksum->cksumtype);
 | 
				
			||||||
    if (c == NULL)
 | 
					    if (c == NULL)
 | 
				
			||||||
	return KRB5_PROG_SUMTYPE_NOSUPP;
 | 
						return KRB5_PROG_SUMTYPE_NOSUPP;
 | 
				
			||||||
 | 
					    if (c->keytype != KEYTYPE_NULL && c->keytype != keyblock->keytype)
 | 
				
			||||||
 | 
						return KRB5_PROG_KEYTYPE_NOSUPP;
 | 
				
			||||||
    if (cksum->checksum.length != c->checksumsize)
 | 
					    if (cksum->checksum.length != c->checksumsize)
 | 
				
			||||||
	return KRB5KRB_AP_ERR_MODIFIED;
 | 
						return KRB5KRB_AP_ERR_MODIFIED;
 | 
				
			||||||
 | 
					    if (c->verify) {
 | 
				
			||||||
 | 
						ret = (*c->verify)(ptr, len, keyblock, cksum->checksum.data);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
	tmp = malloc (c->checksumsize);
 | 
						tmp = malloc (c->checksumsize);
 | 
				
			||||||
	if (tmp == NULL)
 | 
						if (tmp == NULL)
 | 
				
			||||||
	    return ENOMEM;
 | 
						    return ENOMEM;
 | 
				
			||||||
    (*c->checksum)(ptr, len, tmp);
 | 
						(*c->checksum)(ptr, len, keyblock, tmp);
 | 
				
			||||||
	ret = memcmp (cksum->checksum.data, tmp, c->checksumsize);
 | 
						ret = memcmp (cksum->checksum.data, tmp, c->checksumsize);
 | 
				
			||||||
	free (tmp);
 | 
						free (tmp);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if (ret == 0)
 | 
					    if (ret == 0)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user