summaryrefslogtreecommitdiffstats
path: root/src/lib/crypto/crypto_tests
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2009-10-19 20:04:21 +0000
committerGreg Hudson <ghudson@mit.edu>2009-10-19 20:04:21 +0000
commite6b93b7dd43bb765900b2db71641479b597844da (patch)
tree2b6da09e37da6ca699a8cb43c87e8a4218132254 /src/lib/crypto/crypto_tests
parent04a5d19e61bedbb1da4db52334c00f7a54a9d5a8 (diff)
downloadkrb5-e6b93b7dd43bb765900b2db71641479b597844da.tar.gz
krb5-e6b93b7dd43bb765900b2db71641479b597844da.tar.xz
krb5-e6b93b7dd43bb765900b2db71641479b597844da.zip
Implement new APIs to allow improved crypto performance
Merge branches/enc-perf to trunk. Adds the krb5_key opaque type, the krb5_k_* APIs to use them, and caching of derived keys when krb5_k_* functions are used. Updates the krb5 auth context and GSS id-rec to use krb5_keys. ticket: 6576 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@22944 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/crypto/crypto_tests')
-rw-r--r--src/lib/crypto/crypto_tests/Makefile.in4
-rw-r--r--src/lib/crypto/crypto_tests/aes-test.c6
-rw-r--r--src/lib/crypto/crypto_tests/t_cksum.c9
-rw-r--r--src/lib/crypto/crypto_tests/t_cts.c23
-rw-r--r--src/lib/crypto/crypto_tests/t_encrypt.c128
-rw-r--r--src/lib/crypto/crypto_tests/t_hmac.c5
-rw-r--r--src/lib/crypto/crypto_tests/t_kperf.c119
7 files changed, 239 insertions, 55 deletions
diff --git a/src/lib/crypto/crypto_tests/Makefile.in b/src/lib/crypto/crypto_tests/Makefile.in
index ab6ebfa4c6..7b240d5783 100644
--- a/src/lib/crypto/crypto_tests/Makefile.in
+++ b/src/lib/crypto/crypto_tests/Makefile.in
@@ -33,6 +33,7 @@ EXTRADEPSRCS=\
$(srcdir)/t_shs3.c \
$(srcdir)/t_shs.c \
$(srcdir)/t_verify.c \
+ $(srcdir)/t_kperf.c \
$(srcdir)/ytest.c
##DOSBUILDTOP = ..\..\..
@@ -149,6 +150,9 @@ t_shs: t_shs.o $(SUPPORT_DEPLIB) $(CRYPTO_DEPLIB)
t_shs3: t_shs3.o $(SUPPORT_DEPLIB) $(CRYPTO_DEPLIB)
$(CC_LINK) -o t_shs3 t_shs3.o $(SUPPORT_LIB) $(CRYPTO_DEPLIB)
+t_kperf: t_kperf.o $(SUPPORT_DEPLIB) $(CRYPTO_DEPLIB)
+ $(CC_LINK) -o t_kperf t_kperf.o $(SUPPORT_LIB) $(CRYPTO_DEPLIB)
+
ytest: ytest.o shs.o $(SUPPORT_DEPLIB) $(CRYPTO_DEPLIB)
$(CC_LINK) -o ytest ytest.o $(SUPPORT_LIB) $(CRYPTO_DEPLIB)
diff --git a/src/lib/crypto/crypto_tests/aes-test.c b/src/lib/crypto/crypto_tests/aes-test.c
index c05fd26e3c..8999bd7578 100644
--- a/src/lib/crypto/crypto_tests/aes-test.c
+++ b/src/lib/crypto/crypto_tests/aes-test.c
@@ -50,7 +50,11 @@ static void init()
}
static void enc()
{
- krb5int_aes_encrypt(&enc_key, &ivec, &in, &out);
+ krb5_key key;
+
+ krb5_k_create_key(NULL, &enc_key, &key);
+ krb5int_aes_encrypt(key, &ivec, &in, &out);
+ krb5_k_free_key(NULL, key);
}
static void hexdump(const char *label, const char *cp, int len)
diff --git a/src/lib/crypto/crypto_tests/t_cksum.c b/src/lib/crypto/crypto_tests/t_cksum.c
index 98187f7f16..2b53651197 100644
--- a/src/lib/crypto/crypto_tests/t_cksum.c
+++ b/src/lib/crypto/crypto_tests/t_cksum.c
@@ -75,6 +75,7 @@ main(argc, argv)
krb5_boolean valid;
size_t length;
krb5_keyblock keyblock;
+ krb5_key key;
krb5_error_code kret=0;
krb5_data plaintext, newstyle_checksum;
@@ -89,6 +90,8 @@ main(argc, argv)
keyblock.length = sizeof(testkey);
keyblock.contents = testkey;
+ krb5_k_create_key(NULL, &keyblock, &key);
+
length = khp.hashsize;
newstyle_checksum.length = length;
@@ -102,13 +105,13 @@ main(argc, argv)
plaintext.length = strlen(argv[msgindex]);
plaintext.data = argv[msgindex];
- if ((kret = (*(khp.hash))(&keyblock, 0, 0, &plaintext, &newstyle_checksum))) {
+ if ((kret = (*(khp.hash))(key, 0, 0, &plaintext, &newstyle_checksum))) {
printf("krb5_calculate_checksum choked with %d\n", kret);
break;
}
print_checksum("correct", MD, argv[msgindex], &newstyle_checksum);
- if ((kret = (*(khp.verify))(&keyblock, 0, 0, &plaintext, &newstyle_checksum,
+ if ((kret = (*(khp.verify))(key, 0, 0, &plaintext, &newstyle_checksum,
&valid))) {
printf("verify on new checksum choked with %d\n", kret);
break;
@@ -120,7 +123,7 @@ main(argc, argv)
printf("Verify succeeded for \"%s\"\n", argv[msgindex]);
newstyle_checksum.data[0]++;
- if ((kret = (*(khp.verify))(&keyblock, 0, 0, &plaintext, &newstyle_checksum,
+ if ((kret = (*(khp.verify))(key, 0, 0, &plaintext, &newstyle_checksum,
&valid))) {
printf("verify on new checksum choked with %d\n", kret);
break;
diff --git a/src/lib/crypto/crypto_tests/t_cts.c b/src/lib/crypto/crypto_tests/t_cts.c
index aef813273f..fab5b27071 100644
--- a/src/lib/crypto/crypto_tests/t_cts.c
+++ b/src/lib/crypto/crypto_tests/t_cts.c
@@ -114,15 +114,12 @@ static void test_cts()
"I would like the General Gau's Chicken, please, and wonton soup.";
static const unsigned char aeskey[16] = "chicken teriyaki";
static const int lengths[] = { 17, 31, 32, 47, 48, 64 };
- extern krb5_error_code krb5int_aes_encrypt(const krb5_keyblock *,
- const krb5_data *,
- const krb5_data *,
- krb5_data *);
int i;
char outbuf[64], encivbuf[16], decivbuf[16], outbuf2[64];
krb5_data in, out, enciv, deciv, out2;
- krb5_keyblock key;
+ krb5_keyblock keyblock;
+ krb5_key key;
krb5_error_code err;
in.data = input;
@@ -131,11 +128,17 @@ static void test_cts()
enciv.length = deciv.length = 16;
enciv.data = encivbuf;
deciv.data = decivbuf;
- key.contents = aeskey;
- key.length = 16;
+ keyblock.contents = aeskey;
+ keyblock.length = 16;
+
+ err = krb5_k_create_key(NULL, &keyblock, &key);
+ if (err) {
+ printf("error %ld from krb5_k_create_key\n", (long)err);
+ exit(1);
+ }
memset(enciv.data, 0, 16);
- printk("AES 128-bit key", &key);
+ printk("AES 128-bit key", &keyblock);
for (i = 0; i < sizeof(lengths)/sizeof(lengths[0]); i++) {
memset(enciv.data, 0, 16);
memset(deciv.data, 0, 16);
@@ -143,7 +146,7 @@ static void test_cts()
printf("\n");
in.length = out.length = lengths[i];
printd("IV", &enciv);
- err = krb5int_aes_encrypt(&key, &enciv, &in, &out);
+ err = krb5int_aes_encrypt(key, &enciv, &in, &out);
if (err) {
printf("error %ld from krb5int_aes_encrypt\n", (long)err);
exit(1);
@@ -152,7 +155,7 @@ static void test_cts()
printd("Output", &out);
printd("Next IV", &enciv);
out2.length = out.length;
- err = krb5int_aes_decrypt(&key, &deciv, &out, &out2);
+ err = krb5int_aes_decrypt(key, &deciv, &out, &out2);
if (err) {
printf("error %ld from krb5int_aes_decrypt\n", (long)err);
exit(1);
diff --git a/src/lib/crypto/crypto_tests/t_encrypt.c b/src/lib/crypto/crypto_tests/t_encrypt.c
index 739c6d3e0b..aac31fb21f 100644
--- a/src/lib/crypto/crypto_tests/t_encrypt.c
+++ b/src/lib/crypto/crypto_tests/t_encrypt.c
@@ -78,12 +78,14 @@ int
main ()
{
krb5_context context = 0;
- krb5_data in, in2, out, out2, check, check2, state;
+ krb5_data in, in2, out, out2, check, check2, state, signdata;
krb5_crypto_iov iov[5];
- int i;
+ int i, j, pos;
+ unsigned int dummy;
size_t len;
krb5_enc_data enc_out, enc_out2;
- krb5_keyblock *key;
+ krb5_keyblock *keyblock;
+ krb5_key key;
memset(iov, 0, sizeof(iov));
@@ -94,6 +96,8 @@ main ()
test ("Seeding random number generator",
krb5_c_random_seed (context, &in));
+
+ /* Set up output buffers. */
out.data = malloc(2048);
out2.data = malloc(2048);
check.data = malloc(2048);
@@ -107,39 +111,67 @@ main ()
out2.length = 2048;
check.length = 2048;
check2.length = 2048;
+
for (i = 0; interesting_enctypes[i]; i++) {
krb5_enctype enctype = interesting_enctypes [i];
+
printf ("Testing enctype %d\n", enctype);
test ("Initializing a keyblock",
- krb5_init_keyblock (context, enctype, 0, &key));
- test ("Generating random key",
- krb5_c_make_random_key (context, enctype, key));
+ krb5_init_keyblock (context, enctype, 0, &keyblock));
+ test ("Generating random keyblock",
+ krb5_c_make_random_key (context, enctype, keyblock));
+ test ("Creating opaque key from keyblock",
+ krb5_k_create_key (context, keyblock, &key));
+
enc_out.ciphertext = out;
enc_out2.ciphertext = out2;
/* We use an intermediate `len' because size_t may be different size
than `int' */
- krb5_c_encrypt_length (context, key->enctype, in.length, &len);
+ krb5_c_encrypt_length (context, keyblock->enctype, in.length, &len);
enc_out.ciphertext.length = len;
- test ("Encrypting",
- krb5_c_encrypt (context, key, 7, 0, &in, &enc_out));
+
+ /* Encrypt, decrypt, and see if we got the plaintext back again. */
+ test ("Encrypting (c)",
+ krb5_c_encrypt (context, keyblock, 7, 0, &in, &enc_out));
test ("Decrypting",
- krb5_c_decrypt (context, key, 7, 0, &enc_out, &check));
+ krb5_c_decrypt (context, keyblock, 7, 0, &enc_out, &check));
test ("Comparing", compare_results (&in, &check));
- if ( krb5_c_crypto_length(context, key->enctype, KRB5_CRYPTO_TYPE_HEADER, &len) == 0 ){
- /* We support iov/aead*/
- int j, pos;
- krb5_data signdata;
- signdata.magic = KV5M_DATA;
- signdata.data = (char *) "This should be signed";
- signdata.length = strlen(signdata.data);
+
+ /* Try again with the opaque-key-using variants. */
+ memset(out.data, 0, out.length);
+ test ("Encrypting (k)",
+ krb5_k_encrypt (context, key, 7, 0, &in, &enc_out));
+ test ("Decrypting",
+ krb5_k_decrypt (context, key, 7, 0, &enc_out, &check));
+ test ("Comparing", compare_results (&in, &check));
+
+ /* Check if this enctype supports IOV encryption. */
+ if ( krb5_c_crypto_length(context, keyblock->enctype,
+ KRB5_CRYPTO_TYPE_HEADER, &dummy) == 0 ){
+ /* Set up iovecs for stream decryption. */
+ memcpy(out2.data, enc_out.ciphertext.data, enc_out.ciphertext.length);
iov[0].flags= KRB5_CRYPTO_TYPE_STREAM;
+ iov[0].data.data = out2.data;
+ iov[0].data.length = enc_out.ciphertext.length;
iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
- iov[0].data = enc_out.ciphertext;
- iov[1].data = out;
- test("IOV stream decrypting",
- krb5_c_decrypt_iov( context, key, 7, 0, iov, 2));
+
+ /* Decrypt the encrypted data from above and check it. */
+ test("IOV stream decrypting (c)",
+ krb5_c_decrypt_iov( context, keyblock, 7, 0, iov, 2));
test("Comparing results",
compare_results(&in, &iov[1].data));
+
+ /* Try again with the opaque-key-using variant. */
+ memcpy(out2.data, enc_out.ciphertext.data, enc_out.ciphertext.length);
+ test("IOV stream decrypting (k)",
+ krb5_k_decrypt_iov( context, key, 7, 0, iov, 2));
+ test("Comparing results",
+ compare_results(&in, &iov[1].data));
+
+ /* Set up iovecs for AEAD encryption. */
+ signdata.magic = KV5M_DATA;
+ signdata.data = (char *) "This should be signed";
+ signdata.length = strlen(signdata.data);
iov[0].flags = KRB5_CRYPTO_TYPE_HEADER;
iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
iov[1].data = in; /*We'll need to copy memory before encrypt*/
@@ -147,8 +179,10 @@ main ()
iov[2].data = signdata;
iov[3].flags = KRB5_CRYPTO_TYPE_PADDING;
iov[4].flags = KRB5_CRYPTO_TYPE_TRAILER;
+
+ /* "Allocate" data for the iovec buffers from the "out" buffer. */
test("Setting up iov lengths",
- krb5_c_crypto_length_iov(context, key->enctype, iov, 5));
+ krb5_c_crypto_length_iov(context, keyblock->enctype, iov, 5));
for (j=0,pos=0; j <= 4; j++ ){
if (iov[j].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY)
continue;
@@ -157,56 +191,70 @@ main ()
}
assert (iov[1].data.length == in.length);
memcpy(iov[1].data.data, in.data, in.length);
- test("iov encrypting",
- krb5_c_encrypt_iov(context, key, 7, 0, iov, 5));
+
+ /* Encrypt and decrypt in place, and check the result. */
+ test("iov encrypting (c)",
+ krb5_c_encrypt_iov(context, keyblock, 7, 0, iov, 5));
assert(iov[1].data.length == in.length);
test("iov decrypting",
- krb5_c_decrypt_iov(context, key, 7, 0, iov, 5));
+ krb5_c_decrypt_iov(context, keyblock, 7, 0, iov, 5));
test("Comparing results",
compare_results(&in, &iov[1].data));
+ /* Try again with opaque-key-using variants. */
+ test("iov encrypting (k)",
+ krb5_k_encrypt_iov(context, key, 7, 0, iov, 5));
+ assert(iov[1].data.length == in.length);
+ test("iov decrypting",
+ krb5_k_decrypt_iov(context, key, 7, 0, iov, 5));
+ test("Comparing results",
+ compare_results(&in, &iov[1].data));
}
+
enc_out.ciphertext.length = out.length;
check.length = 2048;
+
test ("init_state",
- krb5_c_init_state (context, key, 7, &state));
+ krb5_c_init_state (context, keyblock, 7, &state));
test ("Encrypting with state",
- krb5_c_encrypt (context, key, 7, &state, &in, &enc_out));
+ krb5_c_encrypt (context, keyblock, 7, &state, &in, &enc_out));
test ("Encrypting again with state",
- krb5_c_encrypt (context, key, 7, &state, &in2, &enc_out2));
+ krb5_c_encrypt (context, keyblock, 7, &state, &in2, &enc_out2));
test ("free_state",
- krb5_c_free_state (context, key, &state));
+ krb5_c_free_state (context, keyblock, &state));
test ("init_state",
- krb5_c_init_state (context, key, 7, &state));
+ krb5_c_init_state (context, keyblock, 7, &state));
test ("Decrypting with state",
- krb5_c_decrypt (context, key, 7, &state, &enc_out, &check));
+ krb5_c_decrypt (context, keyblock, 7, &state, &enc_out, &check));
test ("Decrypting again with state",
- krb5_c_decrypt (context, key, 7, &state, &enc_out2, &check2));
+ krb5_c_decrypt (context, keyblock, 7, &state, &enc_out2, &check2));
test ("free_state",
- krb5_c_free_state (context, key, &state));
+ krb5_c_free_state (context, keyblock, &state));
test ("Comparing",
compare_results (&in, &check));
test ("Comparing",
compare_results (&in2, &check2));
- krb5_free_keyblock (context, key);
+
+ krb5_free_keyblock (context, keyblock);
+ krb5_k_free_key (context, key);
}
/* Test the RC4 decrypt fallback from key usage 9 to 8. */
test ("Initializing an RC4 keyblock",
- krb5_init_keyblock (context, ENCTYPE_ARCFOUR_HMAC, 0, &key));
+ krb5_init_keyblock (context, ENCTYPE_ARCFOUR_HMAC, 0, &keyblock));
test ("Generating random RC4 key",
- krb5_c_make_random_key (context, ENCTYPE_ARCFOUR_HMAC, key));
+ krb5_c_make_random_key (context, ENCTYPE_ARCFOUR_HMAC, keyblock));
enc_out.ciphertext = out;
- krb5_c_encrypt_length (context, key->enctype, in.length, &len);
+ krb5_c_encrypt_length (context, keyblock->enctype, in.length, &len);
enc_out.ciphertext.length = len;
check.length = 2048;
test ("Encrypting with RC4 key usage 8",
- krb5_c_encrypt (context, key, 8, 0, &in, &enc_out));
+ krb5_c_encrypt (context, keyblock, 8, 0, &in, &enc_out));
test ("Decrypting with RC4 key usage 9",
- krb5_c_decrypt (context, key, 9, 0, &enc_out, &check));
+ krb5_c_decrypt (context, keyblock, 9, 0, &enc_out, &check));
test ("Comparing", compare_results (&in, &check));
- krb5_free_keyblock (context, key);
+ krb5_free_keyblock (context, keyblock);
free(out.data);
free(out2.data);
free(check.data);
diff --git a/src/lib/crypto/crypto_tests/t_hmac.c b/src/lib/crypto/crypto_tests/t_hmac.c
index bf629c359f..30830d6173 100644
--- a/src/lib/crypto/crypto_tests/t_hmac.c
+++ b/src/lib/crypto/crypto_tests/t_hmac.c
@@ -98,6 +98,7 @@ static krb5_error_code hmac1(const struct krb5_hash_provider *h,
char tmp[40];
size_t blocksize, hashsize;
krb5_error_code err;
+ krb5_key k;
printk(" test key", key);
blocksize = h->blocksize;
@@ -120,7 +121,9 @@ static krb5_error_code hmac1(const struct krb5_hash_provider *h,
printk(" pre-hashed key", key);
}
printd(" hmac input", in);
- err = krb5_hmac(h, key, 1, in, out);
+ krb5_k_create_key(NULL, key, &k);
+ err = krb5_hmac(h, k, 1, in, out);
+ krb5_k_free_key(NULL, k);
if (err == 0)
printd(" hmac output", out);
return err;
diff --git a/src/lib/crypto/crypto_tests/t_kperf.c b/src/lib/crypto/crypto_tests/t_kperf.c
new file mode 100644
index 0000000000..f56aa3cd15
--- /dev/null
+++ b/src/lib/crypto/crypto_tests/t_kperf.c
@@ -0,0 +1,119 @@
+/* -*- mode: c; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/crypto_tests/t_kperf.c
+ *
+ * Copyright (C) 2009 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * 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
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/*
+ * This file contains a harness to measure the performance improvement
+ * of using the the krb5_k functions (which cache derived keys) over
+ * the equivalent krb5_c functions which do not. Sample usages:
+ *
+ * ./t_kperf ce aes128-cts 10 100000
+ * ./t_kperf kv aes256-cts 1024 10000
+ *
+ * The first usage encrypts ('e') a hundred thousand ten-byte blobs
+ * with aes128-cts, using the non-caching APIs ('c'). The second
+ * usage verifies ('v') ten thousand checksums over 1K blobs with the
+ * first available keyed checksum type for aes256-cts, using the
+ * caching APIs ('k'). Run commands under "time" to measure how much
+ * time is used by the operations.
+ */
+
+#include "k5-int.h"
+
+int
+main(int argc, char **argv)
+{
+ krb5_keyblock kblock;
+ krb5_key key;
+ krb5_enctype enctype;
+ krb5_cksumtype cktype, *cktypelist;
+ int blocksize, num_blocks, intf, op, i;
+ unsigned int count;
+ size_t outlen, cklen;
+ krb5_data block;
+ krb5_enc_data outblock;
+ krb5_checksum sum;
+ krb5_boolean val;
+
+ if (argc != 5) {
+ fprintf(stderr, "Usage: t_kperf {c|k}{e|d|m|v} type size nblocks\n");
+ exit(1);
+ }
+ intf = argv[1][0];
+ assert(intf == 'c' || intf =='k');
+ op = argv[1][1];
+ assert(krb5_string_to_enctype(argv[2], &enctype) == 0);
+ blocksize = atoi(argv[3]);
+ num_blocks = atoi(argv[4]);
+
+ /* Pick the first available keyed checksum type. */
+ krb5_c_keyed_checksum_types(NULL, enctype, &count, &cktypelist);
+ assert(count > 0);
+ cktype = cktypelist[0];
+
+ block.data = "notrandom";
+ block.length = 9;
+ krb5_c_random_seed(NULL, &block);
+
+ krb5_c_make_random_key(NULL, enctype, &kblock);
+ krb5_k_create_key(NULL, &kblock, &key);
+
+ block.length = blocksize;
+ block.data = calloc(1, blocksize);
+
+ krb5_c_encrypt_length(NULL, enctype, blocksize, &outlen);
+ outblock.enctype = enctype;
+ outblock.ciphertext.length = outlen;
+ outblock.ciphertext.data = calloc(1, outlen);
+
+ krb5_c_checksum_length(NULL, cktype, &cklen);
+ sum.checksum_type = cktype;
+ sum.length = cklen;
+ sum.contents = calloc(1, cklen);
+
+ for (i = 0; i < num_blocks; i++) {
+ if (intf == 'c') {
+ if (op == 'e')
+ krb5_c_encrypt(NULL, &kblock, 0, NULL, &block, &outblock);
+ else if (op == 'd')
+ krb5_c_decrypt(NULL, &kblock, 0, NULL, &outblock, &block);
+ else if (op == 'm')
+ krb5_c_make_checksum(NULL, cktype, &kblock, 0, &block, &sum);
+ else if (op == 'v')
+ krb5_c_verify_checksum(NULL, &kblock, 0, &block, &sum, &val);
+ } else {
+ if (op == 'e')
+ krb5_k_encrypt(NULL, key, 0, NULL, &block, &outblock);
+ else if (op == 'd')
+ krb5_k_decrypt(NULL, key, 0, NULL, &outblock, &block);
+ else if (op == 'm')
+ krb5_k_make_checksum(NULL, cktype, key, 0, &block, &sum);
+ else if (op == 'v')
+ krb5_k_verify_checksum(NULL, key, 0, &block, &sum, &val);
+ }
+ }
+ return 0;
+}