2 * Copyright (C) 2008 by the Massachusetts Institute of Technology.
3 * Copyright 1995 by Richard P. Basch. All Rights Reserved.
4 * Copyright 1995 by Lehman Brothers, Inc. All Rights Reserved.
6 * Export of this software from the United States of America may
7 * require a specific license from the United States Government.
8 * It is the responsibility of any person or organization contemplating
9 * export to obtain such a license before exporting.
11 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
12 * distribute this software and its documentation for any purpose and
13 * without fee is hereby granted, provided that the above copyright
14 * notice appear in all copies and that both that copyright notice and
15 * this permission notice appear in supporting documentation, and that
16 * the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used
17 * in advertising or publicity pertaining to distribution of the software
18 * without specific, written prior permission. Richard P. Basch,
19 * Lehman Brothers and M.I.T. make no representations about the suitability
20 * of this software for any purpose. It is provided "as is" without
21 * express or implied warranty.
29 krb5int_des3_cbc_encrypt_iov(krb5_crypto_iov *data,
30 unsigned long num_data,
31 const mit_des_key_schedule ks1,
32 const mit_des_key_schedule ks2,
33 const mit_des_key_schedule ks3,
36 unsigned DES_INT32 left, right;
37 const unsigned DES_INT32 *kp1, *kp2, *kp3;
38 const unsigned char *ip;
40 struct iov_block_state input_pos, output_pos;
41 unsigned char iblock[MIT_DES_BLOCK_LENGTH];
42 unsigned char oblock[MIT_DES_BLOCK_LENGTH];
44 IOV_BLOCK_STATE_INIT(&input_pos);
45 IOV_BLOCK_STATE_INIT(&output_pos);
48 * Get key pointer here. This won't need to be reinitialized
50 kp1 = (const unsigned DES_INT32 *)ks1;
51 kp2 = (const unsigned DES_INT32 *)ks2;
52 kp3 = (const unsigned DES_INT32 *)ks3;
55 * Initialize left and right with the contents of the initial
61 ip = mit_des_zeroblock;
62 GET_HALF_BLOCK(left, ip);
63 GET_HALF_BLOCK(right, ip);
66 * Suitably initialized, now work the length down 8 bytes
70 unsigned DES_INT32 temp;
75 if (!krb5int_c_iov_get_block(iblock, MIT_DES_BLOCK_LENGTH, data, num_data, &input_pos))
78 GET_HALF_BLOCK(temp, ip);
80 GET_HALF_BLOCK(temp, ip);
84 * Encrypt what we have
86 DES_DO_ENCRYPT(left, right, kp1);
87 DES_DO_DECRYPT(left, right, kp2);
88 DES_DO_ENCRYPT(left, right, kp3);
91 * Copy the results out
93 PUT_HALF_BLOCK(left, op);
94 PUT_HALF_BLOCK(right, op);
96 krb5int_c_iov_put_block(data, num_data, oblock, MIT_DES_BLOCK_LENGTH, &output_pos);
100 memcpy(ivec, oblock, MIT_DES_BLOCK_LENGTH);
104 krb5int_des3_cbc_decrypt_iov(krb5_crypto_iov *data,
105 unsigned long num_data,
106 const mit_des_key_schedule ks1,
107 const mit_des_key_schedule ks2,
108 const mit_des_key_schedule ks3,
111 unsigned DES_INT32 left, right;
112 const unsigned DES_INT32 *kp1, *kp2, *kp3;
113 const unsigned char *ip;
114 unsigned DES_INT32 ocipherl, ocipherr;
115 unsigned DES_INT32 cipherl, cipherr;
117 struct iov_block_state input_pos, output_pos;
118 unsigned char iblock[MIT_DES_BLOCK_LENGTH];
119 unsigned char oblock[MIT_DES_BLOCK_LENGTH];
121 IOV_BLOCK_STATE_INIT(&input_pos);
122 IOV_BLOCK_STATE_INIT(&output_pos);
125 * Get key pointer here. This won't need to be reinitialized
127 kp1 = (const unsigned DES_INT32 *)ks1;
128 kp2 = (const unsigned DES_INT32 *)ks2;
129 kp3 = (const unsigned DES_INT32 *)ks3;
132 * Decrypting is harder than encrypting because of
133 * the necessity of remembering a lot more things.
134 * Should think about this a little more...
141 * Prime the old cipher with ivec.
146 ip = mit_des_zeroblock;
147 GET_HALF_BLOCK(ocipherl, ip);
148 GET_HALF_BLOCK(ocipherr, ip);
151 * Now do this in earnest until we run out of length.
155 * Read a block from the input into left and
156 * right. Save this cipher block for later.
159 if (!krb5int_c_iov_get_block(iblock, MIT_DES_BLOCK_LENGTH, data, num_data, &input_pos))
165 GET_HALF_BLOCK(left, ip);
166 GET_HALF_BLOCK(right, ip);
173 DES_DO_DECRYPT(left, right, kp3);
174 DES_DO_ENCRYPT(left, right, kp2);
175 DES_DO_DECRYPT(left, right, kp1);
178 * Xor with the old cipher to get plain
179 * text. Output 8 or less bytes of this.
184 PUT_HALF_BLOCK(left, op);
185 PUT_HALF_BLOCK(right, op);
188 * Save current cipher block here
193 krb5int_c_iov_put_block(data, num_data, oblock, MIT_DES_BLOCK_LENGTH, &output_pos);
197 memcpy(ivec, oblock, MIT_DES_BLOCK_LENGTH);