2 * Copyright (C) 1998 by the FundsXpress, INC.
6 * Export of this software from the United States of America may require
7 * a specific license from the United States Government. It is the
8 * responsibility of any person or organization contemplating export to
9 * 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 FundsXpress. not be used in advertising or publicity pertaining
17 * to distribution of the software without specific, written prior
18 * permission. FundsXpress makes no representations about the suitability of
19 * this software for any purpose. It is provided "as is" without express
20 * or implied warranty.
22 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
24 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30 #define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */
32 static krb5_error_code
33 krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc,
34 const struct krb5_hash_provider *hash,
35 const krb5_keyblock *key,
37 const krb5_data *ivec,
38 const krb5_data *input,
43 krb5_dk_decrypt(enc, hash, key, usage, ivec, input, output)
44 const struct krb5_enc_provider *enc;
45 const struct krb5_hash_provider *hash;
46 const krb5_keyblock *key;
48 const krb5_data *ivec;
49 const krb5_data *input;
52 return krb5_dk_decrypt_maybe_trunc_hmac(enc, hash, key, usage,
53 ivec, input, output, 0);
57 krb5int_aes_dk_decrypt(enc, hash, key, usage, ivec, input, output)
58 const struct krb5_enc_provider *enc;
59 const struct krb5_hash_provider *hash;
60 const krb5_keyblock *key;
62 const krb5_data *ivec;
63 const krb5_data *input;
66 return krb5_dk_decrypt_maybe_trunc_hmac(enc, hash, key, usage,
67 ivec, input, output, 96 / 8);
70 static krb5_error_code
71 krb5_dk_decrypt_maybe_trunc_hmac(enc, hash, key, usage, ivec, input, output,
73 const struct krb5_enc_provider *enc;
74 const struct krb5_hash_provider *hash;
75 const krb5_keyblock *key;
77 const krb5_data *ivec;
78 const krb5_data *input;
83 size_t hashsize, blocksize, keybytes, keylength, enclen, plainlen;
84 unsigned char *plaindata, *kedata, *kidata, *cksum, *cn;
87 unsigned char constantdata[K5CLENGTH];
89 /* allocate and set up ciphertext and to-be-derived keys */
91 (*(hash->hash_size))(&hashsize);
92 (*(enc->block_size))(&blocksize);
93 (*(enc->keysize))(&keybytes, &keylength);
97 else if (hmacsize > hashsize)
98 return KRB5KRB_AP_ERR_BAD_INTEGRITY;
100 enclen = input->length - hmacsize;
102 if ((kedata = (unsigned char *) malloc(keylength)) == NULL)
104 if ((kidata = (unsigned char *) malloc(keylength)) == NULL) {
108 if ((plaindata = (unsigned char *) malloc(enclen)) == NULL) {
113 if ((cksum = (unsigned char *) malloc(hashsize)) == NULL) {
120 ke.contents = kedata;
121 ke.length = keylength;
122 ki.contents = kidata;
123 ki.length = keylength;
125 /* derive the keys */
127 d1.data = (char *) constantdata;
128 d1.length = K5CLENGTH;
130 d1.data[0] = (usage>>24)&0xff;
131 d1.data[1] = (usage>>16)&0xff;
132 d1.data[2] = (usage>>8)&0xff;
133 d1.data[3] = usage&0xff;
135 d1.data[4] = (char) 0xAA;
137 if ((ret = krb5_derive_key(enc, key, &ke, &d1)) != 0)
142 if ((ret = krb5_derive_key(enc, key, &ki, &d1)) != 0)
145 /* decrypt the ciphertext */
148 d1.data = input->data;
151 d2.data = (char *) plaindata;
153 if ((ret = ((*(enc->decrypt))(&ke, ivec, &d1, &d2))) != 0)
156 if (ivec != NULL && ivec->length == blocksize)
157 cn = (unsigned char *) d1.data + d1.length - blocksize;
161 /* verify the hash */
163 d1.length = hashsize;
164 d1.data = (char *) cksum;
166 if ((ret = krb5_hmac(hash, &ki, 1, &d2, &d1)) != 0)
169 if (memcmp(cksum, input->data+enclen, hmacsize) != 0) {
170 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
174 /* because this encoding isn't self-describing wrt length, the
175 best we can do here is to compute the length minus the
178 plainlen = enclen - blocksize;
180 if (output->length < plainlen)
181 return(KRB5_BAD_MSIZE);
183 output->length = plainlen;
185 memcpy(output->data, d2.data+blocksize, output->length);
188 memcpy(ivec->data, cn, blocksize);
193 memset(kedata, 0, keylength);
194 memset(kidata, 0, keylength);
195 memset(plaindata, 0, enclen);
196 memset(cksum, 0, hashsize);
206 #ifdef ATHENA_DES3_KLUDGE
208 krb5_marc_dk_decrypt(enc, hash, key, usage, ivec, input, output)
209 const struct krb5_enc_provider *enc;
210 const struct krb5_hash_provider *hash;
211 const krb5_keyblock *key;
213 const krb5_data *ivec;
214 const krb5_data *input;
218 size_t hashsize, blocksize, keybytes, keylength, enclen, plainlen;
219 unsigned char *plaindata, *kedata, *kidata, *cksum, *cn;
220 krb5_keyblock ke, ki;
222 unsigned char constantdata[K5CLENGTH];
224 /* allocate and set up ciphertext and to-be-derived keys */
226 (*(hash->hash_size))(&hashsize);
227 (*(enc->block_size))(&blocksize);
228 (*(enc->keysize))(&keybytes, &keylength);
230 enclen = input->length - hashsize;
232 if ((kedata = (unsigned char *) malloc(keylength)) == NULL)
234 if ((kidata = (unsigned char *) malloc(keylength)) == NULL) {
238 if ((plaindata = (unsigned char *) malloc(enclen)) == NULL) {
243 if ((cksum = (unsigned char *) malloc(hashsize)) == NULL) {
250 ke.contents = kedata;
251 ke.length = keylength;
252 ki.contents = kidata;
253 ki.length = keylength;
255 /* derive the keys */
257 d1.data = constantdata;
258 d1.length = K5CLENGTH;
260 d1.data[0] = (usage>>24)&0xff;
261 d1.data[1] = (usage>>16)&0xff;
262 d1.data[2] = (usage>>8)&0xff;
263 d1.data[3] = usage&0xff;
267 if ((ret = krb5_derive_key(enc, key, &ke, &d1)) != 0)
272 if ((ret = krb5_derive_key(enc, key, &ki, &d1)) != 0)
275 /* decrypt the ciphertext */
278 d1.data = input->data;
283 if ((ret = ((*(enc->decrypt))(&ke, ivec, &d1, &d2))) != 0)
286 if (ivec != NULL && ivec->length == blocksize)
287 cn = d1.data + d1.length - blocksize;
291 /* verify the hash */
293 d1.length = hashsize;
296 if ((ret = krb5_hmac(hash, &ki, 1, &d2, &d1)) != 0)
299 if (memcmp(cksum, input->data+enclen, hashsize) != 0) {
300 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
304 /* because this encoding isn't self-describing wrt length, the
305 best we can do here is to compute the length minus the
308 /* get the real plaintext length and copy the data into the output */
310 plainlen = ((((plaindata+blocksize)[0])<<24) |
311 (((plaindata+blocksize)[1])<<16) |
312 (((plaindata+blocksize)[2])<<8) |
313 ((plaindata+blocksize)[3]));
315 if (plainlen > (enclen - blocksize - 4))
316 return(KRB5_BAD_MSIZE);
318 if (output->length < plainlen)
319 return(KRB5_BAD_MSIZE);
321 output->length = plainlen;
323 memcpy(output->data, d2.data+4+blocksize, output->length);
326 memcpy(ivec->data, cn, blocksize);
331 memset(kedata, 0, keylength);
332 memset(kidata, 0, keylength);
333 memset(plaindata, 0, enclen);
334 memset(cksum, 0, hashsize);
343 #endif /* ATHENA_DES3_KLUDGE */