1
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
/* lib/crypto/krb/checksum_confounder.c */
4
* Copyright (C) 2009 by the Massachusetts Institute of Technology.
7
* Export of this software from the United States of America may
8
* require a specific license from the United States Government.
9
* It is the responsibility of any person or organization contemplating
10
* export to obtain such a license before exporting.
12
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13
* distribute this software and its documentation for any purpose and
14
* without fee is hereby granted, provided that the above copyright
15
* notice appear in all copies and that both that copyright notice and
16
* this permission notice appear in supporting documentation, and that
17
* the name of M.I.T. not be used in advertising or publicity pertaining
18
* to distribution of the software without specific, written prior
19
* permission. Furthermore if you modify this software you must label
20
* your software as modified software and not distribute it in such a
21
* fashion that it might be confused with the original M.I.T. software.
22
* M.I.T. makes no representations about the suitability of
23
* this software for any purpose. It is provided "as is" without express
24
* or implied warranty.
28
* Confounder checksum implementation, using tokens of the form:
29
* enc(xorkey, confounder | hash(confounder | data))
30
* where xorkey is the key XOR'd with 0xf0 bytes.
33
#include "crypto_int.h"
35
/* Derive a key by XOR with 0xF0 bytes. */
36
static krb5_error_code
37
mk_xorkey(krb5_key origkey, krb5_key *xorkey)
39
krb5_error_code retval = 0;
40
unsigned char *xorbytes;
41
krb5_keyblock xorkeyblock;
44
xorbytes = malloc(origkey->keyblock.length);
47
memcpy(xorbytes, origkey->keyblock.contents, origkey->keyblock.length);
48
for (i = 0; i < origkey->keyblock.length; i++)
51
/* Do a shallow copy here. */
52
xorkeyblock = origkey->keyblock;
53
xorkeyblock.contents = xorbytes;
55
retval = krb5_k_create_key(0, &xorkeyblock, xorkey);
56
zapfree(xorbytes, sizeof(xorbytes));
61
krb5int_confounder_checksum(const struct krb5_cksumtypes *ctp,
62
krb5_key key, krb5_keyusage usage,
63
const krb5_crypto_iov *data, size_t num_data,
67
krb5_data conf, hashval;
68
krb5_key xorkey = NULL;
69
krb5_crypto_iov *hash_iov, iov;
70
size_t blocksize = ctp->enc->block_size, hashsize = ctp->hash->hashsize;
72
/* Partition the output buffer into confounder and hash. */
73
conf = make_data(output->data, blocksize);
74
hashval = make_data(output->data + blocksize, hashsize);
76
/* Create the confounder. */
77
ret = krb5_c_random_make_octets(NULL, &conf);
81
ret = mk_xorkey(key, &xorkey);
85
/* Hash the confounder, then the input data. */
86
hash_iov = k5alloc((num_data + 1) * sizeof(krb5_crypto_iov), &ret);
89
hash_iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
90
hash_iov[0].data = conf;
91
memcpy(hash_iov + 1, data, num_data * sizeof(krb5_crypto_iov));
92
ret = ctp->hash->hash(hash_iov, num_data + 1, &hashval);
96
/* Confounder and hash are in output buffer; encrypt them in place. */
97
iov.flags = KRB5_CRYPTO_TYPE_DATA;
99
ret = ctp->enc->encrypt(xorkey, NULL, &iov, 1);
103
krb5_k_free_key(NULL, xorkey);
107
krb5_error_code krb5int_confounder_verify(const struct krb5_cksumtypes *ctp,
108
krb5_key key, krb5_keyusage usage,
109
const krb5_crypto_iov *data,
111
const krb5_data *input,
115
unsigned char *plaintext = NULL;
116
krb5_key xorkey = NULL;
117
krb5_data computed = empty_data();
118
krb5_crypto_iov *hash_iov = NULL, iov;
119
size_t blocksize = ctp->enc->block_size, hashsize = ctp->hash->hashsize;
121
plaintext = k5alloc(input->length, &ret);
122
if (plaintext == NULL)
125
ret = mk_xorkey(key, &xorkey);
129
/* Decrypt the input checksum. */
130
iov.flags = KRB5_CRYPTO_TYPE_DATA;
131
iov.data = make_data(plaintext, input->length);
132
memcpy(plaintext, input->data, input->length);
133
ret = ctp->enc->decrypt(xorkey, NULL, &iov, 1);
137
/* Hash the confounder, then the input data. */
138
hash_iov = k5alloc((num_data + 1) * sizeof(krb5_crypto_iov), &ret);
139
if (hash_iov == NULL)
141
hash_iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
142
hash_iov[0].data = make_data(plaintext, blocksize);
143
memcpy(hash_iov + 1, data, num_data * sizeof(krb5_crypto_iov));
144
ret = alloc_data(&computed, hashsize);
147
ret = ctp->hash->hash(hash_iov, num_data + 1, &computed);
151
/* Compare the decrypted hash to the computed one. */
152
*valid = (memcmp(plaintext + blocksize, computed.data, hashsize) == 0);
155
zapfree(plaintext, input->length);
156
zapfree(computed.data, hashsize);
158
krb5_k_free_key(NULL, xorkey);