aboutsummaryrefslogtreecommitdiff
path: root/src/lib/crypto/krb/aead.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/crypto/krb/aead.c')
-rw-r--r--src/lib/crypto/krb/aead.c385
1 files changed, 193 insertions, 192 deletions
diff --git a/src/lib/crypto/krb/aead.c b/src/lib/crypto/krb/aead.c
index f3ca11b..d6c5bbf 100644
--- a/src/lib/crypto/krb/aead.c
+++ b/src/lib/crypto/krb/aead.c
@@ -1,3 +1,4 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
* lib/crypto/aead.c
*
@@ -32,22 +33,22 @@
krb5_crypto_iov *
krb5int_c_locate_iov(krb5_crypto_iov *data,
- size_t num_data,
- krb5_cryptotype type)
+ size_t num_data,
+ krb5_cryptotype type)
{
size_t i;
krb5_crypto_iov *iov = NULL;
if (data == NULL)
- return NULL;
+ return NULL;
for (i = 0; i < num_data; i++) {
- if (data[i].flags == type) {
- if (iov == NULL)
- iov = &data[i];
- else
- return NULL; /* can't appear twice */
- }
+ if (data[i].flags == type) {
+ if (iov == NULL)
+ iov = &data[i];
+ else
+ return NULL; /* can't appear twice */
+ }
}
return iov;
@@ -55,9 +56,9 @@ krb5int_c_locate_iov(krb5_crypto_iov *data,
static krb5_error_code
make_unkeyed_checksum_iov(const struct krb5_hash_provider *hash_provider,
- const krb5_crypto_iov *data,
- size_t num_data,
- krb5_data *output)
+ const krb5_crypto_iov *data,
+ size_t num_data,
+ krb5_data *output)
{
krb5_data *sign_data;
size_t num_sign_data;
@@ -66,22 +67,22 @@ make_unkeyed_checksum_iov(const struct krb5_hash_provider *hash_provider,
/* Create a checksum over all the data to be signed */
for (i = 0, num_sign_data = 0; i < num_data; i++) {
- const krb5_crypto_iov *iov = &data[i];
+ const krb5_crypto_iov *iov = &data[i];
- if (SIGN_IOV(iov))
- num_sign_data++;
+ if (SIGN_IOV(iov))
+ num_sign_data++;
}
/* XXX cleanup to avoid alloc. */
sign_data = calloc(num_sign_data, sizeof(krb5_data));
if (sign_data == NULL)
- return ENOMEM;
+ return ENOMEM;
for (i = 0, j = 0; i < num_data; i++) {
- const krb5_crypto_iov *iov = &data[i];
+ const krb5_crypto_iov *iov = &data[i];
- if (SIGN_IOV(iov))
- sign_data[j++] = iov->data;
+ if (SIGN_IOV(iov))
+ sign_data[j++] = iov->data;
}
ret = (*hash_provider->hash)(num_sign_data, sign_data, output);
@@ -93,50 +94,50 @@ make_unkeyed_checksum_iov(const struct krb5_hash_provider *hash_provider,
krb5_error_code
krb5int_c_make_checksum_iov(const struct krb5_cksumtypes *cksum_type,
- krb5_key key,
- krb5_keyusage usage,
- const krb5_crypto_iov *data,
- size_t num_data,
- krb5_data *cksum_data)
+ krb5_key key,
+ krb5_keyusage usage,
+ const krb5_crypto_iov *data,
+ size_t num_data,
+ krb5_data *cksum_data)
{
const struct krb5_keytypes *e1, *e2;
krb5_error_code ret;
if (cksum_type->keyhash != NULL) {
- /* Check if key is compatible. */
-
- if (cksum_type->keyed_etype) {
- e1 = find_enctype(cksum_type->keyed_etype);
- e2 = find_enctype(key->keyblock.enctype);
- if (e1 == NULL || e2 == NULL || e1->enc != e2->enc) {
- ret = KRB5_BAD_ENCTYPE;
- goto cleanup;
- }
- }
-
- if (cksum_type->keyhash->hash_iov == NULL)
- return KRB5_BAD_ENCTYPE;
-
- ret = (*cksum_type->keyhash->hash_iov)(key, usage, 0, data, num_data,
- cksum_data);
+ /* Check if key is compatible. */
+
+ if (cksum_type->keyed_etype) {
+ e1 = find_enctype(cksum_type->keyed_etype);
+ e2 = find_enctype(key->keyblock.enctype);
+ if (e1 == NULL || e2 == NULL || e1->enc != e2->enc) {
+ ret = KRB5_BAD_ENCTYPE;
+ goto cleanup;
+ }
+ }
+
+ if (cksum_type->keyhash->hash_iov == NULL)
+ return KRB5_BAD_ENCTYPE;
+
+ ret = (*cksum_type->keyhash->hash_iov)(key, usage, 0, data, num_data,
+ cksum_data);
} else if (cksum_type->flags & KRB5_CKSUMFLAG_DERIVE) {
- ret = krb5int_dk_make_checksum_iov(cksum_type->hash,
- key, usage, data, num_data,
- cksum_data);
+ ret = krb5int_dk_make_checksum_iov(cksum_type->hash,
+ key, usage, data, num_data,
+ cksum_data);
} else {
- ret = make_unkeyed_checksum_iov(cksum_type->hash, data, num_data,
- cksum_data);
+ ret = make_unkeyed_checksum_iov(cksum_type->hash, data, num_data,
+ cksum_data);
}
if (ret == 0) {
- if (cksum_type->trunc_size) {
- cksum_data->length = cksum_type->trunc_size;
- }
+ if (cksum_type->trunc_size) {
+ cksum_data->length = cksum_type->trunc_size;
+ }
}
cleanup:
if (ret != 0) {
- memset(cksum_data->data, 0, cksum_data->length);
+ memset(cksum_data->data, 0, cksum_data->length);
}
return ret;
@@ -148,12 +149,12 @@ krb5int_c_find_checksum_type(krb5_cksumtype cksumtype)
size_t i;
for (i = 0; i < krb5int_cksumtypes_length; i++) {
- if (krb5int_cksumtypes_list[i].ctype == cksumtype)
- break;
+ if (krb5int_cksumtypes_list[i].ctype == cksumtype)
+ break;
}
if (i == krb5int_cksumtypes_length)
- return NULL;
+ return NULL;
return &krb5int_cksumtypes_list[i];
}
@@ -161,17 +162,17 @@ krb5int_c_find_checksum_type(krb5_cksumtype cksumtype)
#ifdef DEBUG_IOV
static void
dump_block(const char *tag,
- size_t i,
- size_t j,
- unsigned char *block,
- size_t block_size)
+ size_t i,
+ size_t j,
+ unsigned char *block,
+ size_t block_size)
{
size_t k;
printf("[%s: %d.%d] ", tag, i, j);
for (k = 0; k < block_size; k++)
- printf("%02x ", block[k] & 0xFF);
+ printf("%02x ", block[k] & 0xFF);
printf("\n");
}
@@ -179,29 +180,29 @@ dump_block(const char *tag,
static int
process_block_p(const krb5_crypto_iov *data,
- size_t num_data,
- struct iov_block_state *iov_state,
- size_t i)
+ size_t num_data,
+ struct iov_block_state *iov_state,
+ size_t i)
{
const krb5_crypto_iov *iov = &data[i];
int process_block;
switch (iov->flags) {
case KRB5_CRYPTO_TYPE_SIGN_ONLY:
- process_block = iov_state->include_sign_only;
- break;
+ process_block = iov_state->include_sign_only;
+ break;
case KRB5_CRYPTO_TYPE_PADDING:
- process_block = (iov_state->pad_to_boundary == 0);
- break;
+ process_block = (iov_state->pad_to_boundary == 0);
+ break;
case KRB5_CRYPTO_TYPE_HEADER:
- process_block = (iov_state->ignore_header == 0);
- break;
+ process_block = (iov_state->ignore_header == 0);
+ break;
case KRB5_CRYPTO_TYPE_DATA:
- process_block = 1;
- break;
+ process_block = 1;
+ break;
default:
- process_block = 0;
- break;
+ process_block = 0;
+ break;
}
return process_block;
@@ -213,70 +214,70 @@ process_block_p(const krb5_crypto_iov *data,
*/
static int
pad_to_boundary_p(const krb5_crypto_iov *data,
- size_t num_data,
- struct iov_block_state *iov_state,
- size_t i,
- size_t j)
+ size_t num_data,
+ struct iov_block_state *iov_state,
+ size_t i,
+ size_t j)
{
/* If the pad_to_boundary flag is unset, return FALSE */
if (iov_state->pad_to_boundary == 0)
- return 0;
+ return 0;
/* If we haven't got any data, we need to get some */
if (j == 0)
- return 0;
+ return 0;
/* No boundary between adjacent buffers marked for processing */
if (data[iov_state->iov_pos].flags == data[i].flags)
- return 0;
+ return 0;
return 1;
}
krb5_boolean
krb5int_c_iov_get_block(unsigned char *block,
- size_t block_size,
- const krb5_crypto_iov *data,
- size_t num_data,
- struct iov_block_state *iov_state)
+ size_t block_size,
+ const krb5_crypto_iov *data,
+ size_t num_data,
+ struct iov_block_state *iov_state)
{
size_t i, j = 0;
for (i = iov_state->iov_pos; i < num_data; i++) {
- const krb5_crypto_iov *iov = &data[i];
- size_t nbytes;
+ const krb5_crypto_iov *iov = &data[i];
+ size_t nbytes;
- if (!process_block_p(data, num_data, iov_state, i))
- continue;
+ if (!process_block_p(data, num_data, iov_state, i))
+ continue;
- if (pad_to_boundary_p(data, num_data, iov_state, i, j))
- break;
+ if (pad_to_boundary_p(data, num_data, iov_state, i, j))
+ break;
- iov_state->iov_pos = i;
+ iov_state->iov_pos = i;
- nbytes = iov->data.length - iov_state->data_pos;
- if (nbytes > block_size - j)
- nbytes = block_size - j;
+ nbytes = iov->data.length - iov_state->data_pos;
+ if (nbytes > block_size - j)
+ nbytes = block_size - j;
- memcpy(block + j, iov->data.data + iov_state->data_pos, nbytes);
+ memcpy(block + j, iov->data.data + iov_state->data_pos, nbytes);
- iov_state->data_pos += nbytes;
- j += nbytes;
+ iov_state->data_pos += nbytes;
+ j += nbytes;
- assert(j <= block_size);
+ assert(j <= block_size);
- if (j == block_size)
- break;
+ if (j == block_size)
+ break;
- assert(iov_state->data_pos == iov->data.length);
+ assert(iov_state->data_pos == iov->data.length);
- iov_state->data_pos = 0;
+ iov_state->data_pos = 0;
}
iov_state->iov_pos = i;
if (j != block_size)
- memset(block + j, 0, block_size - j);
+ memset(block + j, 0, block_size - j);
#ifdef DEBUG_IOV
dump_block("get_block", i, j, block, block_size);
@@ -287,42 +288,42 @@ krb5int_c_iov_get_block(unsigned char *block,
krb5_boolean
krb5int_c_iov_put_block(const krb5_crypto_iov *data,
- size_t num_data,
- unsigned char *block,
- size_t block_size,
- struct iov_block_state *iov_state)
+ size_t num_data,
+ unsigned char *block,
+ size_t block_size,
+ struct iov_block_state *iov_state)
{
size_t i, j = 0;
for (i = iov_state->iov_pos; i < num_data; i++) {
- const krb5_crypto_iov *iov = &data[i];
- size_t nbytes;
+ const krb5_crypto_iov *iov = &data[i];
+ size_t nbytes;
- if (!process_block_p(data, num_data, iov_state, i))
- continue;
+ if (!process_block_p(data, num_data, iov_state, i))
+ continue;
- if (pad_to_boundary_p(data, num_data, iov_state, i, j))
- break;
+ if (pad_to_boundary_p(data, num_data, iov_state, i, j))
+ break;
- iov_state->iov_pos = i;
+ iov_state->iov_pos = i;
- nbytes = iov->data.length - iov_state->data_pos;
- if (nbytes > block_size - j)
- nbytes = block_size - j;
+ nbytes = iov->data.length - iov_state->data_pos;
+ if (nbytes > block_size - j)
+ nbytes = block_size - j;
- memcpy(iov->data.data + iov_state->data_pos, block + j, nbytes);
+ memcpy(iov->data.data + iov_state->data_pos, block + j, nbytes);
- iov_state->data_pos += nbytes;
- j += nbytes;
+ iov_state->data_pos += nbytes;
+ j += nbytes;
- assert(j <= block_size);
+ assert(j <= block_size);
- if (j == block_size)
- break;
+ if (j == block_size)
+ break;
- assert(iov_state->data_pos == iov->data.length);
+ assert(iov_state->data_pos == iov->data.length);
- iov_state->data_pos = 0;
+ iov_state->data_pos = 0;
}
iov_state->iov_pos = i;
@@ -336,13 +337,13 @@ krb5int_c_iov_put_block(const krb5_crypto_iov *data,
krb5_error_code
krb5int_c_iov_decrypt_stream(const struct krb5_aead_provider *aead,
- const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- krb5_key key,
- krb5_keyusage keyusage,
- const krb5_data *ivec,
- krb5_crypto_iov *data,
- size_t num_data)
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ krb5_key key,
+ krb5_keyusage keyusage,
+ const krb5_data *ivec,
+ krb5_crypto_iov *data,
+ size_t num_data)
{
krb5_error_code ret;
unsigned int header_len, trailer_len, padding_len;
@@ -355,26 +356,26 @@ krb5int_c_iov_decrypt_stream(const struct krb5_aead_provider *aead,
assert(stream != NULL);
ret = (*aead->crypto_length)(aead, enc, hash, KRB5_CRYPTO_TYPE_HEADER,
- &header_len);
+ &header_len);
if (ret != 0)
- return ret;
+ return ret;
ret = (*aead->crypto_length)(aead, enc, hash, KRB5_CRYPTO_TYPE_TRAILER,
- &trailer_len);
+ &trailer_len);
if (ret != 0)
- return ret;
+ return ret;
ret = (*aead->crypto_length)(aead, enc, hash, KRB5_CRYPTO_TYPE_PADDING,
- &padding_len);
+ &padding_len);
if (ret != 0)
- return ret;
+ return ret;
if (stream->data.length < header_len + trailer_len)
- return KRB5_BAD_MSIZE;
+ return KRB5_BAD_MSIZE;
iov = calloc(num_data + 2, sizeof(krb5_crypto_iov));
if (iov == NULL)
- return ENOMEM;
+ return ENOMEM;
i = 0;
@@ -384,21 +385,21 @@ krb5int_c_iov_decrypt_stream(const struct krb5_aead_provider *aead,
i++;
for (j = 0; j < num_data; j++) {
- if (data[j].flags == KRB5_CRYPTO_TYPE_DATA) {
- if (got_data) {
- free(iov);
- return KRB5_BAD_MSIZE;
- }
-
- got_data++;
-
- data[j].data.data = stream->data.data + header_len;
- data[j].data.length = stream->data.length - header_len
- - trailer_len;
- }
- if (data[j].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY ||
- data[j].flags == KRB5_CRYPTO_TYPE_DATA)
- iov[i++] = data[j];
+ if (data[j].flags == KRB5_CRYPTO_TYPE_DATA) {
+ if (got_data) {
+ free(iov);
+ return KRB5_BAD_MSIZE;
+ }
+
+ got_data++;
+
+ data[j].data.data = stream->data.data + header_len;
+ data[j].data.length = stream->data.length - header_len
+ - trailer_len;
+ }
+ if (data[j].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY ||
+ data[j].flags == KRB5_CRYPTO_TYPE_DATA)
+ iov[i++] = data[j];
}
/*
@@ -426,34 +427,34 @@ krb5int_c_iov_decrypt_stream(const struct krb5_aead_provider *aead,
krb5_error_code
krb5int_c_padding_length(const struct krb5_aead_provider *aead,
- const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- size_t data_length,
- unsigned int *pad_length)
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ size_t data_length,
+ unsigned int *pad_length)
{
unsigned int padding;
krb5_error_code ret;
ret = (*aead->crypto_length)(aead, enc, hash, KRB5_CRYPTO_TYPE_PADDING,
- &padding);
+ &padding);
if (ret != 0)
- return ret;
+ return ret;
if (padding == 0 || (data_length % padding) == 0)
- *pad_length = 0;
+ *pad_length = 0;
else
- *pad_length = padding - (data_length % padding);
+ *pad_length = padding - (data_length % padding);
return 0;
}
krb5_error_code
krb5int_c_encrypt_aead_compat(const struct krb5_aead_provider *aead,
- const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- krb5_key key, krb5_keyusage usage,
- const krb5_data *ivec, const krb5_data *input,
- krb5_data *output)
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ krb5_key key, krb5_keyusage usage,
+ const krb5_data *ivec, const krb5_data *input,
+ krb5_data *output)
{
krb5_crypto_iov iov[4];
krb5_error_code ret;
@@ -462,23 +463,23 @@ krb5int_c_encrypt_aead_compat(const struct krb5_aead_provider *aead,
unsigned int trailer_len = 0;
ret = (*aead->crypto_length)(aead, enc, hash, KRB5_CRYPTO_TYPE_HEADER,
- &header_len);
+ &header_len);
if (ret != 0)
- return ret;
+ return ret;
ret = krb5int_c_padding_length(aead, enc, hash, input->length,
- &padding_len);
+ &padding_len);
if (ret != 0)
- return ret;
+ return ret;
ret = (*aead->crypto_length)(aead, enc, hash, KRB5_CRYPTO_TYPE_TRAILER,
- &trailer_len);
+ &trailer_len);
if (ret != 0)
- return ret;
+ return ret;
if (output->length <
- header_len + input->length + padding_len + trailer_len)
- return KRB5_BAD_MSIZE;
+ header_len + input->length + padding_len + trailer_len)
+ return KRB5_BAD_MSIZE;
iov[0].flags = KRB5_CRYPTO_TYPE_HEADER;
iov[0].data.data = output->data;
@@ -498,24 +499,24 @@ krb5int_c_encrypt_aead_compat(const struct krb5_aead_provider *aead,
iov[3].data.length = trailer_len;
ret = (*aead->encrypt_iov)(aead, enc, hash, key, usage, ivec,
- iov, sizeof(iov) / sizeof(iov[0]));
+ iov, sizeof(iov) / sizeof(iov[0]));
if (ret != 0)
- zap(iov[1].data.data, iov[1].data.length);
+ zap(iov[1].data.data, iov[1].data.length);
output->length = iov[0].data.length + iov[1].data.length +
- iov[2].data.length + iov[3].data.length;
+ iov[2].data.length + iov[3].data.length;
return ret;
}
krb5_error_code
krb5int_c_decrypt_aead_compat(const struct krb5_aead_provider *aead,
- const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- krb5_key key, krb5_keyusage usage,
- const krb5_data *ivec, const krb5_data *input,
- krb5_data *output)
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ krb5_key key, krb5_keyusage usage,
+ const krb5_data *ivec, const krb5_data *input,
+ krb5_data *output)
{
krb5_crypto_iov iov[2];
krb5_error_code ret;
@@ -523,7 +524,7 @@ krb5int_c_decrypt_aead_compat(const struct krb5_aead_provider *aead,
iov[0].flags = KRB5_CRYPTO_TYPE_STREAM;
iov[0].data.data = malloc(input->length);
if (iov[0].data.data == NULL)
- return ENOMEM;
+ return ENOMEM;
memcpy(iov[0].data.data, input->data, input->length);
iov[0].data.length = input->length;
@@ -533,14 +534,14 @@ krb5int_c_decrypt_aead_compat(const struct krb5_aead_provider *aead,
iov[1].data.length = 0;
ret = krb5int_c_iov_decrypt_stream(aead, enc, hash, key,
- usage, ivec,
- iov, sizeof(iov)/sizeof(iov[0]));
+ usage, ivec,
+ iov, sizeof(iov)/sizeof(iov[0]));
if (ret != 0)
- goto cleanup;
+ goto cleanup;
if (output->length < iov[1].data.length) {
- ret = KRB5_BAD_MSIZE;
- goto cleanup;
+ ret = KRB5_BAD_MSIZE;
+ goto cleanup;
}
memcpy(output->data, iov[1].data.data, iov[1].data.length);
@@ -554,19 +555,19 @@ cleanup:
void
krb5int_c_encrypt_length_aead_compat(const struct krb5_aead_provider *aead,
- const struct krb5_enc_provider *enc,
- const struct krb5_hash_provider *hash,
- size_t inputlen, size_t *length)
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ size_t inputlen, size_t *length)
{
unsigned int header_len = 0;
unsigned int padding_len = 0;
unsigned int trailer_len = 0;
(*aead->crypto_length)(aead, enc, hash, KRB5_CRYPTO_TYPE_HEADER,
- &header_len);
+ &header_len);
krb5int_c_padding_length(aead, enc, hash, inputlen, &padding_len);
(*aead->crypto_length)(aead, enc, hash, KRB5_CRYPTO_TYPE_TRAILER,
- &trailer_len);
+ &trailer_len);
*length = header_len + inputlen + padding_len + trailer_len;
}