aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.in24
-rw-r--r--tests/test-aes-key-wrap.c140
2 files changed, 164 insertions, 0 deletions
diff --git a/tests/Makefile.in b/tests/Makefile.in
new file mode 100644
index 0000000..f63e4fc
--- /dev/null
+++ b/tests/Makefile.in
@@ -0,0 +1,24 @@
+# @configure_input@
+
+INC = ../cryptech.h
+LIB = ../libcryptech.a
+BIN = test-aes-key-wrap
+
+CC = @CC@
+CFLAGS = @CFLAGS@ -I..
+LDFLAGS = @LDFLAGS@ ${LIB}
+
+all: ${BIN}
+
+*.o: ${INC}
+
+${BIN}: ${LIB}
+
+test: all
+ for i in ${BIN}; do ./$$i; done
+
+clean:
+ rm -f *.o ${BIN}
+
+distclean: clean
+ rm -f Makefile
diff --git a/tests/test-aes-key-wrap.c b/tests/test-aes-key-wrap.c
new file mode 100644
index 0000000..cc31011
--- /dev/null
+++ b/tests/test-aes-key-wrap.c
@@ -0,0 +1,140 @@
+/*
+ * Test code for AES Key Wrap.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+
+#include <cryptech.h>
+
+#ifndef TC_BUFSIZE
+#define TC_BUFSIZE 4096
+#endif
+
+/*
+ * Test cases from RFC 5649...which all use a 192-bit key, which our
+ * AES implementation doesn't support, to these will never pass. Feh.
+ *
+ * Have to write our own, I guess, using our Python implementation or
+ * something.
+ */
+
+typedef struct {
+ const char *K; /* Key-encryption-key */
+ const char *Q; /* Plaintext */
+ const char *C; /* Ciphertext */
+} test_case_t;
+
+static const test_case_t test_case[] = {
+
+ { "5840df6e29b02af1 ab493b705bf16ea1 ae8338f4dcc176a8", /* K */
+ "c37b7e6492584340 bed1220780894115 5068f738", /* Q */
+ "138bdeaa9b8fa7fc 61f97742e72248ee 5ae6ae5360d1ae6a 5f54f373fa543b6a"}, /* C */
+
+ { "5840df6e29b02af1 ab493b705bf16ea1 ae8338f4dcc176a8", /* K */
+ "466f7250617369", /* Q */
+ "afbeb0f07dfbf541 9200f2ccb50bb24f" } /* C */
+
+};
+
+static int parse_hex(const char *hex, uint8_t *bin, size_t *len, const size_t max)
+{
+ static const char whitespace[] = " \t\r\n";
+ size_t i;
+
+ assert(hex != NULL && bin != NULL && len != NULL);
+
+ hex += strspn(hex, whitespace);
+
+ for (i = 0; *hex != '\0' && i < max; i++, hex += 2 + strspn(hex + 2, whitespace))
+ if (sscanf(hex, "%2hhx", &bin[i]) != 1)
+ return 0;
+
+ *len = i;
+
+ return *hex == '\0';
+}
+
+static const char *format_hex(const uint8_t *bin, const size_t len, char *hex, const size_t max)
+{
+ size_t i;
+
+ assert(bin != NULL && hex != NULL && len * 3 < max);
+
+ if (len == 0)
+ return "";
+
+ for (i = 0; i < len; i++)
+ sprintf(hex + 3 * i, "%02x:", bin[i]);
+
+ hex[len * 3 - 1] = '\0';
+ return hex;
+}
+
+static int run_test(const test_case_t * const tc)
+{
+ uint8_t K[TC_BUFSIZE], Q[TC_BUFSIZE], C[TC_BUFSIZE], q[TC_BUFSIZE], c[TC_BUFSIZE];
+ size_t K_len, Q_len, C_len, q_len = sizeof(q), c_len = sizeof(c);
+ char h1[TC_BUFSIZE * 3], h2[TC_BUFSIZE * 3];
+ hal_error_t err;
+ int ok = 1;
+
+ assert(tc != NULL);
+
+ if (!parse_hex(tc->K, K, &K_len, sizeof(K)))
+ return printf("couldn't parse KEK %s\n", tc->K), 0;
+
+ if (!parse_hex(tc->Q, Q, &Q_len, sizeof(Q)))
+ return printf("couldn't parse plaintext %s\n", tc->Q), 0;
+
+ if (!parse_hex(tc->C, C, &C_len, sizeof(C)))
+ return printf("couldn't parse ciphertext %s\n", tc->C), 0;
+
+ if ((err = hal_aes_keywrap(K, K_len, Q, Q_len, c, &c_len)) != HAL_OK)
+ ok = printf("couldn't wrap %s: %s\n", tc->Q, hal_error_string(err)), 0;
+
+ if ((err = hal_aes_keyunwrap(K, K_len, C, C_len, q, &q_len)) != HAL_OK)
+ ok = printf("couldn't unwrap %s: %s\n", tc->C, hal_error_string(err)), 0;
+
+ if (C_len != c_len || memcmp(C, c, C_len) != 0)
+ ok = printf("ciphertext mismatch:\n Want: %s\n Got: %s\n",
+ format_hex(C, C_len, h1, sizeof(h1)),
+ format_hex(c, c_len, h2, sizeof(h2))), 0;
+
+ if (Q_len != q_len || memcmp(Q, q, Q_len) != 0)
+ ok = printf("plaintext mismatch:\n Want: %s\n Got: %s\n",
+ format_hex(Q, Q_len, h1, sizeof(h1)),
+ format_hex(q, q_len, h2, sizeof(h2))), 0;
+
+ return ok;
+}
+
+int main (int argc, char *argv[])
+{
+ int i, ok = 1;
+
+ for (i = 0; i < sizeof(test_case)/sizeof(*test_case); i++) {
+ printf("Running test case #%d...", i);
+ if (run_test(&test_case[i]))
+ printf("OK\n");
+ else
+ ok = 0;
+ }
+
+ return !ok;
+}
+
+/*
+ * "Any programmer who fails to comply with the standard naming, formatting,
+ * or commenting conventions should be shot. If it so happens that it is
+ * inconvenient to shoot him, then he is to be politely requested to recode
+ * his program in adherence to the above standard."
+ * -- Michael Spier, Digital Equipment Corporation
+ *
+ * Local variables:
+ * indent-tabs-mode: nil
+ * End:
+ */