]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Add Camellia support to the NSS back end. (It was mostly already camellia-cts-cmac
authorGreg Hudson <ghudson@mit.edu>
Fri, 19 Nov 2010 22:01:32 +0000 (22:01 +0000)
committerGreg Hudson <ghudson@mit.edu>
Fri, 19 Nov 2010 22:01:32 +0000 (22:01 +0000)
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

src/lib/crypto/nss/enc_provider/camellia.c
src/lib/crypto/nss/enc_provider/enc_gen.c
src/lib/crypto/nss/enc_provider/enc_provider.h
src/lib/crypto/nss/nss_gen.h

index 06165d28192f66cf59269c8e68c0f3e1625ad931..3a33d90ca14a90d717b52bd5f1a18e1015ecafa2 100644 (file)
@@ -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?
  */
index 6bdf1d0f92ab6b9145d91159e552bdad8711e55f..2927af318009d518215f296d565d756f7e578387 100644 (file)
@@ -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)
 {
index 8144b6533e3351bed5b54d1226fd6ee21a65d621..4365255ab4ee7994aa6c7e24518a84564eb665af 100644 (file)
@@ -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
index 4eb8f2f744bcbba6a09ce616b1b719591bb2b31a..73f77348adb610178d09e3a2376f098d931dbae8 100644 (file)
@@ -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);