diff options
46 files changed, 864 insertions, 1299 deletions
diff --git a/src/configure.in b/src/configure.in index bf3077b..6f0ee6d 100644 --- a/src/configure.in +++ b/src/configure.in @@ -1060,7 +1060,7 @@ V5_AC_OUTPUT_MAKEFILE(. lib/crypto lib/crypto/krb lib/crypto/krb/crc32 lib/crypto/$CRYPTO_IMPL/des lib/crypto/krb/dk lib/crypto/$CRYPTO_IMPL/enc_provider - lib/crypto/$CRYPTO_IMPL/hash_provider lib/crypto/krb/keyhash_provider + lib/crypto/$CRYPTO_IMPL/hash_provider lib/crypto/krb/checksum lib/crypto/krb/prf lib/crypto/krb/rand2key lib/crypto/$CRYPTO_IMPL lib/crypto/$CRYPTO_IMPL/md4 lib/crypto/$CRYPTO_IMPL/md5 lib/crypto/krb/old lib/crypto/krb/raw lib/crypto/$CRYPTO_IMPL/sha1 diff --git a/src/include/k5-int.h b/src/include/k5-int.h index 2047bb9..e0637e6 100644 --- a/src/include/k5-int.h +++ b/src/include/k5-int.h @@ -653,6 +653,11 @@ struct krb5_enc_provider { krb5_error_code (*decrypt)(krb5_key key, const krb5_data *cipher_state, krb5_crypto_iov *data, size_t num_data); + /* May be NULL if the cipher is not used for a cbc-mac checksum. */ + krb5_error_code (*cbc_mac)(krb5_key key, const krb5_crypto_iov *data, + size_t num_data, const krb5_data *ivec, + krb5_data *output); + krb5_error_code (*make_key)(const krb5_data *randombits, krb5_keyblock *key); @@ -671,26 +676,6 @@ struct krb5_hash_provider { krb5_data *output); }; -struct krb5_keyhash_provider { - size_t hashsize; - - krb5_error_code (*hash)(krb5_key key, krb5_keyusage keyusage, - const krb5_data *input, krb5_data *output); - - krb5_error_code (*verify)(krb5_key key, krb5_keyusage keyusage, - const krb5_data *input, const krb5_data *hash, - krb5_boolean *valid); - - krb5_error_code (*hash_iov)(krb5_key key, krb5_keyusage keyusage, - const krb5_crypto_iov *data, size_t num_data, - krb5_data *output); - - krb5_error_code (*verify_iov)(krb5_key key, krb5_keyusage keyusage, - const krb5_crypto_iov *data, - size_t num_data, const krb5_data *hash, - krb5_boolean *valid); -}; - /* * in here to deal with stuff from lib/crypto */ diff --git a/src/lib/crypto/Makefile.in b/src/lib/crypto/Makefile.in index ce3ea4f..91ea0f3 100644 --- a/src/lib/crypto/Makefile.in +++ b/src/lib/crypto/Makefile.in @@ -19,7 +19,7 @@ LIBFINIFUNC=cryptoint_cleanup_library RELDIR=crypto STOBJLISTS=krb/crc32/OBJS.ST krb/dk/OBJS.ST @CRYPTO_IMPL@/enc_provider/OBJS.ST \ - @CRYPTO_IMPL@/hash_provider/OBJS.ST krb/keyhash_provider/OBJS.ST \ + @CRYPTO_IMPL@/hash_provider/OBJS.ST krb/checksum/OBJS.ST \ krb/prf/OBJS.ST krb/rand2key/OBJS.ST \ krb/old/OBJS.ST krb/raw/OBJS.ST krb/yarrow/OBJS.ST \ @CRYPTO_IMPL@/md4/OBJS.ST @CRYPTO_IMPL@/md5/OBJS.ST @CRYPTO_IMPL@/sha1/OBJS.ST \ @@ -27,7 +27,7 @@ STOBJLISTS=krb/crc32/OBJS.ST krb/dk/OBJS.ST @CRYPTO_IMPL@/enc_provider/OBJS.ST \ krb/OBJS.ST @CRYPTO_IMPL@/OBJS.ST SUBDIROBJLISTS=krb/crc32/OBJS.ST krb/dk/OBJS.ST @CRYPTO_IMPL@/enc_provider/OBJS.ST \ - @CRYPTO_IMPL@/hash_provider/OBJS.ST krb/keyhash_provider/OBJS.ST \ + @CRYPTO_IMPL@/hash_provider/OBJS.ST krb/checksum/OBJS.ST \ krb/prf/OBJS.ST krb/rand2key/OBJS.ST \ krb/old/OBJS.ST krb/raw/OBJS.ST krb/yarrow/OBJS.ST \ @CRYPTO_IMPL@/md4/OBJS.ST @CRYPTO_IMPL@/md5/OBJS.ST @CRYPTO_IMPL@/sha1/OBJS.ST \ diff --git a/src/lib/crypto/builtin/des/des_int.h b/src/lib/crypto/builtin/des/des_int.h index 9dd5994..419459d 100644 --- a/src/lib/crypto/builtin/des/des_int.h +++ b/src/lib/crypto/builtin/des/des_int.h @@ -263,6 +263,11 @@ krb5int_des_cbc_decrypt(krb5_crypto_iov *data, unsigned long num_data, const mit_des_key_schedule schedule, mit_des_cblock ivec); +void +krb5int_des_cbc_mac(const krb5_crypto_iov *data, unsigned long num_data, + const mit_des_key_schedule schedule, mit_des_cblock ivec, + mit_des_cblock out); + /* d3_procky.c */ krb5_error_code mit_des3_process_key(krb5_encrypt_block *eblock, const krb5_keyblock *keyblock); diff --git a/src/lib/crypto/builtin/des/f_aead.c b/src/lib/crypto/builtin/des/f_aead.c index 3f4fbae..bb3982d 100644 --- a/src/lib/crypto/builtin/des/f_aead.c +++ b/src/lib/crypto/builtin/des/f_aead.c @@ -152,6 +152,54 @@ krb5int_des_cbc_decrypt(krb5_crypto_iov *data, unsigned long num_data, } } +void +krb5int_des_cbc_mac(const krb5_crypto_iov *data, unsigned long num_data, + const mit_des_key_schedule schedule, mit_des_cblock ivec, + mit_des_cblock out) +{ + unsigned DES_INT32 left, right; + const unsigned DES_INT32 *kp; + const unsigned char *ip; + struct iov_block_state input_pos; + unsigned char storage[MIT_DES_BLOCK_LENGTH], *block = NULL, *ptr; + + IOV_BLOCK_STATE_INIT(&input_pos); + input_pos.include_sign_only = 1; + + /* Get key pointer here. This won't need to be reinitialized. */ + kp = (const unsigned DES_INT32 *)schedule; + + /* Initialize left and right with the contents of the initial vector. */ + ip = (ivec != NULL) ? ivec : mit_des_zeroblock; + GET_HALF_BLOCK(left, ip); + GET_HALF_BLOCK(right, ip); + + /* Work the length down 8 bytes at a time. */ + for (;;) { + unsigned DES_INT32 temp; + + ptr = iov_next_block(storage, MIT_DES_BLOCK_LENGTH, data, num_data, + &input_pos); + if (ptr == NULL) + break; + block = ptr; + + /* Decompose this block and xor it with the previous ciphertext. */ + GET_HALF_BLOCK(temp, ptr); + left ^= temp; + GET_HALF_BLOCK(temp, ptr); + right ^= temp; + + /* Encrypt what we have. */ + DES_DO_ENCRYPT(left, right, kp); + } + + /* Output the final ciphertext block. */ + ptr = out; + PUT_HALF_BLOCK(left, ptr); + PUT_HALF_BLOCK(right, ptr); +} + #if defined(CONFIG_SMALL) && !defined(CONFIG_SMALL_NO_CRYPTO) void krb5int_des_do_encrypt_2 (unsigned DES_INT32 *left, unsigned DES_INT32 *right, diff --git a/src/lib/crypto/builtin/enc_provider/aes.c b/src/lib/crypto/builtin/enc_provider/aes.c index d482724..0440f7a 100644 --- a/src/lib/crypto/builtin/enc_provider/aes.c +++ b/src/lib/crypto/builtin/enc_provider/aes.c @@ -267,6 +267,7 @@ const struct krb5_enc_provider krb5int_enc_aes128 = { 16, 16, krb5int_aes_encrypt, krb5int_aes_decrypt, + NULL, krb5int_aes_make_key, aes_init_state, krb5int_default_free_state, @@ -277,6 +278,7 @@ const struct krb5_enc_provider krb5int_enc_aes256 = { 32, 32, krb5int_aes_encrypt, krb5int_aes_decrypt, + NULL, krb5int_aes_make_key, aes_init_state, krb5int_default_free_state diff --git a/src/lib/crypto/builtin/enc_provider/des.c b/src/lib/crypto/builtin/enc_provider/des.c index d631727..ed79b06 100644 --- a/src/lib/crypto/builtin/enc_provider/des.c +++ b/src/lib/crypto/builtin/enc_provider/des.c @@ -31,32 +31,24 @@ #include <aead.h> #include <rand2key.h> - static krb5_error_code -k5_des_docrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, - size_t num_data, int enc) +validate_and_schedule(krb5_key key, const krb5_data *ivec, + const krb5_crypto_iov *data, size_t num_data, + mit_des_key_schedule schedule) { - mit_des_key_schedule schedule; - size_t input_length = 0; - unsigned int i; - unsigned char *ivecbytes; - - /* key->keyblock.enctype was checked by the caller */ - - if (key->keyblock.length != 8) - return(KRB5_BAD_KEYSIZE); + size_t i, input_length; - for (i = 0; i < num_data; i++) { + for (i = 0, input_length = 0; i < num_data; i++) { const krb5_crypto_iov *iov = &data[i]; if (ENCRYPT_IOV(iov)) input_length += iov->data.length; } - if ((input_length % 8) != 0) - return(KRB5_BAD_MSIZE); - if (ivec && (ivec->length != 8)) - return(KRB5_BAD_MSIZE); + if (key->keyblock.length != 8) + return KRB5_BAD_KEYSIZE; + if (input_length % 8 != 0 || (ivec != NULL && ivec->length != 8)) + return KRB5_BAD_MSIZE; switch (mit_des_key_sched(key->keyblock.contents, schedule)) { case -1: @@ -64,38 +56,75 @@ k5_des_docrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, case -2: return(KRB5DES_WEAK_KEY); } + return 0; +} + +static krb5_error_code +des_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, + size_t num_data) +{ + mit_des_key_schedule schedule; + krb5_error_code err; - /* this has a return value, but the code always returns zero */ - ivecbytes = ivec ? (unsigned char *) ivec->data : NULL; - if (enc) - krb5int_des_cbc_encrypt(data, num_data, schedule, ivecbytes); - else - krb5int_des_cbc_decrypt(data, num_data, schedule, ivecbytes); + err = validate_and_schedule(key, ivec, data, num_data, schedule); + if (err) + return err; - memset(schedule, 0, sizeof(schedule)); + krb5int_des_cbc_encrypt(data, num_data, schedule, + ivec != NULL ? (unsigned char *) ivec->data : + NULL); - return(0); + zap(schedule, sizeof(schedule)); + return 0; } static krb5_error_code -k5_des_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, - size_t num_data) +des_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, + size_t num_data) { - return k5_des_docrypt(key, ivec, data, num_data, 1); + mit_des_key_schedule schedule; + krb5_error_code err; + + err = validate_and_schedule(key, ivec, data, num_data, schedule); + if (err) + return err; + + krb5int_des_cbc_decrypt(data, num_data, schedule, + ivec != NULL ? (unsigned char *) ivec->data : + NULL); + + zap(schedule, sizeof(schedule)); + return 0; } static krb5_error_code -k5_des_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, - size_t num_data) +des_cbc_mac(krb5_key key, const krb5_crypto_iov *data, size_t num_data, + const krb5_data *ivec, krb5_data *output) { - return k5_des_docrypt(key, ivec, data, num_data, 0); + mit_des_key_schedule schedule; + krb5_error_code err; + + err = validate_and_schedule(key, ivec, data, num_data, schedule); + if (err) + return err; + + if (output->length != 8) + return KRB5_CRYPTO_INTERNAL; + + krb5int_des_cbc_mac(data, num_data, schedule, + ivec != NULL ? (unsigned char *) ivec->data : NULL, + (unsigned char *) output->data); + + zap(schedule, sizeof(schedule)); + return 0; } const struct krb5_enc_provider krb5int_enc_des = { 8, 7, 8, - k5_des_encrypt, - k5_des_decrypt, + des_encrypt, + des_decrypt, + des_cbc_mac, krb5int_des_make_key, krb5int_des_init_state, krb5int_default_free_state diff --git a/src/lib/crypto/builtin/enc_provider/des3.c b/src/lib/crypto/builtin/enc_provider/des3.c index 17c3433..e08cc62 100644 --- a/src/lib/crypto/builtin/enc_provider/des3.c +++ b/src/lib/crypto/builtin/enc_provider/des3.c @@ -110,6 +110,7 @@ const struct krb5_enc_provider krb5int_enc_des3 = { 21, 24, k5_des3_encrypt, k5_des3_decrypt, + NULL, krb5int_des3_make_key, krb5int_des_init_state, krb5int_default_free_state diff --git a/src/lib/crypto/builtin/enc_provider/rc4.c b/src/lib/crypto/builtin/enc_provider/rc4.c index d024e4a..a8e0721 100644 --- a/src/lib/crypto/builtin/enc_provider/rc4.c +++ b/src/lib/crypto/builtin/enc_provider/rc4.c @@ -206,6 +206,7 @@ const struct krb5_enc_provider krb5int_enc_arcfour = { 16, 16, k5_arcfour_docrypt, k5_arcfour_docrypt, + NULL, krb5int_arcfour_make_key, k5_arcfour_init_state, /*xxx not implemented yet*/ krb5int_default_free_state diff --git a/src/lib/crypto/crypto_tests/t_cksum.c b/src/lib/crypto/crypto_tests/t_cksum.c index 16a994f..c4f22bc 100644 --- a/src/lib/crypto/crypto_tests/t_cksum.c +++ b/src/lib/crypto/crypto_tests/t_cksum.c @@ -35,33 +35,27 @@ #define MD5_K5BETA_COMPAT #define MD4_K5BETA_COMPAT -#if MD == 4 -extern struct krb5_keyhash_provider krb5int_keyhash_md4des; -#define khp krb5int_keyhash_md4des +#if MD == 4 +#define CKTYPE CKSUMTYPE_RSA_MD4_DES #endif -#if MD == 5 -extern struct krb5_keyhash_provider krb5int_keyhash_md5des; -#define khp krb5int_keyhash_md5des +#if MD == 5 +#define CKTYPE CKSUMTYPE_RSA_MD5_DES #endif static void -print_checksum(text, number, message, checksum) - char *text; - int number; - char *message; - krb5_data *checksum; +print_checksum(char *text, int number, char *message, krb5_checksum *checksum) { - int i; + unsigned int i; printf("%s MD%d checksum(\"%s\") = ", text, number, message); for (i=0; i<checksum->length; i++) - printf("%02x", (unsigned char) checksum->data[i]); + printf("%02x", (unsigned char) checksum->contents[i]); printf("\n"); } static void -parse_hexstring(const char *s, krb5_data *dat) +parse_hexstring(const char *s, krb5_checksum *cksum) { size_t i, len; unsigned int byte; @@ -69,16 +63,18 @@ parse_hexstring(const char *s, krb5_data *dat) len = strlen(s); cp = malloc(len / 2); - dat->data = (char *)cp; + cksum->contents = cp; if (cp == NULL) { - dat->length = 0; + cksum->length = 0; return; } - dat->length = len / 2; + cksum->length = len / 2; for (i = 0; i + 1 < len; i += 2) { sscanf(&s[i], "%2x", &byte); *cp++ = byte; } + cksum->checksum_type = CKTYPE; + cksum->magic = KV5M_CHECKSUM; } /* @@ -95,11 +91,11 @@ main(argc, argv) { int msgindex; krb5_boolean valid; - size_t length; krb5_keyblock keyblock; krb5_key key; krb5_error_code kret=0; - krb5_data plaintext, newstyle_checksum, knowncksum_dat; + krb5_data plaintext; + krb5_checksum checksum, knowncksum; /* this is a terrible seed, but that's ok for the test. */ @@ -114,27 +110,23 @@ main(argc, argv) krb5_k_create_key(NULL, &keyblock, &key); - length = khp.hashsize; - - newstyle_checksum.length = length; - - if (!(newstyle_checksum.data = (char *) - malloc((unsigned) newstyle_checksum.length))) { - printf("cannot get memory for new style checksum\n"); - return(ENOMEM); - } for (msgindex = 1; msgindex + 1 < argc; msgindex += 2) { plaintext.length = strlen(argv[msgindex]); plaintext.data = argv[msgindex]; - if ((kret = (*(khp.hash))(key, 0, &plaintext, &newstyle_checksum))) { + /* Create a checksum. */ + kret = krb5_k_make_checksum(NULL, CKTYPE, key, 0, &plaintext, + &checksum); + if (kret != 0) { printf("krb5_calculate_checksum choked with %d\n", kret); break; } - print_checksum("correct", MD, argv[msgindex], &newstyle_checksum); + print_checksum("correct", MD, argv[msgindex], &checksum); - if ((kret = (*(khp.verify))(key, 0, &plaintext, &newstyle_checksum, - &valid))) { + /* Verify it. */ + kret = krb5_k_verify_checksum(NULL, key, 0, &plaintext, &checksum, + &valid); + if (kret != 0) { printf("verify on new checksum choked with %d\n", kret); break; } @@ -145,9 +137,11 @@ main(argc, argv) } printf("Verify succeeded for \"%s\"\n", argv[msgindex]); - newstyle_checksum.data[0]++; - if ((kret = (*(khp.verify))(key, 0, &plaintext, &newstyle_checksum, - &valid))) { + /* Corrupt the checksum and see if it still verifies. */ + checksum.contents[0]++; + kret = krb5_k_verify_checksum(NULL, key, 0, &plaintext, &checksum, + &valid); + if (kret != 0) { printf("verify on new checksum choked with %d\n", kret); break; } @@ -157,14 +151,18 @@ main(argc, argv) break; } printf("Verify of bad checksum OK for \"%s\"\n", argv[msgindex]); - parse_hexstring(argv[msgindex+1], &knowncksum_dat); - if (knowncksum_dat.data == NULL) { + free(checksum.contents); + + /* Verify a known-good checksum for this plaintext. */ + parse_hexstring(argv[msgindex+1], &knowncksum); + if (knowncksum.contents == NULL) { printf("parse_hexstring failed\n"); kret = 1; break; } - if ((kret = (*(khp.verify))(key, 0, &plaintext, &knowncksum_dat, - &valid))) { + kret = krb5_k_verify_checksum(NULL, key, 0, &plaintext, &knowncksum, + &valid); + if (kret != 0) { printf("verify on known checksum choked with %d\n", kret); break; } @@ -174,9 +172,8 @@ main(argc, argv) break; } printf("Verify on known checksum succeeded\n"); - kret = 0; + free(knowncksum.contents); } - free(newstyle_checksum.data); if (!kret) printf("%d tests passed successfully for MD%d checksum\n", (argc-1)/2, MD); diff --git a/src/lib/crypto/krb/Makefile.in b/src/lib/crypto/krb/Makefile.in index c59341c..5c08de6 100644 --- a/src/lib/crypto/krb/Makefile.in +++ b/src/lib/crypto/krb/Makefile.in @@ -1,9 +1,9 @@ mydir=lib/crypto/krb BUILDTOP=$(REL)..$(S)..$(S).. -SUBDIRS= arcfour crc32 dk keyhash_provider \ +SUBDIRS= arcfour checksum crc32 dk \ prf rand2key old raw yarrow LOCALINCLUDES = -I$(srcdir) -I$(srcdir)/../@CRYPTO_IMPL@/enc_provider -I$(srcdir)/dk \ - -I$(srcdir)/../@CRYPTO_IMPL@/hash_provider -I$(srcdir)/keyhash_provider \ + -I$(srcdir)/../@CRYPTO_IMPL@/hash_provider \ -I$(srcdir)/prf -I$(srcdir)/rand2key \ -I$(srcdir)/old -I$(srcdir)/raw -I$(srcdir)/yarrow \ -I$(srcdir)/../@CRYPTO_IMPL@/ -I$(srcdir)/../@CRYPTO_IMPL@/des \ @@ -16,8 +16,8 @@ DEFS= ##DOSBUILDTOP = ..\..\.. ##DOSLIBNAME=$(OUTPRE)crypto.lib ##DOSOBJFILE=$(OUTPRE)crypto.lst -##DOSOBJFILELIST=@$(OUTPRE)crypto.lst @$(OUTPRE)des.lst @$(OUTPRE)md4.lst @$(OUTPRE)md5.lst @$(OUTPRE)sha1.lst @$(OUTPRE)arcfour.lst @$(OUTPRE)crc32.lst @$(OUTPRE)dk.lst @$(OUTPRE)old.lst @$(OUTPRE)raw.lst @$(OUTPRE)enc_prov.lst @$(OUTPRE)hash_pro.lst @$(OUTPRE)kh_pro.lst @$(OUTPRE)yarrow.lst @$(OUTPRE)aes.lst -##DOSOBJFILEDEP =$(OUTPRE)crypto.lst $(OUTPRE)des.lst $(OUTPRE)md4.lst $(OUTPRE)md5.lst $(OUTPRE)sha1.lst $(OUTPRE)arcfour.lst $(OUTPRE)crc32.lst $(OUTPRE)dk.lst $(OUTPRE)old.lst $(OUTPRE)raw.lst $(OUTPRE)enc_prov.lst $(OUTPRE)hash_pro.lst $(OUTPRE)kh_pro.lst $(OUTPRE)aes.lst +##DOSOBJFILELIST=@$(OUTPRE)crypto.lst @$(OUTPRE)des.lst @$(OUTPRE)md4.lst @$(OUTPRE)md5.lst @$(OUTPRE)sha1.lst @$(OUTPRE)arcfour.lst @$(OUTPRE)crc32.lst @$(OUTPRE)dk.lst @$(OUTPRE)old.lst @$(OUTPRE)raw.lst @$(OUTPRE)enc_prov.lst @$(OUTPRE)hash_pro.lst @$(OUTPRE)cksum.lst @$(OUTPRE)yarrow.lst @$(OUTPRE)aes.lst +##DOSOBJFILEDEP =$(OUTPRE)crypto.lst $(OUTPRE)des.lst $(OUTPRE)md4.lst $(OUTPRE)md5.lst $(OUTPRE)sha1.lst $(OUTPRE)arcfour.lst $(OUTPRE)crc32.lst $(OUTPRE)dk.lst $(OUTPRE)old.lst $(OUTPRE)raw.lst $(OUTPRE)enc_prov.lst $(OUTPRE)hash_pro.lst $(OUTPRE)cksum.lst $(OUTPRE)aes.lst PROG_LIBPATH=-L$(TOPLIBD) PROG_RPATH=$(KRB5_LIBDIR) @@ -151,14 +151,12 @@ SRCS=\ $(srcdir)/verify_checksum.c \ $(srcdir)/verify_checksum_iov.c -STOBJLISTS=arcfour/OBJS.ST crc32/OBJS.ST dk/OBJS.ST \ - keyhash_provider/OBJS.ST \ - prf/OBJS.ST rand2key/OBJS.ST \ +STOBJLISTS=arcfour/OBJS.ST checksum/OBJS.ST crc32/OBJS.ST \ + dk/OBJS.ST prf/OBJS.ST rand2key/OBJS.ST \ old/OBJS.ST raw/OBJS.ST yarrow/OBJS.ST OBJS.ST -SUBDIROBJLISTS=arcfour/OBJS.ST crc32/OBJS.ST dk/OBJS.ST \ - keyhash_provider/OBJS.ST \ - prf/OBJS.ST rand2key/OBJS.ST \ +SUBDIROBJLISTS=arcfour/OBJS.ST checksum/OBJS.ST crc32/OBJS.ST \ + dk/OBJS.ST prf/OBJS.ST rand2key/OBJS.ST \ old/OBJS.ST raw/OBJS.ST yarrow/OBJS.ST ##DOS##LIBOBJS = $(OBJS) @@ -177,12 +175,12 @@ all-windows:: cd ..\crc32 @echo Making in crypto\crc32 $(MAKE) -$(MFLAGS) + cd ..\checksum + @echo Making in crypto\checksum + $(MAKE) -$(MFLAGS) cd ..\dk @echo Making in crypto\dk $(MAKE) -$(MFLAGS) - cd ..\keyhash_provider - @echo Making in crypto\keyhash_provider - $(MAKE) -$(MFLAGS) cd ..\prf @echo Making in crypto\prf $(MAKE) -$(MFLAGS) @@ -207,12 +205,12 @@ clean-windows:: cd ..\crc32 @echo Making in clean crypto\crc32 $(MAKE) -$(MFLAGS) clean + cd ..\checksum + @echo Making clean in crypto\checksum + $(MAKE) -$(MFLAGS) clean cd ..\dk @echo Making clean in crypto\dk $(MAKE) -$(MFLAGS) clean - cd ..\keyhash_provider - @echo Making clean in crypto\keyhash_provider - $(MAKE) -$(MFLAGS) clean cd ..\prf @echo Making clean in crypto\prf $(MAKE) -$(MFLAGS) clean @@ -237,12 +235,12 @@ check-windows:: cd ..\crc32 @echo Making in check crypto\crc32 $(MAKE) -$(MFLAGS) check + cd ..\checksum + @echo Making check in crypto\checksum + $(MAKE) -$(MFLAGS) check cd ..\dk @echo Making check in crypto\dk $(MAKE) -$(MFLAGS) check - cd ..\keyhash_provider - @echo Making check in crypto\keyhash_provider - $(MAKE) -$(MFLAGS) check cd ..\prf @echo Making check in crypto\prf $(MAKE) -$(MFLAGS) check diff --git a/src/lib/crypto/krb/aead.c b/src/lib/crypto/krb/aead.c index 67835f4..c1f8ccd 100644 --- a/src/lib/crypto/krb/aead.c +++ b/src/lib/crypto/krb/aead.c @@ -53,71 +53,6 @@ krb5int_c_locate_iov(krb5_crypto_iov *data, size_t num_data, return iov; } -krb5_error_code -krb5int_c_make_checksum_iov(const struct krb5_cksumtypes *cksum_type, - krb5_key key, - krb5_keyusage usage, - const krb5_crypto_iov *data, - size_t num_data, - krb5_data *cksum_data) -{ - const struct krb5_keytypes *e1, *e2; - krb5_error_code ret; - - if (cksum_type->keyhash != NULL) { - /* Check if key is compatible. */ - - if (cksum_type->keyed_etype) { - e1 = find_enctype(cksum_type->keyed_etype); - e2 = find_enctype(key->keyblock.enctype); - if (e1 == NULL || e2 == NULL || e1->enc != e2->enc) { - ret = KRB5_BAD_ENCTYPE; - goto cleanup; - } - } - - if (cksum_type->keyhash->hash_iov == NULL) - return KRB5_BAD_ENCTYPE; - - ret = cksum_type->keyhash->hash_iov(key, usage, data, num_data, - cksum_data); - } else if (cksum_type->flags & KRB5_CKSUMFLAG_DERIVE) { - ret = krb5int_dk_make_checksum(cksum_type->hash, key, usage, data, - num_data, cksum_data); - } else { - ret = cksum_type->hash->hash(data, num_data, cksum_data); - } - - if (ret == 0) { - if (cksum_type->trunc_size) { - cksum_data->length = cksum_type->trunc_size; - } - } - -cleanup: - if (ret != 0) { - memset(cksum_data->data, 0, cksum_data->length); - } - - return ret; -} - -const struct krb5_cksumtypes * -krb5int_c_find_checksum_type(krb5_cksumtype cksumtype) -{ - size_t i; - - for (i = 0; i < krb5int_cksumtypes_length; i++) { - if (krb5int_cksumtypes_list[i].ctype == cksumtype) - break; - } - - if (i == krb5int_cksumtypes_length) - return NULL; - - return &krb5int_cksumtypes_list[i]; -} - #ifdef DEBUG_IOV static void dump_block(const char *tag, diff --git a/src/lib/crypto/krb/aead.h b/src/lib/crypto/krb/aead.h index f5a3219..df54a05 100644 --- a/src/lib/crypto/krb/aead.h +++ b/src/lib/crypto/krb/aead.h @@ -36,17 +36,6 @@ krb5int_c_locate_iov(krb5_crypto_iov *data, size_t num_data, krb5_cryptotype type); -krb5_error_code -krb5int_c_make_checksum_iov(const struct krb5_cksumtypes *cksum, - krb5_key key, - krb5_keyusage usage, - const krb5_crypto_iov *data, - size_t num_data, - krb5_data *cksum_data); - -const struct krb5_cksumtypes * -krb5int_c_find_checksum_type(krb5_cksumtype cksumtype); - #define ENCRYPT_CONF_IOV(_iov) ((_iov)->flags == KRB5_CRYPTO_TYPE_HEADER) #define ENCRYPT_DATA_IOV(_iov) ((_iov)->flags == KRB5_CRYPTO_TYPE_DATA || \ diff --git a/src/lib/crypto/krb/checksum/Makefile.in b/src/lib/crypto/krb/checksum/Makefile.in new file mode 100644 index 0000000..61b41f2 --- /dev/null +++ b/src/lib/crypto/krb/checksum/Makefile.in @@ -0,0 +1,32 @@ +mydir=lib/crypto/krb/checksum +BUILDTOP=$(REL)..$(S)..$(S)..$(S).. +LOCALINCLUDES = -I$(srcdir)/.. -I$(srcdir)/../arcfour +DEFS= + +##DOS##BUILDTOP = ..\..\..\.. +##DOS##PREFIXDIR=checksum +##DOS##OBJFILE=..\$(OUTPRE)cksum.lst + +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +STLIBOBJS= cbc.o confounder.o hmac_md5.o unkeyed.o + +OBJS= $(OUTPRE)cbc.$(OBJEXT) $(OUTPRE)confounder.$(OBJEXT) \ + $(OUTPRE)hmac_md5.$(OBJEXT) $(OUTPRE)unkeyed.$(OBJEXT) + +SRCS= $(srcdir)/cbc.c $(srcdir)/confounder.c $(srcdir)/hmac_md5.c \ + $(srcdir)/unkeyed.c + +##DOS##LIBOBJS = $(OBJS) + +all-unix:: all-libobjs + +includes:: depend + +depend:: $(SRCS) + +clean-unix:: clean-libobjs + +@libobj_frag@ + diff --git a/src/lib/crypto/krb/keyhash_provider/md5_hmac.c b/src/lib/crypto/krb/checksum/cbc.c index 45a4e5d..6beadf8 100644 --- a/src/lib/crypto/krb/keyhash_provider/md5_hmac.c +++ b/src/lib/crypto/krb/checksum/cbc.c @@ -1,9 +1,9 @@ /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* - * lib/crypto/keyhash_provider/md5_hmac.c + * lib/crypto/krb/checksum/cbc.c * - * Copyright 2001, 2009 by the Massachusetts Institute of Technology. - * All Rights Reserved. + * Copyright (C) 2009 by the Massachusetts Institute of Technology. + * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. @@ -24,40 +24,20 @@ * this software for any purpose. It is provided "as is" without express * or implied warranty. * - * Implementation of Microsoft KERB_CHECKSUM_MD5_HMAC + * CBC checksum, which computes the ivec resulting from CBC encryption of the + * input. */ #include "k5-int.h" -#include "keyhash_provider.h" -#include "arcfour-int.h" -#include "rsa-md5.h" -#include "hash_provider.h" +#include "cksumtypes.h" -static krb5_error_code -k5_md5_hmac_hash(krb5_key key, krb5_keyusage usage, const krb5_data *input, - krb5_data *output) +krb5_error_code +krb5int_cbc_checksum(const struct krb5_cksumtypes *ctp, + krb5_key key, krb5_keyusage usage, + const krb5_crypto_iov *data, size_t num_data, + krb5_data *output) { - krb5_keyusage ms_usage; - krb5_MD5_CTX ctx; - unsigned char t[4]; - krb5_crypto_iov iov; - - krb5int_MD5Init(&ctx); - - ms_usage = krb5int_arcfour_translate_usage(usage); - store_32_le(ms_usage, t); - krb5int_MD5Update(&ctx, t, sizeof(t)); - krb5int_MD5Update(&ctx, (unsigned char *)input->data, input->length); - krb5int_MD5Final(&ctx); - - iov.flags = KRB5_CRYPTO_TYPE_DATA; - iov.data = make_data(ctx.digest, 16); - return krb5int_hmac(&krb5int_hash_md5, key, &iov, 1, output); + if (ctp->enc->cbc_mac == NULL) + return KRB5_CRYPTO_INTERNAL; + return ctp->enc->cbc_mac(key, data, num_data, NULL, output); } - -const struct krb5_keyhash_provider krb5int_keyhash_md5_hmac = { - 16, - k5_md5_hmac_hash, - NULL, /*checksum again*/ - NULL, NULL -}; diff --git a/src/lib/crypto/krb/checksum/confounder.c b/src/lib/crypto/krb/checksum/confounder.c new file mode 100644 index 0000000..73d69e3 --- /dev/null +++ b/src/lib/crypto/krb/checksum/confounder.c @@ -0,0 +1,159 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + * lib/crypto/krb/checksum/confounder.c + * + * Copyright (C) 2009 by the Massachusetts Institute of Technology. + * All rights reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * Confounder checksum implementation, using tokens of the form: + * enc(xorkey, confounder | hash(confounder | data)) + * where xorkey is the key XOR'd with 0xf0 bytes. + */ + +#include "k5-int.h" +#include "cksumtypes.h" + +/* Derive a key by XOR with 0xF0 bytes. */ +static krb5_error_code +mk_xorkey(krb5_key origkey, krb5_key *xorkey) +{ + krb5_error_code retval = 0; + unsigned char *xorbytes; + krb5_keyblock xorkeyblock; + size_t i = 0; + + xorbytes = malloc(origkey->keyblock.length); + if (xorbytes == NULL) + return ENOMEM; + memcpy(xorbytes, origkey->keyblock.contents, origkey->keyblock.length); + for (i = 0; i < sizeof(xorbytes); i++) + xorbytes[i] ^= 0xf0; + + /* Do a shallow copy here. */ + xorkeyblock = origkey->keyblock; + xorkeyblock.contents = xorbytes; + + retval = krb5_k_create_key(0, &xorkeyblock, xorkey); + zapfree(xorbytes, sizeof(xorbytes)); + return retval; +} + +krb5_error_code +krb5int_confounder_checksum(const struct krb5_cksumtypes *ctp, + krb5_key key, krb5_keyusage usage, + const krb5_crypto_iov *data, size_t num_data, + krb5_data *output) +{ + krb5_error_code ret; + krb5_data conf, hashval; + krb5_key xorkey = NULL; + krb5_crypto_iov *hash_iov, iov; + size_t blocksize = ctp->enc->block_size, hashsize = ctp->hash->hashsize; + + conf = make_data(output->data, blocksize); + hashval = make_data(output->data + blocksize, hashsize); + + /* Create the confounder. */ + ret = krb5_c_random_make_octets(NULL, &conf); + if (ret != 0) + return ret; + + ret = mk_xorkey(key, &xorkey); + if (ret) + return ret; + + /* Hash the confounder, then the input data. */ + hash_iov = k5alloc((num_data + 1) * sizeof(krb5_crypto_iov), &ret); + if (hash_iov == NULL) + goto cleanup; + hash_iov[0].flags = KRB5_CRYPTO_TYPE_DATA; + hash_iov[0].data = conf; + memcpy(hash_iov + 1, data, num_data * sizeof(krb5_crypto_iov)); + ret = ctp->hash->hash(hash_iov, num_data + 1, &hashval); + if (ret != 0) + goto cleanup; + + /* Encrypt the confounder and hash value. */ + iov.flags = KRB5_CRYPTO_TYPE_DATA; + iov.data = *output; + ret = ctp->enc->encrypt(xorkey, NULL, &iov, 1); + +cleanup: + free(hash_iov); + krb5_k_free_key(NULL, xorkey); + return ret; +} + +krb5_error_code krb5int_confounder_verify(const struct krb5_cksumtypes *ctp, + krb5_key key, krb5_keyusage usage, + const krb5_crypto_iov *data, + size_t num_data, + const krb5_data *input, + krb5_boolean *valid) +{ + krb5_error_code ret; + unsigned char *plaintext = NULL; + krb5_key xorkey = NULL; + krb5_data computed = empty_data(); + krb5_crypto_iov *hash_iov, iov; + size_t blocksize = ctp->enc->block_size, hashsize = ctp->hash->hashsize; + + plaintext = k5alloc(input->length, &ret); + if (plaintext == NULL) + return ret; + + ret = mk_xorkey(key, &xorkey); + if (ret != 0) + goto cleanup; + + /* Decrypt the input checksum. */ + iov.flags = KRB5_CRYPTO_TYPE_DATA; + iov.data = make_data(plaintext, input->length); + memcpy(plaintext, input->data, input->length); + ret = ctp->enc->decrypt(xorkey, NULL, &iov, 1); + if (ret != 0) + goto cleanup; + + /* Hash the confounder, then the input data. */ + hash_iov = k5alloc((num_data + 1) * sizeof(krb5_crypto_iov), &ret); + if (hash_iov == NULL) + goto cleanup; + hash_iov[0].flags = KRB5_CRYPTO_TYPE_DATA; + hash_iov[0].data = make_data(plaintext, blocksize); + memcpy(hash_iov + 1, data, num_data * sizeof(krb5_crypto_iov)); + ret = alloc_data(&computed, hashsize); + if (ret != 0) + goto cleanup; + ret = ctp->hash->hash(hash_iov, num_data + 1, &computed); + if (ret != 0) + goto cleanup; + + /* Compare the decrypted hash to the computed one. */ + *valid = (memcmp(plaintext + blocksize, computed.data, hashsize) == 0); + +cleanup: + zapfree(plaintext, input->length); + zapfree(computed.data, hashsize); + free(hash_iov); + krb5_k_free_key(NULL, xorkey); + return ret; +} diff --git a/src/lib/crypto/krb/keyhash_provider/deps b/src/lib/crypto/krb/checksum/deps index 2cca4cd..65fd5f2 100644 --- a/src/lib/crypto/krb/keyhash_provider/deps +++ b/src/lib/crypto/krb/checksum/deps @@ -1,9 +1,21 @@ # # Generated makefile dependencies follow. # -descbc.so descbc.po $(OUTPRE)descbc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ +cbc.so cbc.po $(OUTPRE)cbc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../builtin/des/des_int.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../cksumtypes.h \ + $(srcdir)/../etypes.h $(top_srcdir)/include/k5-buf.h \ + $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ + $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ + $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ + $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \ + $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ + $(top_srcdir)/include/krb5/preauth_plugin.h $(top_srcdir)/include/port-sockets.h \ + $(top_srcdir)/include/socket-utils.h cbc.c +confounder.so confounder.po $(OUTPRE)confounder.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(srcdir)/../cksumtypes.h $(srcdir)/../etypes.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ @@ -11,56 +23,27 @@ descbc.so descbc.po $(OUTPRE)descbc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ - descbc.c keyhash_provider.h -k5_md4des.so k5_md4des.po $(OUTPRE)k5_md4des.$(OBJEXT): \ - $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ - $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ - $(COM_ERR_DEPS) $(srcdir)/../../builtin/des/des_int.h \ - $(srcdir)/../../builtin/md4/rsa-md4.h $(top_srcdir)/include/k5-buf.h \ - $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ - $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ - $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ - $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \ - $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ - $(top_srcdir)/include/krb5/preauth_plugin.h $(top_srcdir)/include/port-sockets.h \ - $(top_srcdir)/include/socket-utils.h k5_md4des.c keyhash_provider.h -k5_md5des.so k5_md5des.po $(OUTPRE)k5_md5des.$(OBJEXT): \ + confounder.c +hmac_md5.so hmac_md5.po $(OUTPRE)hmac_md5.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ - $(COM_ERR_DEPS) $(srcdir)/../../builtin/des/des_int.h \ - $(srcdir)/../../builtin/md5/rsa-md5.h $(top_srcdir)/include/k5-buf.h \ + $(COM_ERR_DEPS) $(srcdir)/../arcfour/arcfour.h $(srcdir)/../cksumtypes.h \ + $(srcdir)/../etypes.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/preauth_plugin.h $(top_srcdir)/include/port-sockets.h \ - $(top_srcdir)/include/socket-utils.h k5_md5des.c keyhash_provider.h -hmac_md5.so hmac_md5.po $(OUTPRE)hmac_md5.$(OBJEXT): \ - $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ - $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ - $(COM_ERR_DEPS) $(srcdir)/../../builtin/hash_provider/hash_provider.h \ - $(srcdir)/../../builtin/md5/rsa-md5.h $(srcdir)/../aead.h \ - $(srcdir)/../arcfour/arcfour-int.h $(srcdir)/../arcfour/arcfour.h \ - $(srcdir)/../cksumtypes.h $(srcdir)/../etypes.h $(top_srcdir)/include/k5-buf.h \ + $(top_srcdir)/include/socket-utils.h hmac_md5.c +unkeyed.so unkeyed.po $(OUTPRE)unkeyed.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../cksumtypes.h \ + $(srcdir)/../etypes.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/preauth_plugin.h $(top_srcdir)/include/port-sockets.h \ - $(top_srcdir)/include/socket-utils.h hmac_md5.c keyhash_provider.h -md5_hmac.so md5_hmac.po $(OUTPRE)md5_hmac.$(OBJEXT): \ - $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ - $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ - $(COM_ERR_DEPS) $(srcdir)/../../builtin/hash_provider/hash_provider.h \ - $(srcdir)/../../builtin/md5/rsa-md5.h $(srcdir)/../arcfour/arcfour-int.h \ - $(srcdir)/../arcfour/arcfour.h $(srcdir)/../etypes.h \ - $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ - $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ - $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ - $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ - $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ - $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \ - $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ - keyhash_provider.h md5_hmac.c + $(top_srcdir)/include/socket-utils.h unkeyed.c diff --git a/src/lib/crypto/krb/checksum/hmac_md5.c b/src/lib/crypto/krb/checksum/hmac_md5.c new file mode 100644 index 0000000..1dc05ea --- /dev/null +++ b/src/lib/crypto/krb/checksum/hmac_md5.c @@ -0,0 +1,94 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + * lib/crypto/krb/checksum/hmac_md5.c + * + * Copyright (C) 2009 by the Massachusetts Institute of Technology. + * All rights reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * Microsoft HMAC-MD5 and MD5-HMAC checksums (see RFC 4757): + * HMAC(KS, hash(msusage || input)) + * KS is HMAC(key, "signaturekey\0") for HMAC-MD5, or just the key for + * MD5-HMAC. + */ + +#include "k5-int.h" +#include "cksumtypes.h" +#include "arcfour.h" +#include "arcfour-int.h" + +krb5_error_code krb5int_hmacmd5_checksum(const struct krb5_cksumtypes *ctp, + krb5_key key, krb5_keyusage usage, + const krb5_crypto_iov *data, + size_t num_data, + krb5_data *output) +{ + krb5_keyusage ms_usage; + krb5_error_code ret; + krb5_keyblock ks, *keyblock; + krb5_crypto_iov *hash_iov = NULL, iov; + krb5_data ds = empty_data(), hashval = empty_data(); + char t[4]; + + if (ctp->ctype == CKSUMTYPE_HMAC_MD5_ARCFOUR) { + /* Compute HMAC(key, "signaturekey\0") to get the signing key ks. */ + ret = alloc_data(&ds, key->keyblock.length); + if (ret != 0) + goto cleanup; + + iov.flags = KRB5_CRYPTO_TYPE_DATA; + iov.data = make_data("signaturekey", 13); + ret = krb5int_hmac(ctp->hash, key, &iov, 1, &ds); + if (ret) + goto cleanup; + ks.length = key->keyblock.length; + ks.contents = (krb5_octet *) ds.data; + keyblock = &ks; + } else /* For md5-hmac, just use the key. */ + keyblock = &key->keyblock; + + /* Compute the MD5 value of the input. */ + ms_usage = krb5int_arcfour_translate_usage(usage); + store_32_le(ms_usage, t); + hash_iov = k5alloc((num_data + 1) * sizeof(krb5_crypto_iov), &ret); + if (hash_iov == NULL) + goto cleanup; + hash_iov[0].flags = KRB5_CRYPTO_TYPE_DATA; + hash_iov[0].data = make_data(t, 4); + memcpy(hash_iov + 1, data, num_data * sizeof(krb5_crypto_iov)); + ret = alloc_data(&hashval, ctp->hash->hashsize); + if (ret != 0) + goto cleanup; + ret = ctp->hash->hash(hash_iov, num_data + 1, &hashval); + if (ret != 0) + goto cleanup; + + /* Compute HMAC(ks, md5value). */ + iov.flags = KRB5_CRYPTO_TYPE_DATA; + iov.data = hashval; + ret = krb5int_hmac_keyblock(ctp->hash, keyblock, &iov, 1, output); + +cleanup: + zapfree(ds.data, ds.length); + zapfree(hashval.data, hashval.length); + free(hash_iov); + return ret; +} diff --git a/src/lib/crypto/krb/checksum/unkeyed.c b/src/lib/crypto/krb/checksum/unkeyed.c new file mode 100644 index 0000000..fddd676 --- /dev/null +++ b/src/lib/crypto/krb/checksum/unkeyed.c @@ -0,0 +1,40 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + * lib/crypto/krb/checksum/unkeyed.c + * + * Copyright (C) 2009 by the Massachusetts Institute of Technology. + * All rights reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * Unkeyed hash checksum implementation. + */ + +#include "k5-int.h" +#include "cksumtypes.h" + +krb5_error_code +krb5int_unkeyed_checksum(const struct krb5_cksumtypes *ctp, + krb5_key key, krb5_keyusage usage, + const krb5_crypto_iov *data, size_t num_data, + krb5_data *output) +{ + return ctp->hash->hash(data, num_data, output); +} diff --git a/src/lib/crypto/krb/checksum_length.c b/src/lib/crypto/krb/checksum_length.c index 50e562c..2e869cb 100644 --- a/src/lib/crypto/krb/checksum_length.c +++ b/src/lib/crypto/krb/checksum_length.c @@ -32,22 +32,12 @@ krb5_error_code KRB5_CALLCONV krb5_c_checksum_length(krb5_context context, krb5_cksumtype cksumtype, size_t *length) { - unsigned int i; + const struct krb5_cksumtypes *ctp; - for (i=0; i<krb5int_cksumtypes_length; i++) { - if (krb5int_cksumtypes_list[i].ctype == cksumtype) - break; - } - - if (i == krb5int_cksumtypes_length) + ctp = find_cksumtype(cksumtype); + if (ctp == NULL) return KRB5_BAD_ENCTYPE; - if (krb5int_cksumtypes_list[i].keyhash) - *length = krb5int_cksumtypes_list[i].keyhash->hashsize; - else if (krb5int_cksumtypes_list[i].trunc_size) - *length = krb5int_cksumtypes_list[i].trunc_size; - else - *length = krb5int_cksumtypes_list[i].hash->hashsize; - + *length = ctp->output_size; return 0; } diff --git a/src/lib/crypto/krb/cksumtype_to_string.c b/src/lib/crypto/krb/cksumtype_to_string.c index 206c2e1..1c084e6 100644 --- a/src/lib/crypto/krb/cksumtype_to_string.c +++ b/src/lib/crypto/krb/cksumtype_to_string.c @@ -31,16 +31,13 @@ krb5_error_code KRB5_CALLCONV krb5_cksumtype_to_string(krb5_cksumtype cksumtype, char *buffer, size_t buflen) { - unsigned int i; + const struct krb5_cksumtypes *ctp; - for (i = 0; i < krb5int_cksumtypes_length; i++) { - if (krb5int_cksumtypes_list[i].ctype == cksumtype) { - if (strlcpy(buffer, krb5int_cksumtypes_list[i].out_string, - buflen) >= buflen) - return ENOMEM; - return 0; - } - } + ctp = find_cksumtype(cksumtype); + if (ctp == NULL) + return KRB5_BAD_ENCTYPE; - return EINVAL; + if (strlcpy(buffer, ctp->out_string, buflen) >= buflen) + return ENOMEM; + return 0; } diff --git a/src/lib/crypto/krb/cksumtypes.c b/src/lib/crypto/krb/cksumtypes.c index 801b453..74fd158 100644 --- a/src/lib/crypto/krb/cksumtypes.c +++ b/src/lib/crypto/krb/cksumtypes.c @@ -26,67 +26,85 @@ */ #include "k5-int.h" +#include "enc_provider.h" #include "hash_provider.h" -#include "keyhash_provider.h" +#include "dk.h" #include "cksumtypes.h" const struct krb5_cksumtypes krb5int_cksumtypes_list[] = { - { CKSUMTYPE_CRC32, KRB5_CKSUMFLAG_NOT_COLL_PROOF, + { CKSUMTYPE_CRC32, "crc32", { 0 }, "CRC-32", - 0, NULL, - &krb5int_hash_crc32 }, + NULL, &krb5int_hash_crc32, + krb5int_unkeyed_checksum, NULL, + 4, 4, CKSUM_UNKEYED | CKSUM_NOT_COLL_PROOF }, - { CKSUMTYPE_RSA_MD4, 0, + { CKSUMTYPE_RSA_MD4, "md4", { 0 }, "RSA-MD4", - 0, NULL, - &krb5int_hash_md4 }, - { CKSUMTYPE_RSA_MD4_DES, 0, + NULL, &krb5int_hash_md4, + krb5int_unkeyed_checksum, NULL, + 16, 16, CKSUM_UNKEYED }, + + { CKSUMTYPE_RSA_MD4_DES, "md4-des", { 0 }, "RSA-MD4 with DES cbc mode", - ENCTYPE_DES_CBC_CRC, &krb5int_keyhash_md4des, - NULL }, + &krb5int_enc_des, &krb5int_hash_md4, + krb5int_confounder_checksum, krb5int_confounder_verify, + 24, 24, 0 }, - { CKSUMTYPE_DESCBC, 0, + { CKSUMTYPE_DESCBC, "des-cbc", { 0 }, "DES cbc mode", - ENCTYPE_DES_CBC_CRC, &krb5int_keyhash_descbc, - NULL }, + &krb5int_enc_des, NULL, + krb5int_cbc_checksum, NULL, + 8, 8, 0 }, - { CKSUMTYPE_RSA_MD5, 0, + { CKSUMTYPE_RSA_MD5, "md5", { 0 }, "RSA-MD5", - 0, NULL, - &krb5int_hash_md5 }, - { CKSUMTYPE_RSA_MD5_DES, 0, + NULL, &krb5int_hash_md5, + krb5int_unkeyed_checksum, NULL, + 16, 16, CKSUM_UNKEYED }, + + { CKSUMTYPE_RSA_MD5_DES, "md5-des", { 0 }, "RSA-MD5 with DES cbc mode", - ENCTYPE_DES_CBC_CRC, &krb5int_keyhash_md5des, - NULL }, + &krb5int_enc_des, &krb5int_hash_md5, + krb5int_confounder_checksum, krb5int_confounder_verify, + 24, 24, 0 }, - { CKSUMTYPE_NIST_SHA, 0, + { CKSUMTYPE_NIST_SHA, "sha", { 0 }, "NIST-SHA", - 0, NULL, - &krb5int_hash_sha1 }, + NULL, &krb5int_hash_sha1, + krb5int_unkeyed_checksum, NULL, + 20, 20, CKSUM_UNKEYED }, - { CKSUMTYPE_HMAC_SHA1_DES3, KRB5_CKSUMFLAG_DERIVE, + { CKSUMTYPE_HMAC_SHA1_DES3, "hmac-sha1-des3", { "hmac-sha1-des3-kd" }, "HMAC-SHA1 DES3 key", - 0, NULL, - &krb5int_hash_sha1 }, - { CKSUMTYPE_HMAC_MD5_ARCFOUR, 0, + NULL, &krb5int_hash_sha1, + krb5int_dk_checksum, NULL, + 20, 20, 0 }, + + { CKSUMTYPE_HMAC_MD5_ARCFOUR, "hmac-md5-rc4", { "hmac-md5-enc", "hmac-md5-earcfour" }, "Microsoft HMAC MD5 (RC4 key)", - ENCTYPE_ARCFOUR_HMAC, &krb5int_keyhash_hmac_md5, - NULL }, + &krb5int_enc_arcfour, &krb5int_hash_md5, + krb5int_hmacmd5_checksum, NULL, + 16, 16, 0 }, - { CKSUMTYPE_HMAC_SHA1_96_AES128, KRB5_CKSUMFLAG_DERIVE, + { CKSUMTYPE_HMAC_SHA1_96_AES128, "hmac-sha1-96-aes128", { 0 }, "HMAC-SHA1 AES128 key", - 0, NULL, - &krb5int_hash_sha1, 12 }, - { CKSUMTYPE_HMAC_SHA1_96_AES256, KRB5_CKSUMFLAG_DERIVE, + NULL, &krb5int_hash_sha1, + krb5int_dk_checksum, NULL, + 20, 12, 0 }, + + { CKSUMTYPE_HMAC_SHA1_96_AES256, "hmac-sha1-96-aes256", { 0 }, "HMAC-SHA1 AES256 key", - 0, NULL, - &krb5int_hash_sha1, 12 }, - { CKSUMTYPE_MD5_HMAC_ARCFOUR, 0, + NULL, &krb5int_hash_sha1, + krb5int_dk_checksum, NULL, + 20, 12, 0 }, + + { CKSUMTYPE_MD5_HMAC_ARCFOUR, "md5-hmac-rc4", { 0 }, "Microsoft MD5 HMAC (RC4 key)", - ENCTYPE_ARCFOUR_HMAC, &krb5int_keyhash_md5_hmac, - NULL } + &krb5int_enc_arcfour, &krb5int_hash_md5, + krb5int_hmacmd5_checksum, NULL, + 16, 16, 0 }, }; -const unsigned int krb5int_cksumtypes_length = +const size_t krb5int_cksumtypes_length = sizeof(krb5int_cksumtypes_list) / sizeof(struct krb5_cksumtypes); diff --git a/src/lib/crypto/krb/cksumtypes.h b/src/lib/crypto/krb/cksumtypes.h index 53f58fd..8c32f66 100644 --- a/src/lib/crypto/krb/cksumtypes.h +++ b/src/lib/crypto/krb/cksumtypes.h @@ -28,42 +28,114 @@ #ifndef CKSUMTYPES_H #define CKSUMTYPES_H #include "k5-int.h" +#include "etypes.h" + +struct krb5_cksumtypes; + +/* + * Compute a checksum over the header, data, padding, and sign-only fields of + * the iov array data (of size num_data). The output buffer will already be + * allocated with ctp->compute_size bytes available; the handler just needs to + * fill in the contents. If ctp->enc is not NULL, the handler can assume that + * key is a valid-length key of an enctype which uses that enc provider. + */ +typedef krb5_error_code (*checksum_func)(const struct krb5_cksumtypes *ctp, + krb5_key key, krb5_keyusage usage, + const krb5_crypto_iov *data, + size_t num_data, + krb5_data *output); + +/* + * Verify a checksum over the header, data, padding, and sign-only fields of + * the iov array data (of size num_data), and store the boolean result in + * *valid. The handler can assume that hash has length ctp->output_size. If + * ctp->enc is not NULL, the handler can assume that key a valid-length key of + * an enctype which uses that enc provider. + */ +typedef krb5_error_code (*verify_func)(const struct krb5_cksumtypes *ctp, + krb5_key key, krb5_keyusage usage, + const krb5_crypto_iov *data, + size_t num_data, + const krb5_data *input, + krb5_boolean *valid); struct krb5_cksumtypes { krb5_cksumtype ctype; - unsigned int flags; char *name; char *aliases[2]; char *out_string; - /* - * If the hash is keyed, this is the etype it is keyed with. - * Actually, it can be keyed by any etype which has the same - * enc_provider as the specified etype. DERIVE checksums can - * be keyed with any valid etype. - */ - krb5_enctype keyed_etype; - /* - * I can't statically initialize a union, so I'm just going to use - * two pointers here. The keyhash is used if non-NULL. If NULL, - * then HMAC/hash with derived keys is used if the relevant flag - * is set. Otherwise, a non-keyed hash is computed. This is all - * kind of messy, but so is the krb5 api. - */ - const struct krb5_keyhash_provider *keyhash; + const struct krb5_enc_provider *enc; const struct krb5_hash_provider *hash; - /* - * This just gets uglier and uglier. In the key derivation case, - * we produce an hmac. To make the hmac code work, we can't hack - * the output size indicated by the hash provider, but we may want - * a truncated hmac. If we want truncation, this is the number of - * bytes we truncate to; it should be 0 otherwise. - */ - unsigned int trunc_size; + checksum_func checksum; + verify_func verify; /* NULL means recompute checksum and compare */ + unsigned int compute_size; /* Allocation size for checksum computation */ + unsigned int output_size; /* Possibly truncated output size */ + krb5_flags flags; }; -#define KRB5_CKSUMFLAG_DERIVE 0x0001 -#define KRB5_CKSUMFLAG_NOT_COLL_PROOF 0x0002 +#define CKSUM_UNKEYED 0x0001 +#define CKSUM_NOT_COLL_PROOF 0x0002 extern const struct krb5_cksumtypes krb5int_cksumtypes_list[]; -extern const unsigned int krb5int_cksumtypes_length; +extern const size_t krb5int_cksumtypes_length; + +krb5_error_code krb5int_unkeyed_checksum(const struct krb5_cksumtypes *ctp, + krb5_key key, krb5_keyusage usage, + const krb5_crypto_iov *data, + size_t num_data, + krb5_data *output); + +krb5_error_code krb5int_cbc_checksum(const struct krb5_cksumtypes *ctp, + krb5_key key, krb5_keyusage usage, + const krb5_crypto_iov *data, + size_t num_data, + krb5_data *output); + +krb5_error_code krb5int_hmacmd5_checksum(const struct krb5_cksumtypes *ctp, + krb5_key key, krb5_keyusage usage, + const krb5_crypto_iov *data, + size_t num_data, + krb5_data *output); + +krb5_error_code krb5int_confounder_checksum(const struct krb5_cksumtypes *ctp, + krb5_key key, krb5_keyusage usage, + const krb5_crypto_iov *data, + size_t num_data, + krb5_data *output); + +krb5_error_code krb5int_confounder_verify(const struct krb5_cksumtypes *ctp, + krb5_key key, krb5_keyusage usage, + const krb5_crypto_iov *data, + size_t num_data, + const krb5_data *input, + krb5_boolean *valid); + +static inline const struct krb5_cksumtypes * +find_cksumtype(krb5_cksumtype ctype) +{ + size_t i; + + for (i = 0; i < krb5int_cksumtypes_length; i++) { + if (krb5int_cksumtypes_list[i].ctype == ctype) + break; + } + + if (i == krb5int_cksumtypes_length) + return NULL; + return &krb5int_cksumtypes_list[i]; +} + +static inline krb5_error_code +verify_key(const struct krb5_cksumtypes *ctp, krb5_key key) +{ + const struct krb5_keytypes *ktp; + + ktp = key ? find_enctype(key->keyblock.enctype) : NULL; + if (ctp->enc != NULL && (!ktp || ktp->enc != ctp->enc)) + return KRB5_BAD_ENCTYPE; + if (key && (!ktp || key->keyblock.length != ktp->enc->keylength)) + return KRB5_BAD_KEYSIZE; + return 0; +} + #endif diff --git a/src/lib/crypto/krb/coll_proof_cksum.c b/src/lib/crypto/krb/coll_proof_cksum.c index a2cfdb7..bc13ba4 100644 --- a/src/lib/crypto/krb/coll_proof_cksum.c +++ b/src/lib/crypto/krb/coll_proof_cksum.c @@ -31,15 +31,8 @@ krb5_boolean KRB5_CALLCONV krb5_c_is_coll_proof_cksum(krb5_cksumtype ctype) { - unsigned int i; + const struct krb5_cksumtypes *ctp; - for (i = 0; i < krb5int_cksumtypes_length; i++) { - if (krb5int_cksumtypes_list[i].ctype == ctype) - return((krb5int_cksumtypes_list[i].flags & - KRB5_CKSUMFLAG_NOT_COLL_PROOF) ? FALSE : TRUE); - } - - /* ick, but it's better than coredumping, which is what the - old code would have done */ - return FALSE; + ctp = find_cksumtype(ctype); + return (ctp != NULL && !(ctp->flags & CKSUM_NOT_COLL_PROOF)); } diff --git a/src/lib/crypto/krb/deps b/src/lib/crypto/krb/deps index c7d3bae2..5e081f7 100644 --- a/src/lib/crypto/krb/deps +++ b/src/lib/crypto/krb/deps @@ -33,7 +33,7 @@ checksum_length.so checksum_length.po $(OUTPRE)checksum_length.$(OBJEXT): \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ - checksum_length.c cksumtypes.h + checksum_length.c cksumtypes.h etypes.h cksumtype_to_string.so cksumtype_to_string.po $(OUTPRE)cksumtype_to_string.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ @@ -44,19 +44,20 @@ cksumtype_to_string.so cksumtype_to_string.po $(OUTPRE)cksumtype_to_string.$(OBJ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ - cksumtype_to_string.c cksumtypes.h + cksumtype_to_string.c cksumtypes.h etypes.h cksumtypes.so cksumtypes.po $(OUTPRE)cksumtypes.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ - $(COM_ERR_DEPS) $(srcdir)/../builtin/hash_provider/hash_provider.h \ - $(srcdir)/keyhash_provider/keyhash_provider.h $(top_srcdir)/include/k5-buf.h \ - $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ - $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ - $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ - $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \ - $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ - $(top_srcdir)/include/krb5/preauth_plugin.h $(top_srcdir)/include/port-sockets.h \ - $(top_srcdir)/include/socket-utils.h cksumtypes.c cksumtypes.h + $(COM_ERR_DEPS) $(srcdir)/../builtin/enc_provider/enc_provider.h \ + $(srcdir)/../builtin/hash_provider/hash_provider.h \ + $(srcdir)/dk/dk.h $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ + $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ + $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ + $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ + $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ + $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \ + $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ + cksumtypes.c cksumtypes.h etypes.h coll_proof_cksum.so coll_proof_cksum.po $(OUTPRE)coll_proof_cksum.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ @@ -67,7 +68,7 @@ coll_proof_cksum.so coll_proof_cksum.po $(OUTPRE)coll_proof_cksum.$(OBJEXT): \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ - cksumtypes.h coll_proof_cksum.c + cksumtypes.h coll_proof_cksum.c etypes.h combine_keys.so combine_keys.po $(OUTPRE)combine_keys.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ @@ -234,7 +235,7 @@ keyed_cksum.so keyed_cksum.po $(OUTPRE)keyed_cksum.$(OBJEXT): \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ - cksumtypes.h keyed_cksum.c + cksumtypes.h etypes.h keyed_cksum.c keyed_checksum_types.so keyed_checksum_types.po $(OUTPRE)keyed_checksum_types.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ @@ -387,7 +388,7 @@ string_to_cksumtype.so string_to_cksumtype.po $(OUTPRE)string_to_cksumtype.$(OBJ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ - cksumtypes.h string_to_cksumtype.c + cksumtypes.h etypes.h string_to_cksumtype.c string_to_enctype.so string_to_enctype.po $(OUTPRE)string_to_enctype.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ @@ -420,7 +421,7 @@ valid_cksumtype.so valid_cksumtype.po $(OUTPRE)valid_cksumtype.$(OBJEXT): \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ - cksumtypes.h valid_cksumtype.c + cksumtypes.h etypes.h valid_cksumtype.c valid_enctype.so valid_enctype.po $(OUTPRE)valid_enctype.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ @@ -442,7 +443,7 @@ verify_checksum.so verify_checksum.po $(OUTPRE)verify_checksum.$(OBJEXT): \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ - cksumtypes.h verify_checksum.c + cksumtypes.h etypes.h verify_checksum.c verify_checksum_iov.so verify_checksum_iov.po $(OUTPRE)verify_checksum_iov.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ diff --git a/src/lib/crypto/krb/dk/checksum.c b/src/lib/crypto/krb/dk/checksum.c index dee4f47..3dbde10 100644 --- a/src/lib/crypto/krb/dk/checksum.c +++ b/src/lib/crypto/krb/dk/checksum.c @@ -28,15 +28,15 @@ #include "k5-int.h" #include "etypes.h" #include "dk.h" -#include "aead.h" +#include "cksumtypes.h" #define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */ krb5_error_code -krb5int_dk_make_checksum(const struct krb5_hash_provider *hash, - krb5_key key, krb5_keyusage usage, - const krb5_crypto_iov *data, size_t num_data, - krb5_data *output) +krb5int_dk_checksum(const struct krb5_cksumtypes *ctp, + krb5_key key, krb5_keyusage usage, + const krb5_crypto_iov *data, size_t num_data, + krb5_data *output) { const struct krb5_keytypes *ktp; const struct krb5_enc_provider *enc; @@ -45,32 +45,24 @@ krb5int_dk_make_checksum(const struct krb5_hash_provider *hash, krb5_data datain; krb5_key kc; + /* Use the key's enctype (more flexible than setting an enctype in ctp). */ ktp = find_enctype(key->keyblock.enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; enc = ktp->enc; - - /* - * key->length will be tested in enc->encrypt. - * output->length will be tested in krb5int_hmac. - */ + if (key->keyblock.length != enc->keylength) + return KRB5_BAD_KEYSIZE; /* Derive the key. */ - - datain.data = (char *) constantdata; - datain.length = K5CLENGTH; - + datain = make_data(constantdata, K5CLENGTH); store_32_be(usage, constantdata); - - datain.data[4] = (char) 0x99; - + constantdata[4] = (char) 0x99; ret = krb5int_derive_key(enc, key, &kc, &datain); if (ret) return ret; /* Hash the data. */ - - ret = krb5int_hmac(hash, kc, data, num_data, output); + ret = krb5int_hmac(ctp->hash, kc, data, num_data, output); if (ret) memset(output->data, 0, output->length); diff --git a/src/lib/crypto/krb/dk/deps b/src/lib/crypto/krb/dk/deps index 1fa446a..029fe6a 100644 --- a/src/lib/crypto/krb/dk/deps +++ b/src/lib/crypto/krb/dk/deps @@ -4,15 +4,15 @@ checksum.so checksum.po $(OUTPRE)checksum.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ - $(COM_ERR_DEPS) $(srcdir)/../aead.h $(srcdir)/../cksumtypes.h \ - $(srcdir)/../etypes.h $(top_srcdir)/include/k5-buf.h \ - $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ - $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ - $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ - $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \ - $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ - $(top_srcdir)/include/krb5/preauth_plugin.h $(top_srcdir)/include/port-sockets.h \ - $(top_srcdir)/include/socket-utils.h checksum.c dk.h + $(COM_ERR_DEPS) $(srcdir)/../cksumtypes.h $(srcdir)/../etypes.h \ + $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ + $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ + $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ + $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ + $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ + $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \ + $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ + checksum.c dk.h dk_aead.so dk_aead.po $(OUTPRE)dk_aead.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../aead.h \ diff --git a/src/lib/crypto/krb/dk/dk.h b/src/lib/crypto/krb/dk/dk.h index 5e00268..0fdd984 100644 --- a/src/lib/crypto/krb/dk/dk.h +++ b/src/lib/crypto/krb/dk/dk.h @@ -27,6 +27,7 @@ #include "k5-int.h" #include "etypes.h" +#include "cksumtypes.h" unsigned int krb5int_dk_crypto_length(const struct krb5_keytypes *ktp, @@ -69,10 +70,10 @@ krb5int_derive_key(const struct krb5_enc_provider *enc, const krb5_data *in_constant); krb5_error_code -krb5int_dk_make_checksum(const struct krb5_hash_provider *hash, - krb5_key key, krb5_keyusage usage, - const krb5_crypto_iov *data, size_t num_data, - krb5_data *output); +krb5int_dk_checksum(const struct krb5_cksumtypes *ctp, + krb5_key key, krb5_keyusage usage, + const krb5_crypto_iov *data, size_t num_data, + krb5_data *output); krb5_error_code krb5int_derive_random(const struct krb5_enc_provider *enc, diff --git a/src/lib/crypto/krb/keyed_checksum_types.c b/src/lib/crypto/krb/keyed_checksum_types.c index 2cba377..3cd1ebc 100644 --- a/src/lib/crypto/krb/keyed_checksum_types.c +++ b/src/lib/crypto/krb/keyed_checksum_types.c @@ -30,13 +30,12 @@ #include "cksumtypes.h" static krb5_boolean -etype_match(krb5_enctype e1, krb5_enctype e2) +is_keyed_for(const struct krb5_cksumtypes *ctp, + const struct krb5_keytypes *ktp) { - const struct krb5_keytypes *ktp1, *ktp2; - - ktp1 = find_enctype(e1); - ktp2 = find_enctype(e2); - return (ktp1 != NULL && ktp2 != NULL && ktp1->enc == ktp2->enc); + if (ctp->flags & CKSUM_UNKEYED) + return FALSE; + return (!ctp->enc || ktp->enc == ctp->enc); } krb5_error_code KRB5_CALLCONV @@ -45,16 +44,20 @@ krb5_c_keyed_checksum_types(krb5_context context, krb5_enctype enctype, { unsigned int i, c, nctypes; krb5_cksumtype *ctypes; - const struct krb5_cksumtypes *ct; + const struct krb5_cksumtypes *ctp; + const struct krb5_keytypes *ktp; *count = 0; *cksumtypes = NULL; + ktp = find_enctype(enctype); + if (ktp == NULL) + return KRB5_BAD_ENCTYPE; + nctypes = 0; for (i = 0; i < krb5int_cksumtypes_length; i++) { - ct = &krb5int_cksumtypes_list[i]; - if ((ct->keyhash && etype_match(ct->keyed_etype, enctype)) || - (ct->flags & KRB5_CKSUMFLAG_DERIVE)) + ctp = &krb5int_cksumtypes_list[i]; + if (is_keyed_for(ctp, ktp)) nctypes++; } @@ -64,10 +67,9 @@ krb5_c_keyed_checksum_types(krb5_context context, krb5_enctype enctype, c = 0; for (i = 0; i < krb5int_cksumtypes_length; i++) { - ct = &krb5int_cksumtypes_list[i]; - if ((ct->keyhash && etype_match(ct->keyed_etype, enctype)) || - (ct->flags & KRB5_CKSUMFLAG_DERIVE)) - ctypes[c++] = krb5int_cksumtypes_list[i].ctype; + ctp = &krb5int_cksumtypes_list[i]; + if (is_keyed_for(ctp, ktp)) + ctypes[c++] = ctp->ctype; } *count = nctypes; diff --git a/src/lib/crypto/krb/keyed_cksum.c b/src/lib/crypto/krb/keyed_cksum.c index 2f8bed6..b6d3e3d 100644 --- a/src/lib/crypto/krb/keyed_cksum.c +++ b/src/lib/crypto/krb/keyed_cksum.c @@ -31,17 +31,10 @@ krb5_boolean KRB5_CALLCONV krb5_c_is_keyed_cksum(krb5_cksumtype ctype) { - unsigned int i; const struct krb5_cksumtypes *ctp; - for (i = 0; i < krb5int_cksumtypes_length; i++) { - ctp = &krb5int_cksumtypes_list[i]; - if (ctp->ctype == ctype) { - return (ctp->keyhash != NULL || - (ctp->flags & KRB5_CKSUMFLAG_DERIVE)); - } - } - - /* Invalid ctype. This is misleading, but better than dumping core. */ - return FALSE; + ctp = find_cksumtype(ctype); + if (ctp == NULL) + return FALSE; + return !(ctp->flags & CKSUM_UNKEYED); } diff --git a/src/lib/crypto/krb/keyhash_provider/Makefile.in b/src/lib/crypto/krb/keyhash_provider/Makefile.in deleted file mode 100644 index b36f91a..0000000 --- a/src/lib/crypto/krb/keyhash_provider/Makefile.in +++ /dev/null @@ -1,33 +0,0 @@ -mydir=lib/crypto/krb/keyhash_provider -BUILDTOP=$(REL)..$(S)..$(S)..$(S).. -LOCALINCLUDES = -I$(srcdir)/../../@CRYPTO_IMPL@/des -I$(srcdir)/../../@CRYPTO_IMPL@/md4 \ - -I$(srcdir)/../../@CRYPTO_IMPL@/md5 -I$(srcdir)/../arcfour \ - -I$(srcdir)/../../@CRYPTO_IMPL@/hash_provider -I$(srcdir)/../../@CRYPTO_IMPL@ \ - -I$(srcdir)/.. -DEFS= - -##DOS##BUILDTOP = ..\..\..\.. -##DOS##PREFIXDIR=keyhash_provider -##DOS##OBJFILE=..\$(OUTPRE)kh_pro.lst - -PROG_LIBPATH=-L$(TOPLIBD) -PROG_RPATH=$(KRB5_LIBDIR) - -STLIBOBJS= descbc.o k5_md4des.o k5_md5des.o hmac_md5.o md5_hmac.o - -OBJS= $(OUTPRE)descbc.$(OBJEXT) $(OUTPRE)k5_md4des.$(OBJEXT) $(OUTPRE)k5_md5des.$(OBJEXT) $(OUTPRE)hmac_md5.$(OBJEXT) $(OUTPRE)md5_hmac.$(OBJEXT) - -SRCS= $(srcdir)/descbc.c $(srcdir)/k5_md4des.c $(srcdir)/k5_md5des.c $(srcdir)/hmac_md5.c $(srcdir)/md5_hmac.c - -##DOS##LIBOBJS = $(OBJS) - -all-unix:: all-libobjs - -includes:: depend - -depend:: $(SRCS) - -clean-unix:: clean-libobjs - -@libobj_frag@ - diff --git a/src/lib/crypto/krb/keyhash_provider/descbc.c b/src/lib/crypto/krb/keyhash_provider/descbc.c deleted file mode 100644 index 9581667..0000000 --- a/src/lib/crypto/krb/keyhash_provider/descbc.c +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -/* - * Copyright (C) 1998 by the FundsXpress, INC. - * - * All rights reserved. - * - * Export of this software from the United States of America may require - * a specific license from the United States Government. It is the - * responsibility of any person or organization contemplating export to - * obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of FundsXpress. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. FundsXpress makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "k5-int.h" -#include "des_int.h" -#include "keyhash_provider.h" - -static krb5_error_code -k5_descbc_hash(krb5_key key, krb5_keyusage usage, const krb5_data *input, - krb5_data *output) -{ - mit_des_key_schedule schedule; - - if (key->keyblock.length != 8) - return(KRB5_BAD_KEYSIZE); - if ((input->length%8) != 0) - return(KRB5_BAD_MSIZE); - if (output->length != 8) - return(KRB5_CRYPTO_INTERNAL); - - switch (mit_des_key_sched(key->keyblock.contents, schedule)) { - case -1: - return(KRB5DES_BAD_KEYPAR); - case -2: - return(KRB5DES_WEAK_KEY); - } - - /* this has a return value, but it's useless to us */ - - mit_des_cbc_cksum((unsigned char *) input->data, - (unsigned char *) output->data, input->length, - schedule, - (const unsigned char *)mit_des_zeroblock); - - memset(schedule, 0, sizeof(schedule)); - - return(0); -} - -const struct krb5_keyhash_provider krb5int_keyhash_descbc = { - 8, - k5_descbc_hash, - NULL, - NULL, - NULL -}; diff --git a/src/lib/crypto/krb/keyhash_provider/hmac_md5.c b/src/lib/crypto/krb/keyhash_provider/hmac_md5.c deleted file mode 100644 index 4da77ef..0000000 --- a/src/lib/crypto/krb/keyhash_provider/hmac_md5.c +++ /dev/null @@ -1,137 +0,0 @@ -/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -/* - * lib/crypto/keyhash_provider/hmac_md5.c - * - * Copyright 2001, 2009 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. Furthermore if you modify this software you must label - * your software as modified software and not distribute it in such a - * fashion that it might be confused with the original M.I.T. software. - * M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * - * Implementation of the Microsoft hmac-md5 checksum type. - * Implemented based on draft-brezak-win2k-krb-rc4-hmac-03 - */ - -#include "k5-int.h" -#include "keyhash_provider.h" -#include "arcfour-int.h" -#include "rsa-md5.h" -#include "hash_provider.h" -#include "../aead.h" - -static krb5_error_code -k5_hmac_md5_hash(krb5_key key, krb5_keyusage usage, const krb5_data *input, - krb5_data *output) -{ - krb5_keyusage ms_usage; - krb5_error_code ret; - krb5_keyblock ks; - krb5_crypto_iov iov; - krb5_data ds; - krb5_MD5_CTX ctx; - char t[4]; - - ret = alloc_data(&ds, key->keyblock.length); - if (ret != 0) - return ret; - - /* Compute HMAC(key, "signaturekey\0") to produce the signing key ks. */ - iov.flags = KRB5_CRYPTO_TYPE_DATA; - iov.data = make_data("signaturekey", 13); - ret = krb5int_hmac(&krb5int_hash_md5, key, &iov, 1, &ds); - if (ret) - goto cleanup; - ks.length = key->keyblock.length; - ks.contents = (krb5_octet *) ds.data; - - /* Compute the MD5 value of the input. */ - krb5int_MD5Init(&ctx); - ms_usage = krb5int_arcfour_translate_usage(usage); - store_32_le(ms_usage, t); - krb5int_MD5Update(&ctx, (unsigned char *) &t, 4); - krb5int_MD5Update(&ctx, (unsigned char *) input->data, input->length); - krb5int_MD5Final(&ctx); - - /* Compute HMAC(ks, md5value). */ - iov.data = make_data(ctx.digest, 16); - ret = krb5int_hmac_keyblock(&krb5int_hash_md5, &ks, &iov, 1, output); - -cleanup: - memset(&ctx, 0, sizeof(ctx)); - zapfree(ds.data, ds.length); - return ret; -} - -static krb5_error_code -k5_hmac_md5_hash_iov(krb5_key key, krb5_keyusage usage, - const krb5_crypto_iov *data, size_t num_data, - krb5_data *output) -{ - krb5_keyusage ms_usage; - krb5_error_code ret; - krb5_keyblock ks; - krb5_crypto_iov iov; - krb5_data ds; - krb5_MD5_CTX ctx; - char t[4]; - size_t i; - - ret = alloc_data(&ds, key->keyblock.length); - if (ret != 0) - return ret; - - /* Compute HMAC(key, "signaturekey\0") to produce the signing key ks. */ - iov.flags = KRB5_CRYPTO_TYPE_DATA; - iov.data = make_data("signaturekey", 13); - ret = krb5int_hmac(&krb5int_hash_md5, key, &iov, 1, &ds); - if (ret) - goto cleanup; - ks.length = key->keyblock.length; - ks.contents = (krb5_octet *) ds.data; - - /* Compute the MD5 value of the input. */ - krb5int_MD5Init(&ctx); - ms_usage = krb5int_arcfour_translate_usage(usage); - store_32_le(ms_usage, t); - krb5int_MD5Update(&ctx, (unsigned char *) &t, 4); - for (i = 0; i < num_data; i++) { - if (SIGN_IOV(&data[i])) - krb5int_MD5Update(&ctx, (unsigned char *) data[i].data.data, - data[i].data.length); - } - krb5int_MD5Final(&ctx); - - /* Compute HMAC(ks, md5value). */ - iov.data = make_data(ctx.digest, 16); - ret = krb5int_hmac_keyblock(&krb5int_hash_md5, &ks, &iov, 1, output); - -cleanup: - memset(&ctx, 0, sizeof(ctx)); - zapfree(ds.data, ds.length); - return ret; -} - -const struct krb5_keyhash_provider krb5int_keyhash_hmac_md5 = { - 16, - k5_hmac_md5_hash, - NULL, /*checksum again*/ - k5_hmac_md5_hash_iov, - NULL /*checksum again */ -}; diff --git a/src/lib/crypto/krb/keyhash_provider/k5_md4des.c b/src/lib/crypto/krb/keyhash_provider/k5_md4des.c deleted file mode 100644 index c33f07f..0000000 --- a/src/lib/crypto/krb/keyhash_provider/k5_md4des.c +++ /dev/null @@ -1,205 +0,0 @@ -/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -/* - * Copyright (C) 1998 by the FundsXpress, INC. - * - * All rights reserved. - * - * Export of this software from the United States of America may require - * a specific license from the United States Government. It is the - * responsibility of any person or organization contemplating export to - * obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of FundsXpress. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. FundsXpress makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "k5-int.h" -#include "des_int.h" -#include "rsa-md4.h" -#include "keyhash_provider.h" - -#define CONFLENGTH 8 - -/* Force acceptance of krb5-beta5 md4des checksum for now. */ -#define KRB5int_MD4DES_BETA5_COMPAT - -/* des-cbc(xorkey, conf | rsa-md4(conf | data)) */ - -extern struct krb5_enc_provider krb5int_enc_des; - -/* Derive a key by XOR with 0xF0 bytes. */ -static krb5_error_code -mk_xorkey(krb5_key origkey, krb5_key *xorkey) -{ - krb5_error_code retval = 0; - unsigned char xorbytes[8]; - krb5_keyblock xorkeyblock; - size_t i = 0; - - if (origkey->keyblock.length != sizeof(xorbytes)) - return KRB5_CRYPTO_INTERNAL; - memcpy(xorbytes, origkey->keyblock.contents, sizeof(xorbytes)); - for (i = 0; i < sizeof(xorbytes); i++) - xorbytes[i] ^= 0xf0; - - /* Do a shallow copy here. */ - xorkeyblock = origkey->keyblock; - xorkeyblock.contents = xorbytes; - - retval = krb5_k_create_key(0, &xorkeyblock, xorkey); - zap(xorbytes, sizeof(xorbytes)); - return retval; -} - -static krb5_error_code -k5_md4des_hash(krb5_key key, krb5_keyusage usage, const krb5_data *input, - krb5_data *output) -{ - krb5_error_code ret; - krb5_data data; - krb5_MD4_CTX ctx; - unsigned char conf[CONFLENGTH]; - krb5_key xorkey = NULL; - krb5_crypto_iov iov; - struct krb5_enc_provider *enc = &krb5int_enc_des; - - if (output->length != (CONFLENGTH+RSA_MD4_CKSUM_LENGTH)) - return(KRB5_CRYPTO_INTERNAL); - - /* create the confouder */ - - data.length = CONFLENGTH; - data.data = (char *) conf; - if ((ret = krb5_c_random_make_octets(/* XXX */ 0, &data))) - return(ret); - - ret = mk_xorkey(key, &xorkey); - if (ret) - return ret; - - /* hash the confounder, then the input data */ - - krb5int_MD4Init(&ctx); - krb5int_MD4Update(&ctx, conf, CONFLENGTH); - krb5int_MD4Update(&ctx, (unsigned char *) input->data, - (unsigned int) input->length); - krb5int_MD4Final(&ctx); - - /* construct the buffer to be encrypted */ - - memcpy(output->data, conf, CONFLENGTH); - memcpy(output->data+CONFLENGTH, ctx.digest, RSA_MD4_CKSUM_LENGTH); - - iov.flags = KRB5_CRYPTO_TYPE_DATA; - iov.data = *output; - ret = enc->encrypt(xorkey, NULL, &iov, 1); - - krb5_k_free_key(NULL, xorkey); - - return (ret); -} - -static krb5_error_code -k5_md4des_verify(krb5_key key, krb5_keyusage usage, - const krb5_data *input, const krb5_data *hash, - krb5_boolean *valid) -{ - krb5_error_code ret; - krb5_MD4_CTX ctx; - unsigned char plaintext[CONFLENGTH+RSA_MD4_CKSUM_LENGTH]; - krb5_key xorkey = NULL; - int compathash = 0; - struct krb5_enc_provider *enc = &krb5int_enc_des; - krb5_data iv; - krb5_crypto_iov iov; - - iv.data = NULL; - iv.length = 0; - - if (key->keyblock.length != 8) - return(KRB5_BAD_KEYSIZE); - if (hash->length != (CONFLENGTH+RSA_MD4_CKSUM_LENGTH)) { -#ifdef KRB5int_MD4DES_BETA5_COMPAT - if (hash->length != RSA_MD4_CKSUM_LENGTH) - return(KRB5_CRYPTO_INTERNAL); - else - compathash = 1; -#else - return(KRB5_CRYPTO_INTERNAL); -#endif - return(KRB5_CRYPTO_INTERNAL); - } - - if (compathash) { - iv.data = malloc(key->keyblock.length); - if (!iv.data) return ENOMEM; - iv.length = key->keyblock.length; - if (key->keyblock.contents) - memcpy(iv.data, key->keyblock.contents, key->keyblock.length); - } else { - ret = mk_xorkey(key, &xorkey); - if (ret) - return ret; - } - - /* decrypt it */ - iov.flags = KRB5_CRYPTO_TYPE_DATA; - iov.data = make_data(plaintext, hash->length); - memcpy(plaintext, hash->data, hash->length); - - if (compathash) { - ret = enc->decrypt(key, &iv, &iov, 1); - zapfree(iv.data, iv.length); - } else { - ret = enc->decrypt(xorkey, NULL, &iov, 1); - krb5_k_free_key(NULL, xorkey); - } - - if (ret) - return ret; - - /* hash the confounder, then the input data */ - - krb5int_MD4Init(&ctx); - if (!compathash) { - krb5int_MD4Update(&ctx, plaintext, CONFLENGTH); - } - krb5int_MD4Update(&ctx, (unsigned char *) input->data, - (unsigned int) input->length); - krb5int_MD4Final(&ctx); - - /* compare the decrypted hash to the computed one */ - - if (!compathash) { - *valid = - (memcmp(plaintext+CONFLENGTH, ctx.digest, RSA_MD4_CKSUM_LENGTH) - == 0); - } else { - *valid = - (memcmp(plaintext, ctx.digest, RSA_MD4_CKSUM_LENGTH) == 0); - } - - memset(plaintext, 0, sizeof(plaintext)); - - return(0); -} - -const struct krb5_keyhash_provider krb5int_keyhash_md4des = { - CONFLENGTH+RSA_MD4_CKSUM_LENGTH, - k5_md4des_hash, - k5_md4des_verify, - NULL, - NULL -}; diff --git a/src/lib/crypto/krb/keyhash_provider/k5_md5des.c b/src/lib/crypto/krb/keyhash_provider/k5_md5des.c deleted file mode 100644 index 25dc61c..0000000 --- a/src/lib/crypto/krb/keyhash_provider/k5_md5des.c +++ /dev/null @@ -1,204 +0,0 @@ -/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -/* - * Copyright (C) 1998 by the FundsXpress, INC. - * - * All rights reserved. - * - * Export of this software from the United States of America may require - * a specific license from the United States Government. It is the - * responsibility of any person or organization contemplating export to - * obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of FundsXpress. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. FundsXpress makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "k5-int.h" -#include "des_int.h" -#include "rsa-md5.h" -#include "keyhash_provider.h" - -#define CONFLENGTH 8 - -/* Force acceptance of krb5-beta5 md5des checksum for now. */ -#define KRB5int_MD5DES_BETA5_COMPAT - -/* des-cbc(xorkey, conf | rsa-md5(conf | data)) */ - -extern struct krb5_enc_provider krb5int_enc_des; - -/* Derive a key by XOR with 0xF0 bytes. */ -static krb5_error_code -mk_xorkey(krb5_key origkey, krb5_key *xorkey) -{ - krb5_error_code retval = 0; - unsigned char xorbytes[8]; - krb5_keyblock xorkeyblock; - size_t i = 0; - - if (origkey->keyblock.length != sizeof(xorbytes)) - return KRB5_CRYPTO_INTERNAL; - memcpy(xorbytes, origkey->keyblock.contents, sizeof(xorbytes)); - for (i = 0; i < sizeof(xorbytes); i++) - xorbytes[i] ^= 0xf0; - - /* Do a shallow copy here. */ - xorkeyblock = origkey->keyblock; - xorkeyblock.contents = xorbytes; - - retval = krb5_k_create_key(0, &xorkeyblock, xorkey); - zap(xorbytes, sizeof(xorbytes)); - return retval; -} - -static krb5_error_code -k5_md5des_hash(krb5_key key, krb5_keyusage usage, const krb5_data *input, - krb5_data *output) -{ - krb5_error_code ret; - krb5_data data; - krb5_MD5_CTX ctx; - unsigned char conf[CONFLENGTH]; - krb5_key xorkey = NULL; - krb5_crypto_iov iov; - struct krb5_enc_provider *enc = &krb5int_enc_des; - - if (output->length != (CONFLENGTH+RSA_MD5_CKSUM_LENGTH)) - return(KRB5_CRYPTO_INTERNAL); - - /* create the confouder */ - - data.length = CONFLENGTH; - data.data = (char *) conf; - if ((ret = krb5_c_random_make_octets(/* XXX */ 0, &data))) - return(ret); - - ret = mk_xorkey(key, &xorkey); - if (ret) - return ret; - - /* hash the confounder, then the input data */ - - krb5int_MD5Init(&ctx); - krb5int_MD5Update(&ctx, conf, CONFLENGTH); - krb5int_MD5Update(&ctx, (unsigned char *) input->data, - (unsigned int) input->length); - krb5int_MD5Final(&ctx); - - /* construct the buffer to be encrypted */ - - memcpy(output->data, conf, CONFLENGTH); - memcpy(output->data+CONFLENGTH, ctx.digest, RSA_MD5_CKSUM_LENGTH); - - iov.flags = KRB5_CRYPTO_TYPE_DATA; - iov.data = *output; - ret = enc->encrypt(xorkey, NULL, &iov, 1); - - krb5_k_free_key(NULL, xorkey); - - return ret; - -} - -static krb5_error_code -k5_md5des_verify(krb5_key key, krb5_keyusage usage, const krb5_data *input, - const krb5_data *hash, krb5_boolean *valid) -{ - krb5_error_code ret; - krb5_MD5_CTX ctx; - unsigned char plaintext[CONFLENGTH+RSA_MD5_CKSUM_LENGTH]; - krb5_key xorkey = NULL; - int compathash = 0; - struct krb5_enc_provider *enc = &krb5int_enc_des; - krb5_data iv; - krb5_crypto_iov iov; - - iv.data = NULL; - iv.length = 0; - - if (key->keyblock.length != 8) - return(KRB5_BAD_KEYSIZE); - - if (hash->length != (CONFLENGTH+RSA_MD5_CKSUM_LENGTH)) { -#ifdef KRB5int_MD5DES_BETA5_COMPAT - if (hash->length != RSA_MD5_CKSUM_LENGTH) - return(KRB5_CRYPTO_INTERNAL); - else - compathash = 1; -#else - return(KRB5_CRYPTO_INTERNAL); -#endif - } - - if (compathash) { - iv.data = malloc(key->keyblock.length); - if (!iv.data) return ENOMEM; - iv.length = key->keyblock.length; - if (key->keyblock.contents) - memcpy(iv.data, key->keyblock.contents, key->keyblock.length); - } else { - ret = mk_xorkey(key, &xorkey); - if (ret) - return ret; - } - - /* decrypt it */ - iov.flags = KRB5_CRYPTO_TYPE_DATA; - iov.data = make_data(plaintext, hash->length); - memcpy(plaintext, hash->data, hash->length); - - if (!compathash) { - ret = enc->decrypt(xorkey, NULL, &iov, 1); - krb5_k_free_key(NULL, xorkey); - } else { - ret = enc->decrypt(key, &iv, &iov, 1); - zap(iv.data, iv.length); - free(iv.data); - } - - if (ret) return(ret); - - /* hash the confounder, then the input data */ - - krb5int_MD5Init(&ctx); - if (!compathash) { - krb5int_MD5Update(&ctx, plaintext, CONFLENGTH); - } - krb5int_MD5Update(&ctx, (unsigned char *) input->data, - (unsigned) input->length); - krb5int_MD5Final(&ctx); - - /* compare the decrypted hash to the computed one */ - - if (!compathash) { - *valid = - (memcmp(plaintext+CONFLENGTH, ctx.digest, RSA_MD5_CKSUM_LENGTH) - == 0); - } else { - *valid = - (memcmp(plaintext, ctx.digest, RSA_MD5_CKSUM_LENGTH) == 0); - } - memset(plaintext, 0, sizeof(plaintext)); - - return(0); -} - -const struct krb5_keyhash_provider krb5int_keyhash_md5des = { - CONFLENGTH+RSA_MD5_CKSUM_LENGTH, - k5_md5des_hash, - k5_md5des_verify, - NULL, - NULL -}; diff --git a/src/lib/crypto/krb/keyhash_provider/keyhash_provider.h b/src/lib/crypto/krb/keyhash_provider/keyhash_provider.h deleted file mode 100644 index 0eb940f..0000000 --- a/src/lib/crypto/krb/keyhash_provider/keyhash_provider.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -/* - * Copyright (C) 1998 by the FundsXpress, INC. - * - * All rights reserved. - * - * Export of this software from the United States of America may require - * a specific license from the United States Government. It is the - * responsibility of any person or organization contemplating export to - * obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of FundsXpress. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. FundsXpress makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "k5-int.h" - -extern const struct krb5_keyhash_provider krb5int_keyhash_descbc; -extern const struct krb5_keyhash_provider krb5int_keyhash_md4des; -extern const struct krb5_keyhash_provider krb5int_keyhash_md5des; -extern const struct krb5_keyhash_provider krb5int_keyhash_hmac_md5; -extern const struct krb5_keyhash_provider krb5int_keyhash_md5_hmac; diff --git a/src/lib/crypto/krb/make_checksum.c b/src/lib/crypto/krb/make_checksum.c index 2a0ede1..aa45457 100644 --- a/src/lib/crypto/krb/make_checksum.c +++ b/src/lib/crypto/krb/make_checksum.c @@ -35,81 +35,43 @@ krb5_k_make_checksum(krb5_context context, krb5_cksumtype cksumtype, krb5_key key, krb5_keyusage usage, const krb5_data *input, krb5_checksum *cksum) { - unsigned int i; const struct krb5_cksumtypes *ctp; - const struct krb5_keytypes *ktp1, *ktp2; - const struct krb5_keyhash_provider *keyhash; krb5_crypto_iov iov; - krb5_data data; + krb5_data cksum_data; krb5_octet *trunc; krb5_error_code ret; - size_t cksumlen; - iov.flags = KRB5_CRYPTO_TYPE_DATA; - iov.data = *input; - - for (i = 0; i < krb5int_cksumtypes_length; i++) { - if (krb5int_cksumtypes_list[i].ctype == cksumtype) - break; - } - if (i == krb5int_cksumtypes_length) + ctp = find_cksumtype(cksumtype); + if (ctp == NULL) return KRB5_BAD_ENCTYPE; - ctp = &krb5int_cksumtypes_list[i]; - - if (ctp->keyhash != NULL) - cksumlen = ctp->keyhash->hashsize; - else - cksumlen = ctp->hash->hashsize; - - cksum->length = cksumlen; - cksum->contents = malloc(cksum->length); - if (cksum->contents == NULL) - return ENOMEM; - data = make_data(cksum->contents, cksum->length); + ret = verify_key(ctp, key); + if (ret != 0) + return ret; - if (ctp->keyhash) { - /* check if key is compatible */ - if (ctp->keyed_etype) { - ktp1 = find_enctype(ctp->keyed_etype); - ktp2 = key ? find_enctype(key->keyblock.enctype) : NULL; - if (ktp1 == NULL || ktp2 == NULL || ktp1->enc != ktp2->enc) { - ret = KRB5_BAD_ENCTYPE; - goto cleanup; - } - } + ret = alloc_data(&cksum_data, ctp->compute_size); + if (ret != 0) + return ret; - keyhash = ctp->keyhash; - if (keyhash->hash == NULL) { - assert(keyhash->hash_iov != NULL); - ret = (*keyhash->hash_iov)(key, usage, &iov, 1, &data); - } else { - ret = (*keyhash->hash)(key, usage, input, &data); - } - } else if (ctp->flags & KRB5_CKSUMFLAG_DERIVE) { - ret = krb5int_dk_make_checksum(ctp->hash, key, usage, &iov, 1, &data); - } else { - /* No key is used. */ - ret = ctp->hash->hash(&iov, 1, &data); - } + iov.flags = KRB5_CRYPTO_TYPE_DATA; + iov.data = *input; + ret = ctp->checksum(ctp, key, usage, &iov, 1, &cksum_data); + if (ret != 0) + goto cleanup; - if (!ret) { - cksum->magic = KV5M_CHECKSUM; - cksum->checksum_type = cksumtype; - if (ctp->trunc_size) { - cksum->length = ctp->trunc_size; - trunc = realloc(cksum->contents, cksum->length); - if (trunc) - cksum->contents = trunc; - } + cksum->magic = KV5M_CHECKSUM; + cksum->checksum_type = cksumtype; + cksum->length = ctp->output_size; + cksum->contents = (krb5_octet *) cksum_data.data; + cksum_data.data = NULL; + if (ctp->output_size < ctp->compute_size) { + trunc = realloc(cksum->contents, ctp->output_size); + if (trunc != NULL) + cksum->contents = trunc; } cleanup: - if (ret) { - zapfree(cksum->contents, cksum->length); - cksum->contents = NULL; - } - + zapfree(cksum_data.data, ctp->compute_size); return ret; } diff --git a/src/lib/crypto/krb/make_checksum_iov.c b/src/lib/crypto/krb/make_checksum_iov.c index 9ac70f5..dcffa48 100644 --- a/src/lib/crypto/krb/make_checksum_iov.c +++ b/src/lib/crypto/krb/make_checksum_iov.c @@ -37,50 +37,37 @@ krb5_k_make_checksum_iov(krb5_context context, krb5_crypto_iov *data, size_t num_data) { - unsigned int i; - size_t cksumlen; krb5_error_code ret; krb5_data cksum_data; krb5_crypto_iov *checksum; const struct krb5_cksumtypes *ctp; - for (i = 0; i < krb5int_cksumtypes_length; i++) { - if (krb5int_cksumtypes_list[i].ctype == cksumtype) - break; - } - if (i == krb5int_cksumtypes_length) + ctp = find_cksumtype(cksumtype); + if (ctp == NULL) return KRB5_BAD_ENCTYPE; - ctp = &krb5int_cksumtypes_list[i]; - if (ctp->keyhash != NULL) - cksum_data.length = ctp->keyhash->hashsize; - else - cksum_data.length = ctp->hash->hashsize; - - if (ctp->trunc_size != 0) - cksumlen = ctp->trunc_size; - else - cksumlen = cksum_data.length; + ret = verify_key(ctp, key); + if (ret != 0) + return ret; checksum = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_CHECKSUM); - if (checksum == NULL || checksum->data.length < cksumlen) + if (checksum == NULL || checksum->data.length < ctp->output_size) return(KRB5_BAD_MSIZE); - cksum_data.data = malloc(cksum_data.length); - if (cksum_data.data == NULL) - return(ENOMEM); + ret = alloc_data(&cksum_data, ctp->compute_size); + if (ret != 0) + return ret; - ret = krb5int_c_make_checksum_iov(&krb5int_cksumtypes_list[i], - key, usage, data, num_data, - &cksum_data); - if (ret == 0) { - memcpy(checksum->data.data, cksum_data.data, cksumlen); - checksum->data.length = cksumlen; - } + ret = ctp->checksum(ctp, key, usage, data, num_data, &cksum_data); + if (ret != 0) + goto cleanup; - free(cksum_data.data); + memcpy(checksum->data.data, cksum_data.data, ctp->output_size); + checksum->data.length = ctp->output_size; - return(ret); +cleanup: + zapfree(cksum_data.data, ctp->compute_size); + return ret; } krb5_error_code KRB5_CALLCONV diff --git a/src/lib/crypto/krb/valid_cksumtype.c b/src/lib/crypto/krb/valid_cksumtype.c index a701efc..07b84fe 100644 --- a/src/lib/crypto/krb/valid_cksumtype.c +++ b/src/lib/crypto/krb/valid_cksumtype.c @@ -31,12 +31,10 @@ krb5_boolean KRB5_CALLCONV krb5_c_valid_cksumtype(krb5_cksumtype ctype) { - unsigned int i; + const struct krb5_cksumtypes *ctp; - for (i = 0; i < krb5int_cksumtypes_length; i++) { - if (krb5int_cksumtypes_list[i].ctype == ctype) - return TRUE; - } - - return FALSE; + ctp = find_cksumtype(ctype); + if (ctp == NULL) + return FALSE; + return TRUE; } diff --git a/src/lib/crypto/krb/verify_checksum.c b/src/lib/crypto/krb/verify_checksum.c index 177c5eb..cb19c23 100644 --- a/src/lib/crypto/krb/verify_checksum.c +++ b/src/lib/crypto/krb/verify_checksum.c @@ -33,58 +33,39 @@ krb5_k_verify_checksum(krb5_context context, krb5_key key, krb5_keyusage usage, const krb5_data *data, const krb5_checksum *cksum, krb5_boolean *valid) { - unsigned int i; const struct krb5_cksumtypes *ctp; - const struct krb5_keyhash_provider *keyhash; - size_t hashsize; + krb5_crypto_iov iov; krb5_error_code ret; - krb5_data indata; + krb5_data cksum_data; krb5_checksum computed; - for (i=0; i<krb5int_cksumtypes_length; i++) { - if (krb5int_cksumtypes_list[i].ctype == cksum->checksum_type) - break; - } - if (i == krb5int_cksumtypes_length) + iov.flags = KRB5_CRYPTO_TYPE_DATA; + iov.data = *data; + + ctp = find_cksumtype(cksum->checksum_type); + if (ctp == NULL) return KRB5_BAD_ENCTYPE; - ctp = &krb5int_cksumtypes_list[i]; - indata.length = cksum->length; - indata.data = (char *) cksum->contents; + ret = verify_key(ctp, key); + if (ret != 0) + return ret; /* If there's actually a verify function, call it. */ - if (ctp->keyhash) { - keyhash = ctp->keyhash; - - if (keyhash->verify == NULL && keyhash->verify_iov != NULL) { - krb5_crypto_iov iov[1]; - - iov[0].flags = KRB5_CRYPTO_TYPE_DATA; - iov[0].data.data = data->data; - iov[0].data.length = data->length; - - return (*keyhash->verify_iov)(key, usage, iov, 1, &indata, valid); - } else if (keyhash->verify != NULL) { - return (*keyhash->verify)(key, usage, data, &indata, valid); - } - } + cksum_data = make_data(cksum->contents, cksum->length); + if (ctp->verify != NULL) + return ctp->verify(ctp, key, usage, &iov, 1, &cksum_data, valid); /* Otherwise, make the checksum again, and compare. */ - ret = krb5_c_checksum_length(context, cksum->checksum_type, &hashsize); - if (ret) - return ret; - - if (cksum->length != hashsize) + if (cksum->length != ctp->output_size) return KRB5_BAD_MSIZE; - computed.length = hashsize; - ret = krb5_k_make_checksum(context, cksum->checksum_type, key, usage, data, &computed); if (ret) return ret; - *valid = (memcmp(computed.contents, cksum->contents, hashsize) == 0); + *valid = (memcmp(computed.contents, cksum->contents, + ctp->output_size) == 0); free(computed.contents); return 0; diff --git a/src/lib/crypto/krb/verify_checksum_iov.c b/src/lib/crypto/krb/verify_checksum_iov.c index e0af46c..0934ae5 100644 --- a/src/lib/crypto/krb/verify_checksum_iov.c +++ b/src/lib/crypto/krb/verify_checksum_iov.c @@ -38,62 +38,42 @@ krb5_k_verify_checksum_iov(krb5_context context, size_t num_data, krb5_boolean *valid) { - unsigned int i; const struct krb5_cksumtypes *ctp; - size_t cksumlen; krb5_error_code ret; krb5_data computed; krb5_crypto_iov *checksum; - for (i = 0; i < krb5int_cksumtypes_length; i++) { - if (krb5int_cksumtypes_list[i].ctype == checksum_type) - break; - } - if (i == krb5int_cksumtypes_length) + ctp = find_cksumtype(checksum_type); + if (ctp == NULL) return KRB5_BAD_ENCTYPE; - ctp = &krb5int_cksumtypes_list[i]; + + ret = verify_key(ctp, key); + if (ret != 0) + return ret; checksum = krb5int_c_locate_iov((krb5_crypto_iov *)data, num_data, KRB5_CRYPTO_TYPE_CHECKSUM); - if (checksum == NULL) - return(KRB5_BAD_MSIZE); + if (checksum == NULL || checksum->data.length != ctp->output_size) + return KRB5_BAD_MSIZE; /* If there's actually a verify function, call it. */ - if (ctp->keyhash && ctp->keyhash->verify_iov) { - return (*ctp->keyhash->verify_iov)(key, usage, data, num_data, - &checksum->data, valid); + if (ctp->verify != NULL) { + return ctp->verify(ctp, key, usage, data, num_data, &checksum->data, + valid); } - /* Otherwise, make the checksum again, and compare. */ - if (ctp->keyhash != NULL) - computed.length = ctp->keyhash->hashsize; - else - computed.length = ctp->hash->hashsize; - - if (ctp->trunc_size != 0) - cksumlen = ctp->trunc_size; - else - cksumlen = computed.length; - - if (checksum->data.length != cksumlen) - return KRB5_BAD_MSIZE; - - computed.data = malloc(computed.length); - if (computed.data == NULL) - return ENOMEM; - - ret = krb5int_c_make_checksum_iov(&krb5int_cksumtypes_list[i], key, usage, - data, num_data, &computed); - if (ret) { - free(computed.data); + ret = alloc_data(&computed, ctp->compute_size); + if (ret != 0) return ret; - } - *valid = (computed.length == cksumlen) && - (memcmp(computed.data, checksum->data.data, cksumlen) == 0); + ret = ctp->checksum(ctp, key, usage, data, num_data, &computed); + if (ret == 0) { + *valid = (memcmp(computed.data, checksum->data.data, + ctp->output_size) == 0); + } - free(computed.data); - return 0; + zapfree(computed.data, ctp->compute_size); + return ret; } krb5_error_code KRB5_CALLCONV diff --git a/src/lib/crypto/libk5crypto.exports b/src/lib/crypto/libk5crypto.exports index bc31c30..b6d7353 100644 --- a/src/lib/crypto/libk5crypto.exports +++ b/src/lib/crypto/libk5crypto.exports @@ -83,8 +83,6 @@ krb5_k_prf krb5_k_reference_key krb5_k_verify_checksum krb5_k_verify_checksum_iov -krb5int_keyhash_md4des -krb5int_keyhash_md5des mit_crc32 krb5int_aes_encrypt krb5int_MD4Init diff --git a/src/lib/crypto/openssl/enc_provider/aes.c b/src/lib/crypto/openssl/enc_provider/aes.c index 51bf5ce..7ba1f52 100644 --- a/src/lib/crypto/openssl/enc_provider/aes.c +++ b/src/lib/crypto/openssl/enc_provider/aes.c @@ -285,7 +285,7 @@ krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec, if (nblocks == 1) { if (input_length != BLOCK_SIZE) return KRB5_BAD_MSIZE; - ret = cbc_enc(key, ivec, data, num_data); + ret = cbc_decr(key, ivec, data, num_data); } else if (nblocks > 1) { ret = cts_decr(key, ivec, data, num_data, input_length); } @@ -309,6 +309,7 @@ const struct krb5_enc_provider krb5int_enc_aes128 = { 16, 16, krb5int_aes_encrypt, krb5int_aes_decrypt, + NULL, krb5int_aes_make_key, krb5int_aes_init_state, krb5int_default_free_state @@ -319,6 +320,7 @@ const struct krb5_enc_provider krb5int_enc_aes256 = { 32, 32, krb5int_aes_encrypt, krb5int_aes_decrypt, + NULL, krb5int_aes_make_key, krb5int_aes_init_state, krb5int_default_free_state diff --git a/src/lib/crypto/openssl/enc_provider/des.c b/src/lib/crypto/openssl/enc_provider/des.c index 59030f8..a1a5245 100644 --- a/src/lib/crypto/openssl/enc_provider/des.c +++ b/src/lib/crypto/openssl/enc_provider/des.c @@ -187,6 +187,7 @@ const struct krb5_enc_provider krb5int_enc_des = { DES_KEY_BYTES, KRB5_MIT_DES_KEYSIZE, k5_des_encrypt, k5_des_decrypt, + NULL, krb5int_des_make_key, krb5int_des_init_state, krb5int_default_free_state diff --git a/src/lib/crypto/openssl/enc_provider/des3.c b/src/lib/crypto/openssl/enc_provider/des3.c index 832eff9..3f0d213 100644 --- a/src/lib/crypto/openssl/enc_provider/des3.c +++ b/src/lib/crypto/openssl/enc_provider/des3.c @@ -193,6 +193,7 @@ const struct krb5_enc_provider krb5int_enc_des3 = { KRB5_MIT_DES3_KEY_BYTES, KRB5_MIT_DES3_KEYSIZE, k5_des3_encrypt, k5_des3_decrypt, + NULL, krb5int_des3_make_key, krb5int_des_init_state, krb5int_default_free_state diff --git a/src/lib/crypto/openssl/enc_provider/rc4.c b/src/lib/crypto/openssl/enc_provider/rc4.c index 51cd350..7ce9436 100644 --- a/src/lib/crypto/openssl/enc_provider/rc4.c +++ b/src/lib/crypto/openssl/enc_provider/rc4.c @@ -145,6 +145,7 @@ const struct krb5_enc_provider krb5int_enc_arcfour = { RC4_KEY_SIZE, RC4_KEY_SIZE, k5_arcfour_docrypt, k5_arcfour_docrypt, + NULL, krb5int_arcfour_make_key, k5_arcfour_init_state, /*xxx not implemented */ k5_arcfour_free_state /*xxx not implemented */ |