static krb5_error_code validate_and_schedule(krb5_key key, const krb5_data *ivec, const krb5_crypto_iov *data, size_t num_data, mit_des_key_schedule schedule) { size_t i, input_length; 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 (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: return(KRB5DES_BAD_KEYPAR); case -2: return(KRB5DES_WEAK_KEY); } return 0; }
static krb5_error_code k5_des_docrypt_iov(const krb5_keyblock *key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data, int enc) { mit_des_key_schedule schedule; size_t input_length = 0; unsigned int i; /* key->enctype was checked by the caller */ if (key->length != 8) return(KRB5_BAD_KEYSIZE); for (i = 0; i < num_data; i++) { const krb5_crypto_iov *iov = &data[i]; if (ENCRYPT_DATA_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); switch (mit_des_key_sched(key->contents, schedule)) { case -1: return(KRB5DES_BAD_KEYPAR); case -2: return(KRB5DES_WEAK_KEY); } /* this has a return value, but the code always returns zero */ if (enc) krb5int_des_cbc_encrypt_iov(data, num_data, schedule, ivec ? ivec->data : NULL); else krb5int_des_cbc_decrypt_iov(data, num_data, schedule, ivec ? ivec->data : NULL); memset(schedule, 0, sizeof(schedule)); return(0); }
static krb5_error_code k5_des_docrypt(const krb5_keyblock *key, const krb5_data *ivec, const krb5_data *input, krb5_data *output, int enc) { mit_des_key_schedule schedule; /* key->enctype was checked by the caller */ if (key->length != 8) return(KRB5_BAD_KEYSIZE); if ((input->length%8) != 0) return(KRB5_BAD_MSIZE); if (ivec && (ivec->length != 8)) return(KRB5_BAD_MSIZE); if (input->length != output->length) return(KRB5_BAD_MSIZE); switch (mit_des_key_sched(key->contents, schedule)) { case -1: return(KRB5DES_BAD_KEYPAR); case -2: return(KRB5DES_WEAK_KEY); } /* this has a return value, but the code always returns zero */ mit_des_cbc_encrypt((krb5_pointer) input->data, (krb5_pointer) output->data, input->length, schedule, (ivec ? (const unsigned char *) ivec->data : (const unsigned char *) mit_des_zeroblock), enc); memset(schedule, 0, sizeof(schedule)); return(0); }
static krb5_error_code k5_md4des_hash(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { krb5_error_code ret; krb5_data data; krb5_MD4_CTX ctx; unsigned char conf[CONFLENGTH]; unsigned char xorkey[8]; unsigned int i; mit_des_key_schedule schedule; if (key->length != 8) return(KRB5_BAD_KEYSIZE); if (ivec) return(KRB5_CRYPTO_INTERNAL); 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); /* create and schedule the encryption key */ memcpy(xorkey, key->contents, sizeof(xorkey)); for (i=0; i<sizeof(xorkey); i++) xorkey[i] ^= 0xf0; switch (ret = mit_des_key_sched(xorkey, schedule)) { case -1: return(KRB5DES_BAD_KEYPAR); case -2: return(KRB5DES_WEAK_KEY); } /* hash the confounder, then the input data */ krb5_MD4Init(&ctx); krb5_MD4Update(&ctx, conf, CONFLENGTH); krb5_MD4Update(&ctx, (unsigned char *) input->data, (unsigned int) input->length); krb5_MD4Final(&ctx); /* construct the buffer to be encrypted */ memcpy(output->data, conf, CONFLENGTH); memcpy(output->data+CONFLENGTH, ctx.digest, RSA_MD4_CKSUM_LENGTH); /* encrypt it, in place. this has a return value, but it's always zero. */ mit_des_cbc_encrypt((krb5_pointer) output->data, (krb5_pointer) output->data, output->length, schedule, (const unsigned char *) mit_des_zeroblock, 1); return(0); }
static krb5_error_code k5_md4des_verify(const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *ivec, const krb5_data *input, const krb5_data *hash, krb5_boolean *valid) { krb5_MD4_CTX ctx; unsigned char plaintext[CONFLENGTH+RSA_MD4_CKSUM_LENGTH]; unsigned char xorkey[8]; unsigned int i; mit_des_key_schedule schedule; int compathash = 0; if (key->length != 8) return(KRB5_BAD_KEYSIZE); if (ivec) return(KRB5_CRYPTO_INTERNAL); if (hash->length != (CONFLENGTH+RSA_MD4_CKSUM_LENGTH)) { #ifdef KRB5_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); } /* create and schedule the encryption key */ memcpy(xorkey, key->contents, sizeof(xorkey)); if (!compathash) { for (i=0; i<sizeof(xorkey); i++) xorkey[i] ^= 0xf0; } switch (mit_des_key_sched(xorkey, schedule)) { case -1: return(KRB5DES_BAD_KEYPAR); case -2: return(KRB5DES_WEAK_KEY); } /* decrypt it. this has a return value, but it's always zero. */ if (!compathash) { mit_des_cbc_encrypt((krb5_pointer) hash->data, (krb5_pointer) plaintext, hash->length, schedule, (const unsigned char *) mit_des_zeroblock, 0); } else { mit_des_cbc_encrypt((krb5_pointer) hash->data, (krb5_pointer) plaintext, hash->length, schedule, xorkey, 0); } /* hash the confounder, then the input data */ krb5_MD4Init(&ctx); if (!compathash) { krb5_MD4Update(&ctx, plaintext, CONFLENGTH); } krb5_MD4Update(&ctx, (unsigned char *) input->data, (unsigned int) input->length); krb5_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); }