summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiloslav Trmač <mitr@redhat.com>2010-10-04 21:25:21 +0200
committerMiloslav Trmač <mitr@redhat.com>2010-10-04 21:25:21 +0200
commit566ee5e8a43f6f9c5705c9d154e89cf43759b77f (patch)
treeefd72b5c8422f192ebeb569036375469e5845ff5
parent91475817b3f08ebf76cee39271aa5a692c8930d5 (diff)
downloadncrypto-566ee5e8a43f6f9c5705c9d154e89cf43759b77f.tar.gz
ncrypto-566ee5e8a43f6f9c5705c9d154e89cf43759b77f.tar.xz
ncrypto-566ee5e8a43f6f9c5705c9d154e89cf43759b77f.zip
Add basic digest support
-rw-r--r--Makefile.am13
-rw-r--r--configure.ac1
-rw-r--r--include/ncrypto/ncrypto.h56
-rw-r--r--lib/ncrypto_local.c234
-rw-r--r--tests/digests.c160
5 files changed, 461 insertions, 3 deletions
diff --git a/Makefile.am b/Makefile.am
index e19052e..2d4a0ab 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -29,12 +29,19 @@
versionedincludedir = $(includedir)/ncrypto-0/ncrypto
ACLOCAL_AMFLAGS = -I m4
-AM_CPPFLAGS = -I $(top_srcdir)/include $(NSS_CFLAGS) $(GLIB_CFLAGS)
+AM_CPPFLAGS = -I $(top_srcdir)/include $(GLIB_CFLAGS) $(NSS_CFLAGS) \
+ $(OPENSSL_CFLAGS)
## Targets
lib_LTLIBRARIES = lib/libncrypto.la
pkginclude_HEADERS = include/ncrypto/ncrypto.h
+TESTS = tests/digests
## Rules
-lib_libncrypto_la_SOURCES = lib/ncrypto.c
-lib_libncrypto_la_LDFLAGS = -version-info 0:0:0 \ No newline at end of file
+noinst_PROGRAMS = $(TESTS)
+
+lib_libncrypto_la_SOURCES = lib/ncrypto.c lib/ncrypto_local.c
+lib_libncrypto_la_LDFLAGS = -version-info 0:0:0 $(OPENSSL_LIBS)
+
+tests_digests_LDADD = lib/libncrypto.la $(GLIB_LIBS)
+tests_digests_LDFLAGS = -no-install
diff --git a/configure.ac b/configure.ac
index ed53177..fc29b65 100644
--- a/configure.ac
+++ b/configure.ac
@@ -49,6 +49,7 @@ PKG_CHECK_MODULES(GLIB,[glib-2.0])
AC_DEFINE(G_DISABLE_DEPRECATED,,
[Stay away from deprecated glib functionality.])
PKG_CHECK_MODULES(NSS,[nss])
+PKG_CHECK_MODULES(OPENSSL,[libcrypto])
# Checks for header files.
diff --git a/include/ncrypto/ncrypto.h b/include/ncrypto/ncrypto.h
index e69de29..5da7949 100644
--- a/include/ncrypto/ncrypto.h
+++ b/include/ncrypto/ncrypto.h
@@ -0,0 +1,56 @@
+/* libncrypto interface.
+
+Copyright 2010 Red Hat, Inc.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+Red Hat author: Miloslav Trmač <mitr@redhat.com> */
+
+#ifndef NCRYPTO_H__
+#define NCRYPTO_H__
+
+#include <stddef.h>
+
+#include <pkcs11.h>
+
+struct ncr_digest_session;
+
+/* Session lifetime management. */
+CK_RV ncr_digest_alloc (struct ncr_digest_session **sess,
+ CK_MECHANISM_TYPE mech);
+CK_RV ncr_digest_free (struct ncr_digest_session *sess);
+/* Use either: ncr_digest_{init,update*,final} (), or
+ ncr_{digest_init,digest} (). After finishing such a call sequence, a new
+ sequence can be started within the same session. */
+CK_RV ncr_digest_init (struct ncr_digest_session *sess);
+CK_RV ncr_digest_update (struct ncr_digest_session *sess, const void *data,
+ size_t size);
+CK_RV ncr_digest_final (struct ncr_digest_session *sess, void *dest,
+ size_t *size_ptr);
+CK_RV ncr_digest (struct ncr_digest_session *sess, void *dest,
+ size_t *dest_size_ptr, const void *data, size_t data_size);
+
+CK_RV ncr_digest_standalone (CK_MECHANISM_TYPE mech, void *dest,
+ size_t *dest_size_ptr, const void *data,
+ size_t data_size);
+
+#endif
diff --git a/lib/ncrypto_local.c b/lib/ncrypto_local.c
new file mode 100644
index 0000000..be05dc4
--- /dev/null
+++ b/lib/ncrypto_local.c
@@ -0,0 +1,234 @@
+/* In-process crypto implementation.
+
+Copyright 2010 Red Hat, Inc.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+Red Hat author: Miloslav Trmač <mitr@redhat.com> */
+#include <config.h>
+
+#include <glib.h>
+#include <openssl/evp.h>
+
+#include <ncrypto/ncrypto.h>
+
+ /* Helpers */
+
+static CK_RV
+ckr_openssl (void)
+{
+ /* FIXME: better error handling? This will be replaced anyway. */
+ return CKR_GENERAL_ERROR;
+}
+
+ /* Digest handling */
+
+static const EVP_MD *
+digest_evp_from_mech (CK_MECHANISM_TYPE mech)
+{
+ switch (mech)
+ {
+#define E(M, E) \
+ case CKM_##M: \
+ return EVP_##E ();
+ E (MD5, md5);
+ E (SHA_1, sha1);
+ E (SHA224, sha224);
+ E (SHA256, sha256);
+ E (SHA384, sha384);
+ E (SHA512, sha512);
+#undef E
+ default:
+ g_return_val_if_reached (NULL);
+ }
+}
+
+struct ncr_digest_session
+{
+ EVP_MD_CTX ctx;
+ const EVP_MD *md;
+ /* Debugging only */
+ enum { NDS_NEW, NDS_INITIALIZED, NDS_UPDATED, NDS_FINISHED } state;
+};
+
+CK_RV
+ncr_digest_alloc (struct ncr_digest_session **sess, CK_MECHANISM_TYPE mech)
+{
+ struct ncr_digest_session *s;
+ const EVP_MD *md;
+
+ g_return_val_if_fail (sess != NULL, CKR_ARGUMENTS_BAD);
+
+ md = digest_evp_from_mech (mech);
+ if (md == NULL)
+ return CKR_MECHANISM_INVALID;
+
+ s = malloc (sizeof (*s));
+ if (s == NULL)
+ return CKR_HOST_MEMORY;
+
+ EVP_MD_CTX_init (&s->ctx);
+ s->state = NDS_NEW;
+ s->md = md;
+ *sess = s;
+ return CKR_OK;
+}
+
+CK_RV
+ncr_digest_free (struct ncr_digest_session *sess)
+{
+ g_return_val_if_fail (sess != NULL, CKR_ARGUMENTS_BAD);
+
+ EVP_MD_CTX_cleanup (&sess->ctx);
+ return CKR_OK;
+}
+
+CK_RV
+ncr_digest_init (struct ncr_digest_session *sess)
+{
+ g_return_val_if_fail (sess != NULL, CKR_ARGUMENTS_BAD);
+ g_return_val_if_fail (sess->state == NDS_NEW || sess->state == NDS_FINISHED,
+ CKR_OPERATION_ACTIVE);
+
+ if (EVP_DigestInit_ex (&sess->ctx, sess->md, NULL) == 0)
+ return ckr_openssl ();
+
+ sess->state = NDS_INITIALIZED;
+ return CKR_OK;
+}
+
+CK_RV
+ncr_digest_update (struct ncr_digest_session *sess, const void *data,
+ size_t size)
+{
+ g_return_val_if_fail (sess != NULL, CKR_ARGUMENTS_BAD);
+ g_return_val_if_fail (data != NULL, CKR_ARGUMENTS_BAD);
+ g_return_val_if_fail (sess->state == NDS_INITIALIZED
+ || sess->state == NDS_UPDATED,
+ CKR_OPERATION_NOT_INITIALIZED);
+
+ if (EVP_DigestUpdate (&sess->ctx, data, size) == 0)
+ return ckr_openssl ();
+
+ sess->state = NDS_UPDATED;
+ return CKR_OK;
+}
+
+CK_RV
+ncr_digest_final (struct ncr_digest_session *sess, void *dest,
+ size_t *size_ptr)
+{
+ size_t md_size;
+
+ g_return_val_if_fail (sess != NULL, CKR_ARGUMENTS_BAD);
+ g_return_val_if_fail (sess->state == NDS_INITIALIZED
+ || sess->state == NDS_UPDATED,
+ CKR_OPERATION_NOT_INITIALIZED);
+
+ md_size = EVP_MD_size (sess->md);
+ if (dest == NULL)
+ {
+ *size_ptr = md_size;
+ return CKR_OK;
+ }
+ if (*size_ptr < md_size)
+ {
+ *size_ptr = md_size;
+ g_return_val_if_reached (CKR_BUFFER_TOO_SMALL);
+ }
+ *size_ptr = md_size;
+
+ g_return_val_if_fail (dest != NULL, CKR_ARGUMENTS_BAD);
+
+ if (EVP_DigestFinal_ex (&sess->ctx, dest, NULL) == 0)
+ return ckr_openssl ();
+
+ sess->state = NDS_FINISHED;
+ return CKR_OK;
+}
+
+CK_RV
+ncr_digest (struct ncr_digest_session *sess, void *dest, size_t *dest_size_ptr,
+ const void *data, size_t data_size)
+{
+ size_t md_size;
+
+ g_return_val_if_fail (sess != NULL, CKR_ARGUMENTS_BAD);
+ g_return_val_if_fail (sess->state == NDS_INITIALIZED,
+ CKR_OPERATION_NOT_INITIALIZED);
+ g_return_val_if_fail (dest_size_ptr != NULL, CKR_ARGUMENTS_BAD);
+
+ md_size = EVP_MD_size (sess->md);
+ if (dest == NULL)
+ {
+ *dest_size_ptr = md_size;
+ return CKR_OK;
+ }
+ if (*dest_size_ptr < md_size)
+ {
+ *dest_size_ptr = md_size;
+ g_return_val_if_reached (CKR_BUFFER_TOO_SMALL);
+ }
+ *dest_size_ptr = md_size;
+
+ g_return_val_if_fail (data != NULL, CKR_ARGUMENTS_BAD);
+
+ if (EVP_DigestUpdate(&sess->ctx, data, data_size) == 0
+ || EVP_DigestFinal_ex(&sess->ctx, dest, NULL) == 0)
+ return ckr_openssl ();
+
+ sess->state = NDS_FINISHED;
+ return CKR_OK;
+}
+
+CK_RV
+ncr_digest_standalone (CK_MECHANISM_TYPE mech, void *dest,
+ size_t *dest_size_ptr, const void *data,
+ size_t data_size)
+{
+ const EVP_MD *md;
+ size_t md_size;
+
+ g_return_val_if_fail (dest_size_ptr != NULL, CKR_ARGUMENTS_BAD);
+
+ md = digest_evp_from_mech (mech);
+ if (md == NULL)
+ return CKR_MECHANISM_INVALID;
+
+ md_size = EVP_MD_size (md);
+ if (dest == NULL)
+ {
+ *dest_size_ptr = md_size;
+ return CKR_OK;
+ }
+ if (*dest_size_ptr < md_size)
+ {
+ *dest_size_ptr = md_size;
+ g_return_val_if_reached (CKR_BUFFER_TOO_SMALL);
+ }
+ *dest_size_ptr = md_size;
+
+ g_return_val_if_fail (data != NULL, CKR_ARGUMENTS_BAD);
+
+ return EVP_Digest(data, data_size, dest, NULL, md, NULL) != 0
+ ? CKR_OK : ckr_openssl ();
+}
diff --git a/tests/digests.c b/tests/digests.c
new file mode 100644
index 0000000..8013698
--- /dev/null
+++ b/tests/digests.c
@@ -0,0 +1,160 @@
+/* ncr_digest_* tests.
+
+Copyright 2010 Red Hat, Inc.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+Red Hat author: Miloslav Trmač <mitr@redhat.com> */
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+#include <ncrypto/ncrypto.h>
+
+struct tv
+{
+ CK_MECHANISM_TYPE mech;
+ const uint8_t *input;
+ size_t input_size;
+ const uint8_t *output;
+ size_t output_size;
+};
+
+static const struct tv tvs[] =
+ {
+#define TV(M, IN, OUT) \
+ { \
+ (M), (const uint8_t *)(IN), sizeof (IN) - 1, (const uint8_t *)(OUT), \
+ sizeof (OUT) - 1 \
+ }
+ TV (CKM_MD5, "",
+ "\xD4\x1D\x8C\xD9\x8F\x00\xB2\x04\xE9\x80\x09\x98\xEC\xF8\x42\x7E"),
+ TV (CKM_MD5, "a",
+ "\x0C\xC1\x75\xB9\xC0\xF1\xB6\xA8\x31\xC3\x99\xE2\x69\x77\x26\x61"),
+ TV (CKM_MD5, "abc",
+ "\x90\x01\x50\x98\x3C\xD2\x4F\xB0\xD6\x96\x3F\x7D\x28\xE1\x7F\x72"),
+ TV (CKM_MD5, "message digest",
+ "\xF9\x6B\x69\x7D\x7C\xB7\x93\x8D\x52\x5A\x2F\x31\xAA\xF1\x61\xD0"),
+ TV (CKM_MD5, "abcdefghijklmnopqrstuvwxyz",
+ "\xC3\xFC\xD3\xD7\x61\x92\xE4\x00\x7D\xFB\x49\x6C\xCA\x67\xE1\x3B"),
+ TV (CKM_MD5,
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ "\xD1\x74\xAB\x98\xD2\x77\xD9\xF5\xA5\x61\x1C\x2C\x9F\x41\x9D\x9F"),
+ TV (CKM_MD5,
+ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
+ "\x57\xED\xF4\xA2\x2B\xE3\xC9\x55\xAC\x49\xDA\x2E\x21\x07\xB6\x7A"),
+
+ TV (CKM_SHA_1, "abc",
+ "\xa9\x99\x3e\x36\x47\x06\x81\x6a\xba\x3e\x25\x71\x78\x50\xc2\x6c\x9c\xd0\xd8\x9d"),
+ TV (CKM_SHA_1, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "\x84\x98\x3e\x44\x1c\x3b\xd2\x6e\xba\xae\x4a\xa1\xf9\x51\x29\xe5\xe5\x46\x70\xf1"),
+
+ TV (CKM_SHA224, "abc",
+ "\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2\x55\xb3\x2a\xad\xbc\xe4\xbd\xa0\xb3\xf7\xe3\x6c\x9d\xa7"),
+ TV (CKM_SHA224, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01\x50\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25"),
+
+ TV (CKM_SHA256, "abc",
+ "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad"),
+ TV (CKM_SHA256, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1"),
+
+ TV (CKM_SHA384, "abc",
+ "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34\xc8\x25\xa7"),
+ TV (CKM_SHA384, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+ "\x09\x33\x0c\x33\xf7\x11\x47\xe8\x3d\x19\x2f\xc7\x82\xcd\x1b\x47\x53\x11\x1b\x17\x3b\x3b\x05\xd2\x2f\xa0\x80\x86\xe3\xb0\xf7\x12\xfc\xc7\xc7\x1a\x55\x7e\x2d\xb9\x66\xc3\xe9\xfa\x91\x74\x60\x39"),
+
+ TV (CKM_SHA512, "abc",
+ "\xdd\xaf\x35\xa1\x93\x61\x7a\xba\xcc\x41\x73\x49\xae\x20\x41\x31\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2\x0a\x9e\xee\xe6\x4b\x55\xd3\x9a\x21\x92\x99\x2a\x27\x4f\xc1\xa8\x36\xba\x3c\x23\xa3\xfe\xeb\xbd\x45\x4d\x44\x23\x64\x3c\xe8\x0e\x2a\x9a\xc9\x4f\xa5\x4c\xa4\x9f"),
+ TV (CKM_SHA512, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+ "\x8e\x95\x9b\x75\xda\xe3\x13\xda\x8c\xf4\xf7\x28\x14\xfc\x14\x3f\x8f\x77\x79\xc6\xeb\x9f\x7f\xa1\x72\x99\xae\xad\xb6\x88\x90\x18\x50\x1d\x28\x9e\x49\x00\xf7\xe4\x33\x1b\x99\xde\xc4\xb5\x43\x3a\xc7\xd3\x29\xee\xb6\xdd\x26\x54\x5e\x96\xe5\x5b\x87\x4b\xe9\x09"),
+
+
+
+#undef TV
+ };
+
+int
+main (void)
+{
+ struct ncr_digest_session *sess;
+ uint8_t dest[256];
+ size_t i, j, dest_size;
+ CK_RV res;
+
+ for (i = 0; i < G_N_ELEMENTS (tvs); i++)
+ {
+ dest_size = sizeof (dest);
+ res = ncr_digest_standalone (tvs[i].mech, dest, &dest_size, tvs[i].input,
+ tvs[i].input_size);
+ assert (res == CKR_OK);
+ assert (dest_size == tvs[i].output_size);
+ assert (memcmp (dest, tvs[i].output, dest_size) == 0);
+ }
+
+ for (i = 0; i < G_N_ELEMENTS (tvs); i++)
+ {
+ res = ncr_digest_alloc (&sess, tvs[i].mech);
+ assert (res == CKR_OK);
+ for (j = 0; j < 2; j++)
+ {
+ res = ncr_digest_init (sess);
+ assert (res == CKR_OK);
+
+ res = ncr_digest_update (sess, tvs[i].input, tvs[i].input_size);
+ assert (res == CKR_OK);
+
+ dest_size = sizeof (dest);
+ res = ncr_digest_final (sess, dest, &dest_size);
+ assert (res == CKR_OK);
+ assert (dest_size == tvs[i].output_size);
+ assert (memcmp (dest, tvs[i].output, dest_size) == 0);
+ }
+ res = ncr_digest_free (sess);
+ assert (res == CKR_OK);
+ }
+
+ for (i = 0; i < G_N_ELEMENTS (tvs); i++)
+ {
+ res = ncr_digest_alloc (&sess, tvs[i].mech);
+ assert (res == CKR_OK);
+ for (j = 0; j < 2; j++)
+ {
+ res = ncr_digest_init (sess);
+ assert (res == CKR_OK);
+
+ dest_size = sizeof (dest);
+ res = ncr_digest (sess, dest, &dest_size, tvs[i].input,
+ tvs[i].input_size);
+ assert (res == CKR_OK);
+ assert (dest_size == tvs[i].output_size);
+ assert (memcmp (dest, tvs[i].output, dest_size) == 0);
+ }
+ res = ncr_digest_free (sess);
+ assert (res == CKR_OK);
+ }
+
+ return EXIT_SUCCESS;
+}