Ejemplo n.º 1
0
void
krb5int_des_cbc_decrypt(const mit_des_cblock *in,
			mit_des_cblock *out,
			unsigned long length,
			const mit_des_key_schedule schedule,
			const mit_des_cblock ivec)
{
	unsigned DES_INT32 left, right;
	const unsigned DES_INT32 *kp;
	const unsigned char *ip;
	unsigned char *op;
	unsigned DES_INT32 ocipherl, ocipherr;
	unsigned DES_INT32 cipherl, cipherr;

	/*
	 * Get key pointer here.  This won't need to be reinitialized
	 */
	kp = (const unsigned DES_INT32 *)schedule;

	/*
	 * Decrypting is harder than encrypting because of
	 * the necessity of remembering a lot more things.
	 * Should think about this a little more...
	 */

	if (length <= 0)
		return;

	/*
	 * Prime the old cipher with ivec.
	 */
	ip = ivec;
	GET_HALF_BLOCK(ocipherl, ip);
	GET_HALF_BLOCK(ocipherr, ip);

	/*
	 * Now do this in earnest until we run out of length.
	 */
	ip = *in;
	op = *out;
	for (;;) {		/* check done inside loop */
		/*
		 * Read a block from the input into left and
		 * right.  Save this cipher block for later.
		 */
		GET_HALF_BLOCK(left, ip);
		GET_HALF_BLOCK(right, ip);
		cipherl = left;
		cipherr = right;

		/*
		 * Decrypt this.
		 */
		DES_DO_DECRYPT(left, right, kp);

		/*
		 * Xor with the old cipher to get plain
		 * text.  Output 8 or less bytes of this.
		 */
		left ^= ocipherl;
		right ^= ocipherr;
		if (length > 8) {
			length -= 8;
			PUT_HALF_BLOCK(left, op);
			PUT_HALF_BLOCK(right, op);
			/*
			 * Save current cipher block here
			 */
			ocipherl = cipherl;
			ocipherr = cipherr;
		} else {
			/*
			 * Trouble here.  Start at end of output,
			 * work backwards.
			 */
			op += (int) length;
			switch(length) {
			case 8:
				*(--op) = (unsigned char) (right & 0xff);
			case 7:
				*(--op) = (unsigned char) ((right >> 8) & 0xff);
			case 6:
				*(--op) = (unsigned char) ((right >> 16) & 0xff);
			case 5:
				*(--op) = (unsigned char) ((right >> 24) & 0xff);
			case 4:
				*(--op) = (unsigned char) (left & 0xff);
			case 3:
				*(--op) = (unsigned char) ((left >> 8) & 0xff);
			case 2:
				*(--op) = (unsigned char) ((left >> 16) & 0xff);
			case 1:
				*(--op) = (unsigned char) ((left >> 24) & 0xff);
				break;
			}
			break;		/* we're done */
		}
	}
}
Ejemplo n.º 2
0
void
krb5int_des3_cbc_decrypt_iov(krb5_crypto_iov *data,
			     unsigned long num_data,
			     const mit_des_key_schedule ks1,
			     const mit_des_key_schedule ks2,
			     const mit_des_key_schedule ks3,
			     mit_des_cblock ivec)
{
    unsigned DES_INT32 left, right;
    const unsigned DES_INT32 *kp1, *kp2, *kp3;
    const unsigned char *ip;
    unsigned DES_INT32 ocipherl, ocipherr;
    unsigned DES_INT32 cipherl, cipherr;
    unsigned char *op;
    struct iov_block_state input_pos, output_pos;
    unsigned char iblock[MIT_DES_BLOCK_LENGTH];
    unsigned char oblock[MIT_DES_BLOCK_LENGTH];

    IOV_BLOCK_STATE_INIT(&input_pos);
    IOV_BLOCK_STATE_INIT(&output_pos);

    /*
     * Get key pointer here.  This won't need to be reinitialized
     */
    kp1 = (const unsigned DES_INT32 *)ks1;
    kp2 = (const unsigned DES_INT32 *)ks2;
    kp3 = (const unsigned DES_INT32 *)ks3;

    /*
     * Decrypting is harder than encrypting because of
     * the necessity of remembering a lot more things.
     * Should think about this a little more...
     */

    if (num_data == 0)
	return;

    /*
     * Prime the old cipher with ivec.
     */
    if (ivec != NULL)
	ip = ivec;
    else
	ip = mit_des_zeroblock;
    GET_HALF_BLOCK(ocipherl, ip);
    GET_HALF_BLOCK(ocipherr, ip);

    /*
     * Now do this in earnest until we run out of length.
     */
    for (;;) {
	/*
	 * Read a block from the input into left and
	 * right.  Save this cipher block for later.
	 */

	if (!krb5int_c_iov_get_block(iblock, MIT_DES_BLOCK_LENGTH, data, num_data, &input_pos))
	    break;

	if (input_pos.iov_pos == num_data)
	    break;

	ip = iblock;
	op = oblock;

	GET_HALF_BLOCK(left, ip);
	GET_HALF_BLOCK(right, ip);
	cipherl = left;
	cipherr = right;

	/*
	 * Decrypt this.
	 */
	DES_DO_DECRYPT(left, right, kp3);
	DES_DO_ENCRYPT(left, right, kp2);
	DES_DO_DECRYPT(left, right, kp1);

	/*
	 * Xor with the old cipher to get plain
	 * text.  Output 8 or less bytes of this.
	 */
	left ^= ocipherl;
	right ^= ocipherr;

	PUT_HALF_BLOCK(left, op);
	PUT_HALF_BLOCK(right, op);

	/*
	 * Save current cipher block here
	 */
	ocipherl = cipherl;
	ocipherr = cipherr;

	krb5int_c_iov_put_block(data, num_data, oblock, MIT_DES_BLOCK_LENGTH, &output_pos);
    }

    if (ivec != NULL) {
	op = ivec;
	PUT_HALF_BLOCK(ocipherl,op);
	PUT_HALF_BLOCK(ocipherr, op);
    }
}
Ejemplo n.º 3
0
void
krb5int_des3_cbc_encrypt_iov(krb5_crypto_iov *data,
			     unsigned long num_data,
			     const mit_des_key_schedule ks1,
			     const mit_des_key_schedule ks2,
			     const mit_des_key_schedule ks3,
			     mit_des_cblock ivec)
{
    unsigned DES_INT32 left, right;
    const unsigned DES_INT32 *kp1, *kp2, *kp3;
    const unsigned char *ip;
    unsigned char *op;
    struct iov_block_state input_pos, output_pos;
    unsigned char iblock[MIT_DES_BLOCK_LENGTH];
    unsigned char oblock[MIT_DES_BLOCK_LENGTH];

    IOV_BLOCK_STATE_INIT(&input_pos);
    IOV_BLOCK_STATE_INIT(&output_pos);

    /*
     * Get key pointer here.  This won't need to be reinitialized
     */
    kp1 = (const unsigned DES_INT32 *)ks1;
    kp2 = (const unsigned DES_INT32 *)ks2;
    kp3 = (const unsigned DES_INT32 *)ks3;

    /*
     * Initialize left and right with the contents of the initial
     * vector.
     */
    if (ivec != NULL)
	ip = ivec;
    else
	ip = mit_des_zeroblock;
    GET_HALF_BLOCK(left, ip);
    GET_HALF_BLOCK(right, ip);

    /*
     * Suitably initialized, now work the length down 8 bytes
     * at a time.
     */
    for (;;) {
	unsigned DES_INT32 temp;

	ip = iblock;
	op = oblock;

	if (!krb5int_c_iov_get_block(iblock, MIT_DES_BLOCK_LENGTH, data, num_data, &input_pos))
	    break;

	if (input_pos.iov_pos == num_data)
	    break;

	GET_HALF_BLOCK(temp, ip);
	left  ^= temp;
	GET_HALF_BLOCK(temp, ip);
	right ^= temp;

	/*
	 * Encrypt what we have
	 */
	DES_DO_ENCRYPT(left, right, kp1);
	DES_DO_DECRYPT(left, right, kp2);
	DES_DO_ENCRYPT(left, right, kp3);

	/*
	 * Copy the results out
	 */
	PUT_HALF_BLOCK(left, op);
	PUT_HALF_BLOCK(right, op);

	krb5int_c_iov_put_block(data, num_data, oblock, MIT_DES_BLOCK_LENGTH, &output_pos);
    }

    if (ivec != NULL)
	memcpy(ivec, oblock, MIT_DES_BLOCK_LENGTH);
}
Ejemplo n.º 4
0
void
krb5int_des_cbc_decrypt(krb5_crypto_iov *data, unsigned long num_data,
                        const mit_des_key_schedule schedule,
                        mit_des_cblock ivec)
{
    unsigned DES_INT32 left, right;
    const unsigned DES_INT32 *kp;
    const unsigned char *ip;
    unsigned DES_INT32 ocipherl, ocipherr;
    unsigned DES_INT32 cipherl, cipherr;
    struct iov_block_state input_pos, output_pos;
    unsigned char storage[MIT_DES_BLOCK_LENGTH], *block = NULL, *ptr;

    IOV_BLOCK_STATE_INIT(&input_pos);
    IOV_BLOCK_STATE_INIT(&output_pos);

    /* Get key pointer here.  This won't need to be reinitialized. */
    kp = (const unsigned DES_INT32 *)schedule;

    /*
     * Decrypting is harder than encrypting because of
     * the necessity of remembering a lot more things.
     * Should think about this a little more...
     */

    /* Prime the old cipher with ivec. */
    ip = (ivec != NULL) ? ivec : mit_des_zeroblock;
    GET_HALF_BLOCK(ocipherl, ip);
    GET_HALF_BLOCK(ocipherr, ip);

    /* Work the length down 8 bytes at a time. */
    for (;;) {
        if (!krb5int_c_iov_get_block_nocopy(storage, MIT_DES_BLOCK_LENGTH,
                                            data, num_data, &input_pos, &ptr))
            break;
        block = ptr;

        /* Split this block into left and right. */
        GET_HALF_BLOCK(left, ptr);
        GET_HALF_BLOCK(right, ptr);
        cipherl = left;
        cipherr = right;

        /* Decrypt and xor with the old cipher to get plain text. */
        DES_DO_DECRYPT(left, right, kp);
        left ^= ocipherl;
        right ^= ocipherr;

        /* Store the encrypted halves back into block. */
        ptr = block;
        PUT_HALF_BLOCK(left, ptr);
        PUT_HALF_BLOCK(right, ptr);

        /* Save current cipher block halves. */
        ocipherl = cipherl;
        ocipherr = cipherr;

        krb5int_c_iov_put_block_nocopy(data, num_data, storage,
                                       MIT_DES_BLOCK_LENGTH, &output_pos,
                                       block);
    }

    if (ivec != NULL && block != NULL) {
        ptr = ivec;
        PUT_HALF_BLOCK(ocipherl, ptr);
        PUT_HALF_BLOCK(ocipherr, ptr);
    }
}