From 228548a2afeb4075d6da16e78bb97ca44c7bfabd Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Sat, 3 Oct 2009 18:07:44 +0000 Subject: [PATCH] Update the crypto derived key support code to conform to most of the current coding practices (except lack of tabs). Use the helper functions k5alloc, zapfree, and find_enctype to reduce code size. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@22840 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/crypto/krb/dk/checksum.c | 100 +++++++--------- src/lib/crypto/krb/dk/derive.c | 157 +++++++++--------------- src/lib/crypto/krb/dk/dk.h | 133 +++++++++----------- src/lib/crypto/krb/dk/dk_aead.c | 109 +++++++---------- src/lib/crypto/krb/dk/dk_decrypt.c | 85 ++++++------- src/lib/crypto/krb/dk/dk_encrypt.c | 180 ++++++++++++---------------- src/lib/crypto/krb/dk/stringtokey.c | 51 ++++---- 7 files changed, 334 insertions(+), 481 deletions(-) diff --git a/src/lib/crypto/krb/dk/checksum.c b/src/lib/crypto/krb/dk/checksum.c index f4b18bf0c..fb5622a73 100644 --- a/src/lib/crypto/krb/dk/checksum.c +++ b/src/lib/crypto/krb/dk/checksum.c @@ -36,41 +36,35 @@ krb5_dk_make_checksum(const struct krb5_hash_provider *hash, const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *input, krb5_data *output) { - int i; + const struct krb5_keytypes *ktp; const struct krb5_enc_provider *enc; - size_t blocksize, keybytes, keylength; + size_t keylength; krb5_error_code ret; unsigned char constantdata[K5CLENGTH]; krb5_data datain; unsigned char *kcdata; krb5_keyblock kc; - for (i=0; ienctype) - break; - } + ktp = find_enctype(key->enctype); + if (ktp == NULL) + return KRB5_BAD_ENCTYPE; + enc = ktp->enc; - if (i == krb5_enctypes_length) - return(KRB5_BAD_ENCTYPE); + /* + * key->length will be tested in enc->encrypt. + * output->length will be tested in krb5_hmac. + */ - enc = krb5_enctypes_list[i].enc; - - /* allocate and set to-be-derived keys */ - - blocksize = enc->block_size; - keybytes = enc->keybytes; + /* Allocate and set to-be-derived keys. */ keylength = enc->keylength; - - /* key->length will be tested in enc->encrypt - output->length will be tested in krb5_hmac */ - - if ((kcdata = (unsigned char *) malloc(keylength)) == NULL) - return(ENOMEM); + kcdata = malloc(keylength); + if (kcdata == NULL) + return ENOMEM; kc.contents = kcdata; kc.length = keylength; - /* derive the key */ + /* Derive the key. */ datain.data = (char *) constantdata; datain.length = K5CLENGTH; @@ -79,24 +73,21 @@ krb5_dk_make_checksum(const struct krb5_hash_provider *hash, datain.data[4] = (char) 0x99; - if ((ret = krb5_derive_key(enc, key, &kc, &datain)) != 0) + ret = krb5_derive_key(enc, key, &kc, &datain); + if (ret) goto cleanup; /* hash the data */ datain = *input; - if ((ret = krb5_hmac(hash, &kc, 1, &datain, output)) != 0) + ret = krb5_hmac(hash, &kc, 1, &datain, output); + if (ret) memset(output->data, 0, output->length); - /* ret is set correctly by the prior call */ - cleanup: - memset(kcdata, 0, keylength); - - free(kcdata); - - return(ret); + zapfree(kcdata, keylength); + return ret; } krb5_error_code @@ -105,41 +96,36 @@ krb5int_dk_make_checksum_iov(const struct krb5_hash_provider *hash, const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { - int i; + const struct krb5_keytypes *ktp; const struct krb5_enc_provider *enc; - size_t blocksize, keybytes, keylength; + size_t keylength; krb5_error_code ret; unsigned char constantdata[K5CLENGTH]; krb5_data datain; unsigned char *kcdata; krb5_keyblock kc; - for (i=0; ienctype) - break; - } - - if (i == krb5_enctypes_length) - return(KRB5_BAD_ENCTYPE); + ktp = find_enctype(key->enctype); + if (ktp == NULL) + return KRB5_BAD_ENCTYPE; + enc = ktp->enc; - enc = krb5_enctypes_list[i].enc; + /* + * key->length will be tested in enc->encrypt. + * output->length will be tested in krb5_hmac. + */ - /* allocate and set to-be-derived keys */ + /* Allocate and set to-be-derived keys. */ - blocksize = enc->block_size; - keybytes = enc->keybytes; keylength = enc->keylength; - - /* key->length will be tested in enc->encrypt - output->length will be tested in krb5_hmac */ - - if ((kcdata = (unsigned char *) malloc(keylength)) == NULL) - return(ENOMEM); + kcdata = malloc(keylength); + if (kcdata == NULL) + return ENOMEM; kc.contents = kcdata; kc.length = keylength; - /* derive the key */ + /* Derive the key. */ datain.data = (char *) constantdata; datain.length = K5CLENGTH; @@ -148,20 +134,18 @@ krb5int_dk_make_checksum_iov(const struct krb5_hash_provider *hash, datain.data[4] = (char) 0x99; - if ((ret = krb5_derive_key(enc, key, &kc, &datain)) != 0) + ret = krb5_derive_key(enc, key, &kc, &datain); + if (ret) goto cleanup; - /* hash the data */ + /* Hash the data. */ - if ((ret = krb5int_hmac_iov(hash, &kc, data, num_data, output)) != 0) + ret = krb5int_hmac_iov(hash, &kc, data, num_data, output); + if (ret) memset(output->data, 0, output->length); - /* ret is set correctly by the prior call */ - cleanup: - memset(kcdata, 0, keylength); - - free(kcdata); + zapfree(kcdata, keylength); return(ret); } diff --git a/src/lib/crypto/krb/dk/derive.c b/src/lib/crypto/krb/dk/derive.c index 77b05fa1a..8c8214c12 100644 --- a/src/lib/crypto/krb/dk/derive.c +++ b/src/lib/crypto/krb/dk/derive.c @@ -32,33 +32,27 @@ krb5_derive_key(const struct krb5_enc_provider *enc, const krb5_keyblock *inkey, krb5_keyblock *outkey, const krb5_data *in_constant) { - size_t blocksize, keybytes, keylength, n; - unsigned char *inblockdata, *outblockdata, *rawkey; + size_t blocksize, keybytes, n; + unsigned char *inblockdata = NULL, *outblockdata = NULL, *rawkey = NULL; krb5_data inblock, outblock; + krb5_error_code ret; blocksize = enc->block_size; keybytes = enc->keybytes; - keylength = enc->keylength; - if ((inkey->length != keylength) || - (outkey->length != keylength)) - return(KRB5_CRYPTO_INTERNAL); + if (inkey->length != enc->keylength || outkey->length != enc->keylength) + return KRB5_CRYPTO_INTERNAL; - /* allocate and set up buffers */ - - if ((inblockdata = (unsigned char *) malloc(blocksize)) == NULL) - return(ENOMEM); - - if ((outblockdata = (unsigned char *) malloc(blocksize)) == NULL) { - free(inblockdata); - return(ENOMEM); - } - - if ((rawkey = (unsigned char *) malloc(keybytes)) == NULL) { - free(outblockdata); - free(inblockdata); - return(ENOMEM); - } + /* Allocate and set up buffers. */ + inblockdata = k5alloc(blocksize, &ret); + if (ret) + goto cleanup; + outblockdata = k5alloc(blocksize, &ret); + if (ret) + goto cleanup; + rawkey = k5alloc(keybytes, &ret); + if (ret) + goto cleanup; inblock.data = (char *) inblockdata; inblock.length = blocksize; @@ -66,7 +60,7 @@ krb5_derive_key(const struct krb5_enc_provider *enc, outblock.data = (char *) outblockdata; outblock.length = blocksize; - /* initialize the input block */ + /* Initialize the input block. */ if (in_constant->length == inblock.length) { memcpy(inblock.data, in_constant->data, inblock.length); @@ -75,14 +69,16 @@ krb5_derive_key(const struct krb5_enc_provider *enc, inblock.length*8, (unsigned char *) inblock.data); } - /* loop encrypting the blocks until enough key bytes are generated */ + /* Loop encrypting the blocks until enough key bytes are generated */ n = 0; while (n < keybytes) { - (*(enc->encrypt))(inkey, 0, &inblock, &outblock); + ret = (*enc->encrypt)(inkey, 0, &inblock, &outblock); + if (ret) + goto cleanup; if ((keybytes - n) <= outblock.length) { - memcpy(rawkey+n, outblock.data, (keybytes - n)); + memcpy(rawkey + n, outblock.data, (keybytes - n)); break; } @@ -96,19 +92,15 @@ krb5_derive_key(const struct krb5_enc_provider *enc, inblock.data = (char *) rawkey; inblock.length = keybytes; - (*(enc->make_key))(&inblock, outkey); - - /* clean memory, free resources and exit */ - - memset(inblockdata, 0, blocksize); - memset(outblockdata, 0, blocksize); - memset(rawkey, 0, keybytes); + ret = (*enc->make_key)(&inblock, outkey); + if (ret) + goto cleanup; - free(rawkey); - free(outblockdata); - free(inblockdata); - - return(0); +cleanup: + zapfree(inblockdata, blocksize); + zapfree(outblockdata, blocksize); + zapfree(rawkey, keybytes); + return ret; } @@ -117,33 +109,28 @@ krb5_derive_random(const struct krb5_enc_provider *enc, const krb5_keyblock *inkey, krb5_data *outrnd, const krb5_data *in_constant) { - size_t blocksize, keybytes, keylength, n; - unsigned char *inblockdata, *outblockdata, *rawkey; + size_t blocksize, keybytes, n; + unsigned char *inblockdata = NULL, *outblockdata = NULL, *rawkey = NULL; krb5_data inblock, outblock; + krb5_error_code ret; blocksize = enc->block_size; keybytes = enc->keybytes; - keylength = enc->keylength; - - if ((inkey->length != keylength) || - (outrnd->length != keybytes)) - return(KRB5_CRYPTO_INTERNAL); - /* allocate and set up buffers */ + if (inkey->length != enc->keylength || outrnd->length != keybytes) + return KRB5_CRYPTO_INTERNAL; - if ((inblockdata = (unsigned char *) malloc(blocksize)) == NULL) - return(ENOMEM); + /* Allocate and set up buffers. */ - if ((outblockdata = (unsigned char *) malloc(blocksize)) == NULL) { - free(inblockdata); - return(ENOMEM); - } - - if ((rawkey = (unsigned char *) malloc(keybytes)) == NULL) { - free(outblockdata); - free(inblockdata); - return(ENOMEM); - } + inblockdata = k5alloc(blocksize, &ret); + if (ret) + goto cleanup; + outblockdata = k5alloc(blocksize, &ret); + if (ret) + goto cleanup; + rawkey = k5alloc(keybytes, &ret); + if (ret) + goto cleanup; inblock.data = (char *) inblockdata; inblock.length = blocksize; @@ -151,8 +138,7 @@ krb5_derive_random(const struct krb5_enc_provider *enc, outblock.data = (char *) outblockdata; outblock.length = blocksize; - /* initialize the input block */ - + /* Initialize the input block. */ if (in_constant->length == inblock.length) { memcpy(inblock.data, in_constant->data, inblock.length); } else { @@ -160,14 +146,15 @@ krb5_derive_random(const struct krb5_enc_provider *enc, inblock.length*8, (unsigned char *) inblock.data); } - /* loop encrypting the blocks until enough key bytes are generated */ - + /* Loop encrypting the blocks until enough key bytes are generated. */ n = 0; while (n < keybytes) { - (*(enc->encrypt))(inkey, 0, &inblock, &outblock); + ret = (*enc->encrypt)(inkey, 0, &inblock, &outblock); + if (ret) + goto cleanup; if ((keybytes - n) <= outblock.length) { - memcpy(rawkey+n, outblock.data, (keybytes - n)); + memcpy(rawkey + n, outblock.data, (keybytes - n)); break; } @@ -176,42 +163,12 @@ krb5_derive_random(const struct krb5_enc_provider *enc, n += outblock.length; } - /* postprocess the key */ - - memcpy (outrnd->data, rawkey, keybytes); - - /* clean memory, free resources and exit */ - - memset(inblockdata, 0, blocksize); - memset(outblockdata, 0, blocksize); - memset(rawkey, 0, keybytes); - - free(rawkey); - free(outblockdata); - free(inblockdata); - - return(0); -} - -#if 0 -#include "etypes.h" -void -krb5_random2key (krb5_enctype enctype, krb5_data *inblock, - krb5_keyblock *outkey) -{ - int i; - const struct krb5_enc_provider *enc; - - for (i=0; idata, rawkey, keybytes); - enc->make_key (inblock, outkey); +cleanup: + zapfree(inblockdata, blocksize); + zapfree(outblockdata, blocksize); + zapfree(rawkey, keybytes); + return ret; } -#endif diff --git a/src/lib/crypto/krb/dk/dk.h b/src/lib/crypto/krb/dk/dk.h index 54d1076c8..9ddeb408c 100644 --- a/src/lib/crypto/krb/dk/dk.h +++ b/src/lib/crypto/krb/dk/dk.h @@ -26,64 +26,64 @@ #include "k5-int.h" -void krb5_dk_encrypt_length -(const struct krb5_enc_provider *enc, - const struct krb5_hash_provider *hash, - size_t input, size_t *length); - -krb5_error_code krb5_dk_encrypt -(const struct krb5_enc_provider *enc, - const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, - const krb5_data *ivec, - const krb5_data *input, krb5_data *output); - -void krb5int_aes_encrypt_length -(const struct krb5_enc_provider *enc, - const struct krb5_hash_provider *hash, - size_t input, size_t *length); - -krb5_error_code krb5int_aes_dk_encrypt -(const struct krb5_enc_provider *enc, - const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, - const krb5_data *ivec, - const krb5_data *input, krb5_data *output); - -krb5_error_code krb5_dk_decrypt -(const struct krb5_enc_provider *enc, - const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, - const krb5_data *ivec, const krb5_data *input, - krb5_data *arg_output); - -krb5_error_code krb5int_aes_dk_decrypt -(const struct krb5_enc_provider *enc, - const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, - const krb5_data *ivec, const krb5_data *input, - krb5_data *arg_output); - -krb5_error_code krb5int_dk_string_to_key -(const struct krb5_enc_provider *enc, - const krb5_data *string, const krb5_data *salt, - const krb5_data *params, krb5_keyblock *key); - -krb5_error_code krb5_derive_key -(const struct krb5_enc_provider *enc, - const krb5_keyblock *inkey, - krb5_keyblock *outkey, const krb5_data *in_constant); - -krb5_error_code krb5_dk_make_checksum -(const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, - const krb5_data *input, krb5_data *output); +void krb5_dk_encrypt_length(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + size_t input, size_t *length); + +krb5_error_code krb5_dk_encrypt(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, + const krb5_data *input, krb5_data *output); + +void krb5int_aes_encrypt_length(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + size_t input, size_t *length); + +krb5_error_code krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, + krb5_keyusage usage, + const krb5_data *ivec, + const krb5_data *input, + krb5_data *output); + +krb5_error_code krb5_dk_decrypt(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_data *ivec, const krb5_data *input, + krb5_data *arg_output); + +krb5_error_code krb5int_aes_dk_decrypt(const struct krb5_enc_provider *enc, + const struct krb5_hash_provider *hash, + const krb5_keyblock *key, + krb5_keyusage usage, + const krb5_data *ivec, + const krb5_data *input, + krb5_data *arg_output); + +krb5_error_code krb5int_dk_string_to_key(const struct krb5_enc_provider *enc, + const krb5_data *string, + const krb5_data *salt, + const krb5_data *params, + krb5_keyblock *key); + +krb5_error_code krb5_derive_key(const struct krb5_enc_provider *enc, + const krb5_keyblock *inkey, + krb5_keyblock *outkey, + const krb5_data *in_constant); + +krb5_error_code krb5_dk_make_checksum(const struct krb5_hash_provider *hash, + const krb5_keyblock *key, + krb5_keyusage usage, + const krb5_data *input, + krb5_data *output); krb5_error_code krb5int_dk_make_checksum_iov(const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, - const krb5_crypto_iov *data, size_t num_data, - krb5_data *output); + const krb5_keyblock *key, krb5_keyusage usage, + const krb5_crypto_iov *data, size_t num_data, + krb5_data *output); krb5_error_code krb5_derive_random(const struct krb5_enc_provider *enc, @@ -94,26 +94,3 @@ krb5_derive_random(const struct krb5_enc_provider *enc, extern const struct krb5_aead_provider krb5int_aead_dk; extern const struct krb5_aead_provider krb5int_aead_aes; - -/* CCM */ - -void -krb5int_ccm_encrypt_length(const struct krb5_enc_provider *enc, - const struct krb5_hash_provider *hash, - size_t inputlen, size_t *length); - -extern const struct krb5_aead_provider krb5int_aead_ccm; - -krb5_error_code krb5int_ccm_encrypt -(const struct krb5_enc_provider *enc, - const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, - const krb5_data *ivec, const krb5_data *input, - krb5_data *arg_output); - -krb5_error_code krb5int_ccm_decrypt -(const struct krb5_enc_provider *enc, - const struct krb5_hash_provider *hash, - const krb5_keyblock *key, krb5_keyusage usage, - const krb5_data *ivec, const krb5_data *input, - krb5_data *arg_output); diff --git a/src/lib/crypto/krb/dk/dk_aead.c b/src/lib/crypto/krb/dk/dk_aead.c index e995f9ae6..13eb007cd 100644 --- a/src/lib/crypto/krb/dk/dk_aead.c +++ b/src/lib/crypto/krb/dk/dk_aead.c @@ -8,7 +8,7 @@ * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. - * + * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright @@ -84,11 +84,13 @@ krb5int_dk_encrypt_iov(const struct krb5_aead_provider *aead, /* E(Confounder | Plaintext | Pad) | Checksum */ - ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_PADDING, &blocksize); + ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_PADDING, + &blocksize); if (ret != 0) return ret; - ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_TRAILER, &hmacsize); + ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_TRAILER, + &hmacsize); if (ret != 0) return ret; @@ -110,7 +112,7 @@ krb5int_dk_encrypt_iov(const struct krb5_aead_provider *aead, return KRB5_BAD_MSIZE; if (blocksize != 0) { - /* Check that the input data is correctly padded */ + /* Check that the input data is correctly padded. */ if (plainlen % blocksize) padsize = blocksize - (plainlen % blocksize); } @@ -125,24 +127,18 @@ krb5int_dk_encrypt_iov(const struct krb5_aead_provider *aead, } ke.length = enc->keylength; - ke.contents = malloc(ke.length); - if (ke.contents == NULL) { - ret = ENOMEM; + ke.contents = k5alloc(ke.length, &ret); + if (ret != 0) goto cleanup; - } ki.length = enc->keylength; - ki.contents = malloc(ki.length); - if (ki.contents == NULL) { - ret = ENOMEM; + ki.contents = k5alloc(ki.length, &ret); + if (ret != 0) goto cleanup; - } - cksum = (unsigned char *)malloc(hash->hashsize); - if (cksum == NULL) { - ret = ENOMEM; + cksum = k5alloc(hash->hashsize, &ret); + if (ret != 0) goto cleanup; - } - /* derive the keys */ + /* Derive the keys. */ d1.data = (char *)constantdata; d1.length = K5CLENGTH; @@ -161,7 +157,7 @@ krb5int_dk_encrypt_iov(const struct krb5_aead_provider *aead, if (ret != 0) goto cleanup; - /* generate confounder */ + /* Generate confounder. */ header->data.length = enc->block_size; @@ -169,7 +165,7 @@ krb5int_dk_encrypt_iov(const struct krb5_aead_provider *aead, if (ret != 0) goto cleanup; - /* hash the plaintext */ + /* Hash the plaintext. */ d2.length = hash->hashsize; d2.data = (char *)cksum; @@ -177,32 +173,23 @@ krb5int_dk_encrypt_iov(const struct krb5_aead_provider *aead, if (ret != 0) goto cleanup; - /* encrypt the plaintext (header | data | padding) */ + /* Encrypt the plaintext (header | data | padding) */ assert(enc->encrypt_iov != NULL); - ret = enc->encrypt_iov(&ke, ivec, data, num_data); /* will update ivec */ + ret = (*enc->encrypt_iov)(&ke, ivec, data, num_data); /* updates ivec */ if (ret != 0) goto cleanup; - /* possibly truncate the hash */ + /* Possibly truncate the hash */ assert(hmacsize <= d2.length); memcpy(trailer->data.data, cksum, hmacsize); trailer->data.length = hmacsize; cleanup: - if (ke.contents != NULL) { - memset(ke.contents, 0, ke.length); - free(ke.contents); - } - if (ki.contents != NULL) { - memset(ki.contents, 0, ki.length); - free(ki.contents); - } - if (cksum != NULL) { - free(cksum); - } - + zapfree(ke.contents, ke.length); + zapfree(ki.contents, ki.length); + free(cksum); return ret; } @@ -222,12 +209,13 @@ krb5int_dk_decrypt_iov(const struct krb5_aead_provider *aead, krb5_crypto_iov *header, *trailer; krb5_keyblock ke, ki; size_t i; - unsigned int blocksize = 0; /* careful, this is enc block size not confounder len */ + unsigned int blocksize = 0; /* enc block size, not confounder len */ unsigned int cipherlen = 0; unsigned int hmacsize = 0; unsigned char *cksum = NULL; - if (krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_STREAM) != NULL) { + if (krb5int_c_locate_iov(data, num_data, + KRB5_CRYPTO_TYPE_STREAM) != NULL) { return krb5int_c_iov_decrypt_stream(aead, enc, hash, key, usage, ivec, data, num_data); } @@ -237,11 +225,13 @@ krb5int_dk_decrypt_iov(const struct krb5_aead_provider *aead, /* E(Confounder | Plaintext | Pad) | Checksum */ - ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_PADDING, &blocksize); + ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_PADDING, + &blocksize); if (ret != 0) return ret; - ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_TRAILER, &hmacsize); + ret = aead->crypto_length(aead, enc, hash, KRB5_CRYPTO_TYPE_TRAILER, + &hmacsize); if (ret != 0) return ret; @@ -273,24 +263,18 @@ krb5int_dk_decrypt_iov(const struct krb5_aead_provider *aead, return KRB5_BAD_MSIZE; ke.length = enc->keylength; - ke.contents = malloc(ke.length); - if (ke.contents == NULL) { - ret = ENOMEM; + ke.contents = k5alloc(ke.length, &ret); + if (ret != 0) goto cleanup; - } ki.length = enc->keylength; - ki.contents = malloc(ki.length); - if (ki.contents == NULL) { - ret = ENOMEM; + ki.contents = k5alloc(ki.length, &ret); + if (ret != 0) goto cleanup; - } - cksum = (unsigned char *)malloc(hash->hashsize); - if (cksum == NULL) { - ret = ENOMEM; + cksum = k5alloc(hash->hashsize, &ret); + if (ret != 0) goto cleanup; - } - /* derive the keys */ + /* Derive the keys. */ d1.data = (char *)constantdata; d1.length = K5CLENGTH; @@ -309,14 +293,14 @@ krb5int_dk_decrypt_iov(const struct krb5_aead_provider *aead, if (ret != 0) goto cleanup; - /* decrypt the plaintext (header | data | padding) */ + /* Decrypt the plaintext (header | data | padding). */ assert(enc->decrypt_iov != NULL); - ret = enc->decrypt_iov(&ke, ivec, data, num_data); /* will update ivec */ + ret = (*enc->decrypt_iov)(&ke, ivec, data, num_data); /* updates ivec */ if (ret != 0) goto cleanup; - /* verify the hash */ + /* Verify the hash. */ d1.length = hash->hashsize; /* non-truncated length */ d1.data = (char *)cksum; @@ -324,24 +308,16 @@ krb5int_dk_decrypt_iov(const struct krb5_aead_provider *aead, if (ret != 0) goto cleanup; - /* compare only the possibly truncated length */ + /* Compare only the possibly truncated length. */ if (memcmp(cksum, trailer->data.data, hmacsize) != 0) { ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; goto cleanup; } cleanup: - if (ke.contents != NULL) { - memset(ke.contents, 0, ke.length); - free(ke.contents); - } - if (ki.contents != NULL) { - memset(ki.contents, 0, ki.length); - free(ki.contents); - } - if (cksum != NULL) { - free(cksum); - } + zapfree(ke.contents, ke.length); + zapfree(ki.contents, ki.length); + free(cksum); return ret; } @@ -383,4 +359,3 @@ const struct krb5_aead_provider krb5int_aead_aes = { krb5int_dk_encrypt_iov, krb5int_dk_decrypt_iov }; - diff --git a/src/lib/crypto/krb/dk/dk_decrypt.c b/src/lib/crypto/krb/dk/dk_decrypt.c index c38c4d5bf..1c0358a2d 100644 --- a/src/lib/crypto/krb/dk/dk_decrypt.c +++ b/src/lib/crypto/krb/dk/dk_decrypt.c @@ -71,17 +71,15 @@ krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc, int ivec_mode) { krb5_error_code ret; - size_t hashsize, blocksize, keybytes, keylength, enclen, plainlen; - unsigned char *plaindata, *kedata, *kidata, *cksum, *cn; + size_t hashsize, blocksize, keylength, enclen, plainlen; + unsigned char *plaindata = NULL, *kedata = NULL, *kidata = NULL; + unsigned char *cksum = NULL, *cn; krb5_keyblock ke, ki; krb5_data d1, d2; unsigned char constantdata[K5CLENGTH]; - /* allocate and set up ciphertext and to-be-derived keys */ - hashsize = hash->hashsize; blocksize = enc->block_size; - keybytes = enc->keybytes; keylength = enc->keylength; if (hmacsize == 0) @@ -91,30 +89,26 @@ krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc, enclen = input->length - hmacsize; - if ((kedata = (unsigned char *) malloc(keylength)) == NULL) - return(ENOMEM); - if ((kidata = (unsigned char *) malloc(keylength)) == NULL) { - free(kedata); - return(ENOMEM); - } - if ((plaindata = (unsigned char *) malloc(enclen)) == NULL) { - free(kidata); - free(kedata); - return(ENOMEM); - } - if ((cksum = (unsigned char *) malloc(hashsize)) == NULL) { - free(plaindata); - free(kidata); - free(kedata); - return(ENOMEM); - } + /* Allocate and set up ciphertext and to-be-derived keys. */ + kedata = k5alloc(keylength, &ret); + if (ret != 0) + goto cleanup; + kidata = k5alloc(keylength, &ret); + if (ret != 0) + goto cleanup; + plaindata = k5alloc(enclen, &ret); + if (ret != 0) + goto cleanup; + cksum = k5alloc(hashsize, &ret); + if (ret != 0) + goto cleanup; ke.contents = kedata; ke.length = keylength; ki.contents = kidata; ki.length = keylength; - /* derive the keys */ + /* Derive the keys. */ d1.data = (char *) constantdata; d1.length = K5CLENGTH; @@ -123,12 +117,14 @@ krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc, d1.data[4] = (char) 0xAA; - if ((ret = krb5_derive_key(enc, key, &ke, &d1)) != 0) + ret = krb5_derive_key(enc, key, &ke, &d1); + if (ret != 0) goto cleanup; d1.data[4] = 0x55; - if ((ret = krb5_derive_key(enc, key, &ki, &d1)) != 0) + ret = krb5_derive_key(enc, key, &ki, &d1); + if (ret != 0) goto cleanup; /* decrypt the ciphertext */ @@ -139,7 +135,8 @@ krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc, d2.length = enclen; d2.data = (char *) plaindata; - if ((ret = ((*(enc->decrypt))(&ke, ivec, &d1, &d2))) != 0) + ret = (*enc->decrypt)(&ke, ivec, &d1, &d2); + if (ret != 0) goto cleanup; if (ivec != NULL && ivec->length == blocksize) { @@ -147,18 +144,19 @@ krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc, 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); + cn = (unsigned char *) d1.data + blocksize * (nblocks - 2); } else abort(); } else cn = NULL; - /* verify the hash */ + /* Verify the hash. */ d1.length = hashsize; d1.data = (char *) cksum; - if ((ret = krb5_hmac(hash, &ki, 1, &d2, &d1)) != 0) + ret = krb5_hmac(hash, &ki, 1, &d2, &d1); + if (ret != 0) goto cleanup; if (memcmp(cksum, input->data+enclen, hmacsize) != 0) { @@ -166,14 +164,16 @@ krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc, goto cleanup; } - /* because this encoding isn't self-describing wrt length, the - best we can do here is to compute the length minus the - confounder. */ + /* + * Because this encoding isn't self-describing wrt length, the + * best we can do here is to compute the length minus the + * confounder. + */ plainlen = enclen - blocksize; if (output->length < plainlen) - return(KRB5_BAD_MSIZE); + return KRB5_BAD_MSIZE; output->length = plainlen; @@ -182,19 +182,10 @@ krb5_dk_decrypt_maybe_trunc_hmac(const struct krb5_enc_provider *enc, if (cn != NULL) memcpy(ivec->data, cn, blocksize); - ret = 0; - cleanup: - memset(kedata, 0, keylength); - memset(kidata, 0, keylength); - memset(plaindata, 0, enclen); - memset(cksum, 0, hashsize); - - free(cksum); - free(plaindata); - free(kidata); - free(kedata); - - return(ret); + zapfree(kedata, keylength); + zapfree(kidata, keylength); + zapfree(plaindata, enclen); + zapfree(cksum, hashsize); + return ret; } - diff --git a/src/lib/crypto/krb/dk/dk_encrypt.c b/src/lib/crypto/krb/dk/dk_encrypt.c index 6596e53ce..b06079c63 100644 --- a/src/lib/crypto/krb/dk/dk_encrypt.c +++ b/src/lib/crypto/krb/dk/dk_encrypt.c @@ -29,12 +29,14 @@ #define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */ -/* the spec says that the confounder size and padding are specific to - the encryption algorithm. This code (dk_encrypt_length and - dk_encrypt) assume the confounder is always the blocksize, and the - padding is always zero bytes up to the blocksize. If these - assumptions ever fails, the keytype table should be extended to - include these bits of info. */ +/* + * The spec says that the confounder size and padding are specific to + * the encryption algorithm. This code (dk_encrypt_length and + * dk_encrypt) assume the confounder is always the blocksize, and the + * padding is always zero bytes up to the blocksize. If these + * assumptions ever fails, the keytype table should be extended to + * include these bits of info. + */ void krb5_dk_encrypt_length(const struct krb5_enc_provider *enc, @@ -45,7 +47,7 @@ krb5_dk_encrypt_length(const struct krb5_enc_provider *enc, blocksize = enc->block_size; hashsize = hash->hashsize; - *length = krb5_roundup(blocksize+inputlen, blocksize) + hashsize; + *length = krb5_roundup(blocksize + inputlen, blocksize) + hashsize; } krb5_error_code @@ -55,46 +57,43 @@ krb5_dk_encrypt(const struct krb5_enc_provider *enc, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { - size_t blocksize, keybytes, keylength, plainlen, enclen; + size_t blocksize, keylength, plainlen, enclen; krb5_error_code ret; unsigned char constantdata[K5CLENGTH]; krb5_data d1, d2; - unsigned char *plaintext, *kedata, *kidata; + unsigned char *plaintext = NULL, *kedata = NULL, *kidata = NULL; char *cn; krb5_keyblock ke, ki; - /* allocate and set up plaintext and to-be-derived keys */ - blocksize = enc->block_size; - keybytes = enc->keybytes; keylength = enc->keylength; - plainlen = krb5_roundup(blocksize+input->length, blocksize); + plainlen = krb5_roundup(blocksize + input->length, blocksize); krb5_dk_encrypt_length(enc, hash, input->length, &enclen); - /* key->length, ivec will be tested in enc->encrypt */ + /* key->length, ivec will be tested in enc->encrypt. */ if (output->length < enclen) return(KRB5_BAD_MSIZE); - if ((kedata = (unsigned char *) malloc(keylength)) == NULL) - return(ENOMEM); - if ((kidata = (unsigned char *) malloc(keylength)) == NULL) { - free(kedata); - return(ENOMEM); - } - if ((plaintext = (unsigned char *) malloc(plainlen)) == NULL) { - free(kidata); - free(kedata); - return(ENOMEM); - } + /* Allocate and set up plaintext and to-be-derived keys. */ + + kedata = k5alloc(keylength, &ret); + if (ret != 0) + goto cleanup; + kidata = k5alloc(keylength, &ret); + if (ret != 0) + goto cleanup; + plaintext = k5alloc(plainlen, &ret); + if (ret != 0) + goto cleanup; ke.contents = kedata; ke.length = keylength; ki.contents = kidata; ki.length = keylength; - /* derive the keys */ + /* Derive the keys. */ d1.data = (char *) constantdata; d1.length = K5CLENGTH; @@ -103,28 +102,31 @@ krb5_dk_encrypt(const struct krb5_enc_provider *enc, d1.data[4] = (char) 0xAA; - if ((ret = krb5_derive_key(enc, key, &ke, &d1))) + ret = krb5_derive_key(enc, key, &ke, &d1); + if (ret != 0) goto cleanup; d1.data[4] = 0x55; - if ((ret = krb5_derive_key(enc, key, &ki, &d1))) + ret = krb5_derive_key(enc, key, &ki, &d1); + if (ret != 0) goto cleanup; - /* put together the plaintext */ + /* Put together the plaintext. */ d1.length = blocksize; d1.data = (char *) plaintext; - if ((ret = krb5_c_random_make_octets(/* XXX */ 0, &d1))) + ret = krb5_c_random_make_octets(/* XXX */ 0, &d1); + if (ret != 0) goto cleanup; - memcpy(plaintext+blocksize, input->data, input->length); + memcpy(plaintext + blocksize, input->data, input->length); - memset(plaintext+blocksize+input->length, 0, - plainlen - (blocksize+input->length)); + memset(plaintext + blocksize + input->length, 0, + plainlen - (blocksize + input->length)); - /* encrypt the plaintext */ + /* Encrypt the plaintext. */ d1.length = plainlen; d1.data = (char *) plaintext; @@ -132,7 +134,8 @@ krb5_dk_encrypt(const struct krb5_enc_provider *enc, d2.length = plainlen; d2.data = output->data; - if ((ret = ((*(enc->encrypt))(&ke, ivec, &d1, &d2)))) + ret = (*enc->encrypt)(&ke, ivec, &d1, &d2); + if (ret != 0) goto cleanup; if (ivec != NULL && ivec->length == blocksize) @@ -140,34 +143,28 @@ krb5_dk_encrypt(const struct krb5_enc_provider *enc, else cn = NULL; - /* hash the plaintext */ + /* Hash the plaintext. */ d2.length = enclen - plainlen; d2.data = output->data+plainlen; output->length = enclen; - if ((ret = krb5_hmac(hash, &ki, 1, &d1, &d2))) { + ret = krb5_hmac(hash, &ki, 1, &d1, &d2); + if (ret != 0) { memset(d2.data, 0, d2.length); goto cleanup; } - /* update ivec */ + /* Update ivec. */ if (cn != NULL) memcpy(ivec->data, cn, blocksize); - /* ret is set correctly by the prior call */ - cleanup: - memset(kedata, 0, keylength); - memset(kidata, 0, keylength); - memset(plaintext, 0, plainlen); - - free(plaintext); - free(kidata); - free(kedata); - - return(ret); + zapfree(kedata, keylength); + zapfree(kidata, keylength); + zapfree(plaintext, plainlen); + return ret; } /* Not necessarily "AES", per se, but "a CBC+CTS mode block cipher @@ -222,7 +219,7 @@ krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc, krb5_error_code ret; unsigned char constantdata[K5CLENGTH]; krb5_data d1, d2; - unsigned char *plaintext, *kedata, *kidata; + unsigned char *plaintext = NULL, *kedata = NULL, *kidata = NULL; char *cn; krb5_keyblock ke, ki; @@ -238,26 +235,24 @@ krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc, /* key->length, ivec will be tested in enc->encrypt */ if (output->length < enclen) - return(KRB5_BAD_MSIZE); + return KRB5_BAD_MSIZE; - if ((kedata = (unsigned char *) malloc(keylength)) == NULL) - return(ENOMEM); - if ((kidata = (unsigned char *) malloc(keylength)) == NULL) { - free(kedata); - return(ENOMEM); - } - if ((plaintext = (unsigned char *) malloc(plainlen)) == NULL) { - free(kidata); - free(kedata); - return(ENOMEM); - } + kedata = k5alloc(keylength, &ret); + if (ret != 0) + goto cleanup; + kidata = k5alloc(keylength, &ret); + if (ret != 0) + goto cleanup; + plaintext = k5alloc(plainlen, &ret); + if (ret != 0) + goto cleanup; ke.contents = kedata; ke.length = keylength; ki.contents = kidata; ki.length = keylength; - /* derive the keys */ + /* Derive the keys. */ d1.data = (char *) constantdata; d1.length = K5CLENGTH; @@ -266,12 +261,14 @@ krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc, d1.data[4] = (char) 0xAA; - if ((ret = krb5_derive_key(enc, key, &ke, &d1))) + ret = krb5_derive_key(enc, key, &ke, &d1); + if (ret != 0) goto cleanup; d1.data[4] = 0x55; - if ((ret = krb5_derive_key(enc, key, &ki, &d1))) + ret = krb5_derive_key(enc, key, &ki, &d1); + if (ret != 0) goto cleanup; /* put together the plaintext */ @@ -279,16 +276,17 @@ krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc, d1.length = blocksize; d1.data = (char *) plaintext; - if ((ret = krb5_c_random_make_octets(/* XXX */ 0, &d1))) + ret = krb5_c_random_make_octets(NULL, &d1); + if (ret != 0) goto cleanup; - memcpy(plaintext+blocksize, input->data, input->length); + memcpy(plaintext + blocksize, input->data, input->length); /* Ciphertext stealing; there should be no more. */ if (plainlen != blocksize + input->length) abort(); - /* encrypt the plaintext */ + /* Encrypt the plaintext. */ d1.length = plainlen; d1.data = (char *) plaintext; @@ -296,7 +294,8 @@ krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc, d2.length = plainlen; d2.data = output->data; - if ((ret = ((*(enc->encrypt))(&ke, ivec, &d1, &d2)))) + ret = (*enc->encrypt)(&ke, ivec, &d1, &d2); + if (ret != 0) goto cleanup; if (ivec != NULL && ivec->length == blocksize) { @@ -305,54 +304,29 @@ krb5int_aes_dk_encrypt(const struct krb5_enc_provider *enc, } else cn = NULL; - /* hash the plaintext */ + /* Hash the plaintext. */ d2.length = enclen - plainlen; d2.data = output->data+plainlen; if (d2.length != 96 / 8) abort(); - if ((ret = trunc_hmac(hash, &ki, 1, &d1, &d2))) { + ret = trunc_hmac(hash, &ki, 1, &d1, &d2); + if (ret != 0) { memset(d2.data, 0, d2.length); goto cleanup; } output->length = enclen; - /* update ivec */ - if (cn != NULL) { + /* Update ivec. */ + 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 */ cleanup: - memset(kedata, 0, keylength); - memset(kidata, 0, keylength); - memset(plaintext, 0, plainlen); - - free(plaintext); - free(kidata); - free(kedata); - - return(ret); + zapfree(kedata, keylength); + zapfree(kidata, keylength); + zapfree(plaintext, plainlen); + return ret; } diff --git a/src/lib/crypto/krb/dk/stringtokey.c b/src/lib/crypto/krb/dk/stringtokey.c index 0e54b849f..326565758 100644 --- a/src/lib/crypto/krb/dk/stringtokey.c +++ b/src/lib/crypto/krb/dk/stringtokey.c @@ -36,34 +36,32 @@ krb5int_dk_string_to_key(const struct krb5_enc_provider *enc, { krb5_error_code ret; size_t keybytes, keylength, concatlen; - unsigned char *concat, *foldstring, *foldkeydata; + unsigned char *concat = NULL, *foldstring = NULL, *foldkeydata = NULL; krb5_data indata; krb5_keyblock foldkey; - /* key->length is checked by krb5_derive_key */ + /* key->length is checked by krb5_derive_key. */ keybytes = enc->keybytes; keylength = enc->keylength; - concatlen = string->length+(salt?salt->length:0); + concatlen = string->length + (salt ? salt->length : 0); - if ((concat = (unsigned char *) malloc(concatlen)) == NULL) - return(ENOMEM); - if ((foldstring = (unsigned char *) malloc(keybytes)) == NULL) { - free(concat); - return(ENOMEM); - } - if ((foldkeydata = (unsigned char *) malloc(keylength)) == NULL) { - free(foldstring); - free(concat); - return(ENOMEM); - } + concat = k5alloc(concatlen, &ret); + if (ret != 0) + goto cleanup; + foldstring = k5alloc(keybytes, &ret); + if (ret != 0) + goto cleanup; + foldkeydata = k5alloc(keylength, &ret); + if (ret != 0) + goto cleanup; /* construct input string ( = string + salt), fold it, make_key it */ memcpy(concat, string->data, string->length); if (salt) - memcpy(concat+string->length, salt->data, salt->length); + memcpy(concat + string->length, salt->data, salt->length); krb5_nfold(concatlen*8, concat, keybytes*8, foldstring); @@ -72,25 +70,22 @@ krb5int_dk_string_to_key(const struct krb5_enc_provider *enc, foldkey.length = keylength; foldkey.contents = foldkeydata; - (*(enc->make_key))(&indata, &foldkey); + ret = (*enc->make_key)(&indata, &foldkey); + if (ret != 0) + goto cleanup; /* now derive the key from this one */ indata.length = kerberos_len; indata.data = (char *) kerberos; - if ((ret = krb5_derive_key(enc, &foldkey, key, &indata))) + ret = krb5_derive_key(enc, &foldkey, key, &indata); + if (ret != 0) memset(key->contents, 0, key->length); - /* ret is set correctly by the prior call */ - - memset(concat, 0, concatlen); - memset(foldstring, 0, keybytes); - memset(foldkeydata, 0, keylength); - - free(foldkeydata); - free(foldstring); - free(concat); - - return(ret); +cleanup: + zapfree(concat, concatlen); + zapfree(foldstring, keybytes); + zapfree(foldkeydata, keylength); + return ret; } -- 2.26.2