summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2010-11-19 22:01:32 +0000
committerGreg Hudson <ghudson@mit.edu>2010-11-19 22:01:32 +0000
commitb085c9946d17fde5801e5fa3dd7dfd8eb0700df9 (patch)
tree4c4d2f665bfd201d4a13252fd97c40f9becab81f
parent2f62797b59b7f10515851f4825d0c112d915cf7f (diff)
downloadkrb5-camellia-cts-cmac.tar.gz
Add Camellia support to the NSS back end. (It was mostly alreadycamellia-cts-cmac
there, but we needed a cbc-mac function.) git-svn-id: svn://anonsvn.mit.edu/krb5/branches/camellia-cts-cmac@24523 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/lib/crypto/nss/enc_provider/camellia.c20
-rw-r--r--src/lib/crypto/nss/enc_provider/enc_gen.c70
-rw-r--r--src/lib/crypto/nss/enc_provider/enc_provider.h4
-rw-r--r--src/lib/crypto/nss/nss_gen.h6
4 files changed, 96 insertions, 4 deletions
diff --git a/src/lib/crypto/nss/enc_provider/camellia.c b/src/lib/crypto/nss/enc_provider/camellia.c
index 06165d281..3a33d90ca 100644
--- a/src/lib/crypto/nss/enc_provider/camellia.c
+++ b/src/lib/crypto/nss/enc_provider/camellia.c
@@ -41,9 +41,7 @@
#ifdef CAMELLIA
-/* XXX This still needs a cbc-mac function. */
-
-krb5_error_code
+static krb5_error_code
krb5int_camellia_encrypt(krb5_key key, const krb5_data *ivec,
krb5_crypto_iov *data, size_t num_data)
{
@@ -56,7 +54,7 @@ krb5int_camellia_encrypt(krb5_key key, const krb5_data *ivec,
ivec, data, num_data);
}
-krb5_error_code
+static krb5_error_code
krb5int_camellia_decrypt(krb5_key key, const krb5_data *ivec,
krb5_crypto_iov *data, size_t num_data)
{
@@ -69,6 +67,20 @@ krb5int_camellia_decrypt(krb5_key key, const krb5_data *ivec,
ivec, data, num_data);
}
+krb5_error_code
+krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data,
+ size_t num_data, const krb5_data *ivec,
+ krb5_data *output)
+{
+ krb5_error_code ret;
+
+ ret = k5_nss_gen_import(key, CKM_CAMELLIA_CBC, CKA_DECRYPT);
+ if (ret != 0)
+ return ret;
+ return k5_nss_gen_cbcmac_iov(key, CKM_CAMELLIA_CBC, ivec, data, num_data,
+ output);
+}
+
/*
* perhaps we should store the NSS context in the krb5_data state here?
*/
diff --git a/src/lib/crypto/nss/enc_provider/enc_gen.c b/src/lib/crypto/nss/enc_provider/enc_gen.c
index 6bdf1d0f9..2927af318 100644
--- a/src/lib/crypto/nss/enc_provider/enc_gen.c
+++ b/src/lib/crypto/nss/enc_provider/enc_gen.c
@@ -539,6 +539,76 @@ done:
return ret;
}
+krb5_error_code
+k5_nss_gen_cbcmac_iov(krb5_key krb_key, CK_MECHANISM_TYPE mech,
+ const krb5_data *ivec, const krb5_crypto_iov *data,
+ size_t num_data, krb5_data *output)
+{
+ krb5_error_code ret = 0;
+ PK11Context *ctx = NULL;
+ SECStatus rv;
+ SECItem *param = NULL;
+ struct iov_block_state input_pos, output_pos;
+ unsigned char storage[MAX_BLOCK_SIZE];
+ unsigned char iv0[MAX_BLOCK_SIZE];
+ unsigned char *ptr = NULL, *lastptr = NULL;
+ SECItem iv;
+ size_t blocksize;
+ int length = 0;
+ int currentblock;
+
+ IOV_BLOCK_STATE_INIT(&input_pos);
+ IOV_BLOCK_STATE_INIT(&output_pos);
+
+ blocksize = PK11_GetBlockSize(mech, NULL);
+ assert(blocksize <= sizeof(storage));
+ if (output->length < blocksize)
+ return KRB5_BAD_MSIZE;
+
+ if (ivec && ivec->data) {
+ iv.data = (unsigned char *)ivec->data;
+ iv.len = ivec->length;
+ } else {
+ memset(iv0, 0, sizeof(iv0));
+ iv.data = iv0;
+ iv.len = blocksize;
+ }
+ param = PK11_ParamFromIV(mech, &iv);
+
+ ctx = k5_nss_create_context(krb_key, mech, CKA_ENCRYPT, param);
+ if (ctx == NULL) {
+ ret = k5_nss_map_last_error();
+ goto done;
+ }
+
+ lastptr = iv.data;
+ for (currentblock = 0;;currentblock++) {
+ if (!krb5int_c_iov_get_block_nocopy(storage, blocksize, data, num_data,
+ &input_pos, &ptr))
+ break;
+
+ lastptr = NULL;
+
+ rv = PK11_CipherOp(ctx, ptr, &length, blocksize, ptr, blocksize);
+ if (rv != SECSuccess) {
+ ret = k5_nss_map_last_error();
+ goto done;
+ }
+
+ lastptr = ptr;
+ }
+ memcpy(output->data, lastptr, blocksize);
+
+done:
+ if (ctx) {
+ PK11_Finalize(ctx);
+ PK11_DestroyContext(ctx, PR_TRUE);
+ }
+ if (param)
+ SECITEM_FreeItem(param, PR_TRUE);
+ return ret;
+}
+
void
k5_nss_gen_cleanup(krb5_key krb_key)
{
diff --git a/src/lib/crypto/nss/enc_provider/enc_provider.h b/src/lib/crypto/nss/enc_provider/enc_provider.h
index 8144b6533..4365255ab 100644
--- a/src/lib/crypto/nss/enc_provider/enc_provider.h
+++ b/src/lib/crypto/nss/enc_provider/enc_provider.h
@@ -34,3 +34,7 @@ extern const struct krb5_enc_provider krb5int_enc_aes128;
extern const struct krb5_enc_provider krb5int_enc_aes256;
extern const struct krb5_enc_provider krb5int_enc_aes128_ctr;
extern const struct krb5_enc_provider krb5int_enc_aes256_ctr;
+#ifdef CAMELLIA
+extern const struct krb5_enc_provider krb5int_enc_camellia128;
+extern const struct krb5_enc_provider krb5int_enc_camellia256;
+#endif
diff --git a/src/lib/crypto/nss/nss_gen.h b/src/lib/crypto/nss/nss_gen.h
index 4eb8f2f74..73f77348a 100644
--- a/src/lib/crypto/nss/nss_gen.h
+++ b/src/lib/crypto/nss/nss_gen.h
@@ -90,6 +90,12 @@ k5_nss_gen_cts_iov(krb5_key key, CK_MECHANISM_TYPE mech,
CK_ATTRIBUTE_TYPE operation, const krb5_data *ivec,
krb5_crypto_iov *data, size_t num_data);
+/* Compute a CBC-MAC. */
+krb5_error_code
+k5_nss_gen_cbcmac_iov(krb5_key key, CK_MECHANISM_TYPE mech,
+ const krb5_data *ivec, const krb5_crypto_iov *data,
+ size_t num_data, krb5_data *output);
+
/* Stream state management calls. */
krb5_error_code k5_nss_stream_init_state(krb5_data *new_state);
krb5_error_code k5_nss_stream_free_state(krb5_data *state);