From 757f7b94301743c0ee0aa271c8331c8cf3fe3a1c Mon Sep 17 00:00:00 2001 From: Assar Westerlund Date: Sun, 13 Jul 1997 07:25:56 +0000 Subject: [PATCH] implement rsa-md4-des and rsa-md5-des git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@2252 ec53bebd-3082-4978-b11e-865c3cabbd6b --- lib/krb5/checksum.c | 148 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 131 insertions(+), 17 deletions(-) diff --git a/lib/krb5/checksum.c b/lib/krb5/checksum.c index 7c93470af..06f23daba 100644 --- a/lib/krb5/checksum.c +++ b/lib/krb5/checksum.c @@ -5,16 +5,18 @@ RCSID("$Id$"); struct checksum_type { int type; 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 -NULL_checksum(void *p, size_t len, void *result) +NULL_checksum(void *p, size_t len, const krb5_keyblock *k, void *result) { } 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; md4_init(&m); @@ -23,7 +25,7 @@ MD4_checksum(void *p, size_t len, void *result) } 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; md5_init(&m); @@ -32,7 +34,7 @@ MD5_checksum(void *p, size_t len, void *result) } 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; sha_init(&m); @@ -41,7 +43,7 @@ SHA1_checksum(void *p, size_t len, void *result) } 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; unsigned char *r = result; @@ -53,11 +55,113 @@ CRC_checksum(void *p, size_t len, void *result) 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[] = { - { CKSUMTYPE_NONE, 0, NULL_checksum}, - { CKSUMTYPE_CRC32, 4, CRC_checksum}, - { CKSUMTYPE_RSA_MD4, 16, MD4_checksum}, - { CKSUMTYPE_RSA_MD5, 16, MD5_checksum} + { CKSUMTYPE_NONE, 0, KEYTYPE_NULL, NULL_checksum, NULL}, + { CKSUMTYPE_CRC32, 4, KEYTYPE_NULL, CRC_checksum, NULL}, + { CKSUMTYPE_RSA_MD4, 16, KEYTYPE_NULL, MD4_checksum, NULL}, + { 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]); @@ -90,6 +194,7 @@ krb5_create_checksum (krb5_context context, krb5_cksumtype type, void *ptr, size_t len, + const krb5_keyblock *keyblock, Checksum *result) { struct checksum_type *c; @@ -97,13 +202,15 @@ krb5_create_checksum (krb5_context context, c = find_checksum_type (type); if (c == NULL) return KRB5_PROG_SUMTYPE_NOSUPP; + if (c->keytype != KEYTYPE_NULL && c->keytype != keyblock->keytype) + return KRB5_PROG_KEYTYPE_NOSUPP; result->cksumtype = type; result->checksum.length = c->checksumsize; result->checksum.data = malloc(result->checksum.length); if(result->checksum.data == NULL) return ENOMEM; - (*c->checksum)(ptr, len, result->checksum.data); + (*c->checksum)(ptr, len, keyblock, result->checksum.data); return 0; } @@ -111,6 +218,7 @@ krb5_error_code krb5_verify_checksum (krb5_context context, void *ptr, size_t len, + const krb5_keyblock *keyblock, Checksum *cksum) { void *tmp; @@ -120,14 +228,20 @@ krb5_verify_checksum (krb5_context context, c = find_checksum_type (cksum->cksumtype); if (c == NULL) 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) return KRB5KRB_AP_ERR_MODIFIED; - tmp = malloc (c->checksumsize); - if (tmp == NULL) - return ENOMEM; - (*c->checksum)(ptr, len, tmp); - ret = memcmp (cksum->checksum.data, tmp, c->checksumsize); - free (tmp); + if (c->verify) { + ret = (*c->verify)(ptr, len, keyblock, cksum->checksum.data); + } else { + tmp = malloc (c->checksumsize); + if (tmp == NULL) + return ENOMEM; + (*c->checksum)(ptr, len, keyblock, tmp); + ret = memcmp (cksum->checksum.data, tmp, c->checksumsize); + free (tmp); + } if (ret == 0) return 0; else