svn rev #22919: branches/enc-perf/src/ include/ lib/crypto/krb/ lib/crypto/krb/dk/
ghudson@MIT.EDU
ghudson at MIT.EDU
Sun Oct 18 14:28:27 EDT 2009
http://src.mit.edu/fisheye/changelog/krb5/?cs=22919
Commit By: ghudson
Log Message:
Implement derived key caching. For now, omit the "nocache" flag, because it
would add code bulk without necessarily saving much work.
Changed Files:
U branches/enc-perf/src/include/k5-int.h
U branches/enc-perf/src/lib/crypto/krb/dk/derive.c
U branches/enc-perf/src/lib/crypto/krb/key.c
Modified: branches/enc-perf/src/include/k5-int.h
===================================================================
--- branches/enc-perf/src/include/k5-int.h 2009-10-18 17:17:42 UTC (rev 22918)
+++ branches/enc-perf/src/include/k5-int.h 2009-10-18 18:28:26 UTC (rev 22919)
@@ -635,10 +635,17 @@
struct addrlist *, enum locate_service_type svc,
int sockettype, int family);
+struct derived_key {
+ krb5_data constant;
+ krb5_key dkey;
+ struct derived_key *next;
+};
+
/* Internal structure of an opaque key identifier */
struct krb5_key_st {
krb5_keyblock keyblock;
int refcount;
+ struct derived_key *derived;
};
/* new encryption provider api */
Modified: branches/enc-perf/src/lib/crypto/krb/dk/derive.c
===================================================================
--- branches/enc-perf/src/lib/crypto/krb/dk/derive.c 2009-10-18 17:17:42 UTC (rev 22918)
+++ branches/enc-perf/src/lib/crypto/krb/dk/derive.c 2009-10-18 18:28:26 UTC (rev 22919)
@@ -27,6 +27,63 @@
#include "k5-int.h"
#include "dk.h"
+static krb5_key
+find_cached_dkey(struct derived_key *list, const krb5_data *constant)
+{
+ for (; list; list = list->next) {
+ if (data_eq(list->constant, *constant)) {
+ krb5_k_reference_key(NULL, list->dkey);
+ return list->dkey;
+ }
+ }
+ return NULL;
+}
+
+static krb5_error_code
+add_cached_dkey(krb5_key key, const krb5_data *constant,
+ const krb5_keyblock *dkeyblock, krb5_key *cached_dkey)
+{
+ krb5_key dkey;
+ krb5_error_code ret;
+ struct derived_key *dkent = NULL;
+ char *data = NULL;
+
+ /* Allocate fields for the new entry. */
+ dkent = malloc(sizeof(*dkent));
+ if (dkent == NULL)
+ goto cleanup;
+ data = malloc(constant->length);
+ if (data == NULL)
+ goto cleanup;
+ ret = krb5_k_create_key(NULL, dkeyblock, &dkey);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Add the new entry to the list. */
+ memcpy(data, constant->data, constant->length);
+ dkent->dkey = dkey;
+ dkent->constant.data = data;
+ dkent->constant.length = constant->length;
+ dkent->next = key->derived;
+ key->derived = dkent;
+
+ /* Return a "copy" of the cached key. */
+ krb5_k_reference_key(NULL, dkey);
+ *cached_dkey = dkey;
+ return 0;
+
+cleanup:
+ free(dkent);
+ free(data);
+ return ENOMEM;
+}
+
+/*
+ * Compute a derived key into the keyblock outkey. This variation on
+ * krb5_derive_key does not cache the result, as it is only used
+ * directly in situations which are not expected to be repeated with
+ * the same inkey and constant.
+ */
krb5_error_code
krb5_derive_keyblock(const struct krb5_enc_provider *enc,
krb5_key inkey, krb5_keyblock *outkey,
@@ -111,22 +168,33 @@
{
krb5_keyblock keyblock;
krb5_error_code ret;
+ krb5_key dkey;
*outkey = NULL;
- /* Set up a temporary keyblock. */
+ /* Check for a cached result. */
+ dkey = find_cached_dkey(inkey->derived, in_constant);
+ if (dkey != NULL) {
+ *outkey = dkey;
+ return 0;
+ }
+
+ /* Derive into a temporary keyblock. */
keyblock.length = enc->keylength;
keyblock.contents = malloc(keyblock.length);
if (keyblock.contents == NULL)
return ENOMEM;
-
ret = krb5_derive_keyblock(enc, inkey, &keyblock, in_constant);
if (ret)
goto cleanup;
- /* Convert the keyblock to a key. */
- ret = krb5_k_create_key(NULL, &keyblock, outkey);
+ /* Cache the derived key. */
+ ret = add_cached_dkey(inkey, in_constant, &keyblock, &dkey);
+ if (ret != 0)
+ goto cleanup;
+ *outkey = dkey;
+
cleanup:
zapfree(keyblock.contents, keyblock.length);
return ret;
Modified: branches/enc-perf/src/lib/crypto/krb/key.c
===================================================================
--- branches/enc-perf/src/lib/crypto/krb/key.c 2009-10-18 17:17:42 UTC (rev 22918)
+++ branches/enc-perf/src/lib/crypto/krb/key.c 2009-10-18 18:28:26 UTC (rev 22919)
@@ -50,6 +50,7 @@
goto cleanup;
key->refcount = 1;
+ key->derived = NULL;
*out = key;
return 0;
@@ -68,8 +69,17 @@
void KRB5_CALLCONV
krb5_k_free_key(krb5_context context, krb5_key key)
{
+ struct derived_key *dk;
+
if (key == NULL || --key->refcount > 0)
return;
+
+ /* Free the derived key cache. */
+ while ((dk = key->derived) != NULL) {
+ key->derived = dk->next;
+ krb5_k_free_key(context, dk->dkey);
+ free(dk);
+ }
krb5int_c_free_keyblock_contents(context, &key->keyblock);
}
More information about the cvs-krb5
mailing list