+2004-02-13 Ken Raeburn <raeburn@mit.edu>
+
+ * dk_decrypt.c (krb5_dk_decrypt_maybe_trunc_hmac): New argument
+ IVEC_MODE. If clear, same old behavior. If set, copy out next
+ to last block for CTS.
+ (krb5_dk_decrypt, krb5int_aes_dk_decrypt): Pass extra argument.
+ * dk_encrypt.c (krb5int_aes_dk_encrypt): For IV, copy out next to
+ last block for CTS.
+
2003-07-22 Ken Raeburn <raeburn@mit.edu>
* checksum.c (krb5_dk_make_checksum, krb5_marc_dk_make_checksum):
const krb5_data *ivec,
const krb5_data *input,
krb5_data *output,
- size_t hmacsize);
+ size_t hmacsize,
+ int ivec_mode);
krb5_error_code
krb5_dk_decrypt(enc, hash, key, usage, ivec, input, output)
krb5_data *output;
{
return krb5_dk_decrypt_maybe_trunc_hmac(enc, hash, key, usage,
- ivec, input, output, 0);
+ ivec, input, output, 0, 0);
}
krb5_error_code
krb5_data *output;
{
return krb5_dk_decrypt_maybe_trunc_hmac(enc, hash, key, usage,
- ivec, input, output, 96 / 8);
+ ivec, input, output, 96 / 8, 1);
}
static krb5_error_code
krb5_dk_decrypt_maybe_trunc_hmac(enc, hash, key, usage, ivec, input, output,
- hmacsize)
+ hmacsize, ivec_mode)
const struct krb5_enc_provider *enc;
const struct krb5_hash_provider *hash;
const krb5_keyblock *key;
const krb5_data *input;
krb5_data *output;
size_t hmacsize;
+ int ivec_mode;
{
krb5_error_code ret;
size_t hashsize, blocksize, keybytes, keylength, enclen, plainlen;
if ((ret = ((*(enc->decrypt))(&ke, ivec, &d1, &d2))) != 0)
goto cleanup;
- if (ivec != NULL && ivec->length == blocksize)
- cn = (unsigned char *) d1.data + d1.length - blocksize;
- else
+ if (ivec != NULL && ivec->length == blocksize) {
+ if (ivec_mode == 0)
+ cn = (unsigned char *) d1.data + d1.length - blocksize;
+ else if (ivec_mode == 1) {
+ int nblocks = (d1.length + blocksize - 1) / blocksize;
+ cn = d1.data + blocksize * (nblocks - 2);
+ } else
+ abort();
+ } else
cn = NULL;
/* verify the hash */
if ((ret = ((*(enc->encrypt))(&ke, ivec, &d1, &d2))))
goto cleanup;
- if (ivec != NULL && ivec->length == blocksize)
- cn = d2.data + d2.length - blocksize;
- else
+ if (ivec != NULL && ivec->length == blocksize) {
+ int nblocks = (d2.length + blocksize - 1) / blocksize;
+ cn = d2.data + blocksize * (nblocks - 2);
+ } else
cn = NULL;
/* hash the plaintext */
output->length = enclen;
/* update ivec */
- if (cn != NULL)
+ if (cn != NULL) {
memcpy(ivec->data, cn, blocksize);
+#if 0
+ {
+ int i;
+ printf("\n%s: output:", __func__);
+ for (i = 0; i < output->length; i++) {
+ if (i % 16 == 0)
+ printf("\n%s: ", __func__);
+ printf(" %02x", i[(unsigned char *)output->data]);
+ }
+ printf("\n%s: outputIV:", __func__);
+ for (i = 0; i < ivec->length; i++) {
+ if (i % 16 == 0)
+ printf("\n%s: ", __func__);
+ printf(" %02x", i[(unsigned char *)ivec->data]);
+ }
+ printf("\n"); fflush(stdout);
+ }
+#endif
+ }
/* ret is set correctly by the prior call */