]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/libkmip/tests.c
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / libkmip / tests.c
diff --git a/ceph/src/libkmip/tests.c b/ceph/src/libkmip/tests.c
new file mode 100644 (file)
index 0000000..c482229
--- /dev/null
@@ -0,0 +1,11400 @@
+/* Copyright (c) 2018 The Johns Hopkins University/Applied Physics Laboratory
+ * All Rights Reserved.
+ *
+ * This file is dual licensed under the terms of the Apache 2.0 License and
+ * the BSD 3-Clause License. See the LICENSE file in the root of this
+ * repository for more information.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "kmip.h"
+
+
+
+#define TEST_PASSED(A, B)       \
+do                              \
+{                               \
+    printf("PASS - %s\n", (B)); \
+    (A)->tests_passed++;        \
+    return(0);                  \
+} while(0)
+
+#define TEST_FAILED(A, B, C)               \
+do                                         \
+{                                          \
+    printf("FAIL - %s @ L%d\n", (B), (C)); \
+    (A)->tests_failed++;                   \
+    return(1);                             \
+} while(0)
+
+#define TRACK_TEST(A) ((A)->test_count++)
+
+
+typedef struct test_tracker
+{
+    uint16 test_count;
+    uint16 tests_failed;
+    uint16 tests_passed;
+} TestTracker;
+
+
+int
+report_encoding_test_result(
+    TestTracker *tracker,
+    struct kmip *ctx,
+    const uint8 *expected,
+    const uint8 *observed,
+    int result,
+    const char *function)
+{
+    if(result == KMIP_OK)
+    {
+        for(size_t i = 0; i < ctx->size; i++)
+        {
+            if(expected[i] != observed[i])
+            {
+                printf("FAIL - %s\n", function);
+                printf("- byte mismatch at: %zu (exp: %X, obs: %X)\n",
+                       i, expected[i], observed[i]);
+                for(size_t j = 0; j < ctx->size; j++)
+                {
+                    printf("- %zu: %X - %X\n", j, expected[j], observed[j]);
+                }
+                tracker->tests_failed++;
+                return(1);
+            }
+        }
+        
+        TEST_PASSED(tracker, function);
+    }
+    else
+    {
+        printf("FAIL - %s\n", function);
+        if(result == KMIP_ERROR_BUFFER_FULL)
+        {
+            printf("- context buffer is full\n");
+        }
+        kmip_print_stack_trace(ctx);
+        tracker->tests_failed++;
+        return(1);
+    }
+}
+
+int
+report_decoding_test_result(
+    TestTracker *tracker,
+    struct kmip *ctx,
+    int comparison,
+    int result,
+    const char *function)
+{
+    if(result == KMIP_OK)
+    {
+        if(comparison)
+        {
+            TEST_PASSED(tracker, function);
+        }
+        else
+        {
+            printf("FAIL - %s\n", function);
+            printf("- compared objects are not identical\n");
+            tracker->tests_failed++;
+            return(1);
+        }
+    }
+    else
+    {
+        printf("FAIL - %s\n", function);
+        if(result == KMIP_ERROR_BUFFER_FULL)
+        {
+            printf("- context buffer is underfull\n");
+        }
+        kmip_print_stack_trace(ctx);
+        tracker->tests_failed++;
+        return(1);
+    }
+}
+
+int
+report_result(TestTracker *tracker, int observed, int expected, const char *function)
+{
+    if(observed == expected)
+    {
+        TEST_PASSED(tracker, function);
+    }
+    else
+    {
+        printf("FAIL - %s\n", function);
+        tracker->tests_failed++;
+        return(1);
+    }
+}
+
+int
+test_linked_list_push(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    LinkedList list = {0};
+
+    LinkedListItem a = {0};
+    LinkedListItem b = {0};
+    LinkedListItem c = {0};
+
+    if(list.head != NULL || list.tail != NULL || list.size != 0)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_linked_list_push(&list, &a);
+
+    if(list.head != &a || list.tail != &a || list.size != 1)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_linked_list_push(&list, &b);
+
+    if(list.head != &b || list.tail != &a || list.size != 2)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_linked_list_push(&list, &c);
+
+    if(list.head != &c || list.tail != &a || list.size != 3)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    LinkedListItem *curr = list.head;
+    if(curr != &c || curr->next != &b || curr->prev != NULL)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    curr = curr->next;
+    if(curr != &b || curr->next != &a || curr->prev != &c)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    curr = curr->next;
+    if(curr != &a || curr->next != NULL || curr->prev != &b)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    TEST_PASSED(tracker, __func__);
+}
+
+int
+test_linked_list_pop(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    LinkedList list = {0};
+
+    if(list.head != NULL || list.tail != NULL || list.size != 0)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    LinkedListItem *item = kmip_linked_list_pop(&list);
+
+    if(item != NULL || list.head != NULL || list.tail != NULL || list.size != 0)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    LinkedListItem a = {0};
+    LinkedListItem b = {0};
+    LinkedListItem c = {0};
+
+    a.next = &b;
+    a.prev = NULL;
+    b.next = &c;
+    b.prev = &a;
+    c.next = NULL;
+    c.prev = &b;
+
+    list.head = &a;
+    list.tail = &c;
+    list.size = 3;
+
+    item = kmip_linked_list_pop(&list);
+
+    if(item != &a || list.head != &b || list.tail != &c || list.size != 2)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    item = kmip_linked_list_pop(&list);
+
+    if(item != &b || list.head != &c || list.tail != &c || list.size != 1)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    item = kmip_linked_list_pop(&list);
+
+    if(item != &c || list.head != NULL || list.tail != NULL || list.size != 0)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    TEST_PASSED(tracker, __func__);
+}
+
+int
+test_linked_list_enqueue(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    LinkedList list = {0};
+
+    LinkedListItem a = {0};
+    LinkedListItem b = {0};
+    LinkedListItem c = {0};
+
+    if(list.head != NULL || list.tail != NULL || list.size != 0)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_linked_list_enqueue(&list, &a);
+
+    if(list.head != &a || list.tail != &a || list.size != 1)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_linked_list_enqueue(&list, &b);
+
+    if(list.head != &a || list.tail != &b || list.size != 2)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_linked_list_enqueue(&list, &c);
+
+    if(list.head != &a || list.tail != &c || list.size != 3)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    LinkedListItem *curr = list.head;
+    if(curr != &a || curr->next != &b || curr->prev != NULL)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    curr = curr->next;
+    if(curr != &b || curr->next != &c || curr->prev != &a)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    curr = curr->next;
+    if(curr != &c || curr->next != NULL || curr->prev != &b)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    TEST_PASSED(tracker, __func__);
+}
+
+int
+test_buffer_full_and_resize(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[40] = {
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20,
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 too_small[30] = {0};
+    uint8 large_enough[40] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, too_small, ARRAY_LENGTH(too_small), KMIP_1_0);
+    
+    struct protocol_version pv = {0};
+    pv.major = 1;
+    pv.minor = 0;
+    
+    int result = kmip_encode_protocol_version(&ctx, &pv);
+    
+    if(result == KMIP_ERROR_BUFFER_FULL)
+    {
+        kmip_reset(&ctx);
+        kmip_set_buffer(&ctx, large_enough, ARRAY_LENGTH(large_enough));
+        
+        result = kmip_encode_protocol_version(&ctx, &pv);
+        result = report_encoding_test_result(
+            tracker,
+            &ctx,
+            expected,
+            large_enough,
+            result,
+            __func__);
+        
+        kmip_destroy(&ctx);
+        
+        return(result);
+    }
+    else
+    {
+        printf("FAIL - %s\n", __func__);
+        printf("- expected buffer full\n");
+        
+        kmip_destroy(&ctx);
+        tracker->tests_failed++;
+        return(1);
+    }
+}
+
+int
+test_is_tag_next(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[3] = {0x42, 0x00, 0x08};
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    uint8 *before = ctx.index;
+    int result = 0;
+    
+    if(kmip_is_tag_next(&ctx, KMIP_TAG_ATTRIBUTE) == KMIP_FALSE)
+    {
+        printf("FAIL - %s\n", __func__);
+        printf("- expected tag is not next\n");
+        tracker->tests_failed++;
+        result = 1;
+    }
+    
+    uint8 *after = ctx.index;
+    
+    if(before != after)
+    {
+        printf("FAIL - %s\n", __func__);
+        printf("- tag checking modifies context buffer index\n");
+        tracker->tests_failed++;
+        result = 1;
+    }
+    
+    kmip_destroy(&ctx);
+    
+    if(result == 0)
+    {
+        printf("PASS - %s\n", __func__);
+        tracker->tests_passed++;
+    }
+    
+    return(result);
+}
+
+int
+test_get_num_items_next(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[168] = {
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x17, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C, 
+        0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, 
+        0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x14, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x4C, 0x65, 
+        0x6E, 0x67, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, 
+        0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B, 
+        0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00        
+    };
+
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    uint8 *before = ctx.index;
+    int result = 0;
+    int count = 0;
+    
+    count = kmip_get_num_items_next(&ctx, KMIP_TAG_ATTRIBUTE);
+    if(count != 3)
+    {
+        printf("FAIL - %s\n", __func__);
+        printf("- expected item count not found (exp. 3, obs. %d)\n",
+               count);
+        tracker->tests_failed++;
+        result = 1;
+    }
+    
+    uint8 *after = ctx.index;
+    
+    if(before != after)
+    {
+        printf("FAIL - %s\n", __func__);
+        printf("- item count checking modifies context buffer index\n");
+        tracker->tests_failed++;
+        result = 1;
+    }
+    
+    kmip_destroy(&ctx);
+    
+    if(result == 0)
+    {
+        printf("PASS - %s\n", __func__);
+        tracker->tests_passed++;
+    }
+    
+    return(result);
+}
+
+int
+test_get_num_items_next_with_partial_item(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[136] = {
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x14, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x4C, 0x65, 
+        0x6E, 0x67, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, 
+        0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B, 
+        0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72 
+    };
+
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    uint8 *before = ctx.index;
+    int result = 0;
+    int count = 0;
+    
+    count = kmip_get_num_items_next(&ctx, KMIP_TAG_ATTRIBUTE);
+    if(count != 2)
+    {
+        printf("FAIL - %s\n", __func__);
+        printf("- expected item count not found (exp. 2, obs. %d)\n",
+               count);
+        tracker->tests_failed++;
+        result = 1;
+    }
+    
+    uint8 *after = ctx.index;
+    
+    if(before != after)
+    {
+        printf("FAIL - %s\n", __func__);
+        printf("- item count checking modifies context buffer index\n");
+        tracker->tests_failed++;
+        result = 1;
+    }
+    
+    kmip_destroy(&ctx);
+    
+    if(result == 0)
+    {
+        printf("PASS - %s\n", __func__);
+        tracker->tests_passed++;
+    }
+    
+    return(result);
+}
+
+int
+test_get_num_items_next_with_mismatch_item(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[80] = {
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, 
+        0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B, 
+        0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72 
+    };
+
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    uint8 *before = ctx.index;
+    int result = 0;
+    int count = 0;
+    
+    count = kmip_get_num_items_next(&ctx, KMIP_TAG_ATTRIBUTE);
+    if(count != 1)
+    {
+        printf("FAIL - %s\n", __func__);
+        printf("- expected item count not found (exp. 1, obs. %d)\n",
+               count);
+        tracker->tests_failed++;
+        result = 1;
+    }
+    
+    uint8 *after = ctx.index;
+    
+    if(before != after)
+    {
+        printf("FAIL - %s\n", __func__);
+        printf("- item count checking modifies context buffer index\n");
+        tracker->tests_failed++;
+        result = 1;
+    }
+    
+    kmip_destroy(&ctx);
+    
+    if(result == 0)
+    {
+        printf("PASS - %s\n", __func__);
+        tracker->tests_passed++;
+    }
+    
+    return(result);
+}
+
+int
+test_get_num_items_next_with_no_matches(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[80] = {
+        0x42, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, 
+        0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B, 
+        0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72 
+    };
+
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    uint8 *before = ctx.index;
+    int result = 0;
+    int count = 0;
+    
+    count = kmip_get_num_items_next(&ctx, KMIP_TAG_ATTRIBUTE);
+    if(count != 0)
+    {
+        printf("FAIL - %s\n", __func__);
+        printf("- expected item count not found (exp. 0, obs. %d)\n",
+               count);
+        tracker->tests_failed++;
+        result = 1;
+    }
+    
+    uint8 *after = ctx.index;
+    
+    if(before != after)
+    {
+        printf("FAIL - %s\n", __func__);
+        printf("- item count checking modifies context buffer index\n");
+        tracker->tests_failed++;
+        result = 1;
+    }
+    
+    kmip_destroy(&ctx);
+    
+    if(result == 0)
+    {
+        printf("PASS - %s\n", __func__);
+        tracker->tests_passed++;
+    }
+    
+    return(result);
+}
+
+int
+test_get_num_items_next_with_non_structures(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[144] = {
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x26,
+        0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35, 
+        0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, 
+        0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, 
+        0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, 
+        0x65, 0x39, 0x38, 0x61, 0x11, 0x11, 0x00, 0x00, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x25,
+        0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35, 
+        0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, 
+        0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, 
+        0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, 
+        0x65, 0x39, 0x38, 0x61, 0x11, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24,
+        0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35, 
+        0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, 
+        0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, 
+        0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, 
+        0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00
+    };
+
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    uint8 *before = ctx.index;
+    int result = 0;
+    int count = 0;
+    
+    count = kmip_get_num_items_next(&ctx, KMIP_TAG_UNIQUE_IDENTIFIER);
+    if(count != 3)
+    {
+        printf("FAIL - %s\n", __func__);
+        printf("- expected item count not found (exp. 3, obs. %d)\n",
+               count);
+        tracker->tests_failed++;
+        result = 1;
+    }
+    
+    uint8 *after = ctx.index;
+    
+    if(before != after)
+    {
+        printf("FAIL - %s\n", __func__);
+        printf("- item count checking modifies context buffer index\n");
+        tracker->tests_failed++;
+        result = 1;
+    }
+    
+    kmip_destroy(&ctx);
+    
+    if(result == 0)
+    {
+        printf("PASS - %s\n", __func__);
+        tracker->tests_passed++;
+    }
+    
+    return(result);
+}
+
+int
+test_buffer_bytes_left(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 a[1] = {0x42};
+    uint8 b[3] = {0x42, 0x00, 0x08};
+    uint8 c[5] = {0x42, 0x00, 0x53, 0x01, 0x00};
+
+    KMIP ctx = {0};
+    kmip_init(&ctx, a, ARRAY_LENGTH(a), KMIP_1_0);
+
+    if(BUFFER_BYTES_LEFT(&ctx) != 1)
+    {
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_destroy(&ctx);
+    kmip_init(&ctx, b, ARRAY_LENGTH(b), KMIP_1_0);
+
+    if(BUFFER_BYTES_LEFT(&ctx) != 3)
+    {
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_destroy(&ctx);
+    kmip_init(&ctx, c, ARRAY_LENGTH(c), KMIP_1_0);
+
+    if(BUFFER_BYTES_LEFT(&ctx) != 5)
+    {
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_destroy(&ctx);
+
+    TEST_PASSED(tracker, __func__);
+}
+
+int
+test_get_num_attributes_next(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* Need to build an encoding with one of each type of support
+       attribute. Verify that this function returns the correct
+       count.
+
+       Need to build an encoding with bad attribute length? Handle
+       weird corner cases?
+    */
+    TEST_FAILED(tracker, __func__, __LINE__);
+}
+
+int
+test_peek_tag(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* Build an encoding with an arbitrary tag value. Verify that this
+       function reads and returns this tag value without changing the
+       context buffer.
+    */
+
+    uint8 underfull_encoding[1] = {0x42};
+    uint8 full_encoding[3] = {0x42, 0x00, 0x08};
+    uint8 overfull_encoding[5] = {0x42, 0x00, 0x53, 0x01, 0x00};
+
+    uint32 tag = 0;
+    uint8 *prev_buffer = NULL;
+    uint8 *prev_index = NULL;
+    size_t prev_size = 0;
+    KMIP ctx = {0};
+    kmip_init(&ctx, underfull_encoding, ARRAY_LENGTH(underfull_encoding), KMIP_1_0);
+
+    prev_buffer = ctx.buffer;
+    prev_index = ctx.index;
+    prev_size = ctx.size;
+    tag = kmip_peek_tag(&ctx);
+    if(tag != 0 || ctx.buffer != prev_buffer || ctx.index != prev_index || ctx.size != prev_size)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_destroy(&ctx);
+    kmip_init(&ctx, full_encoding, ARRAY_LENGTH(full_encoding), KMIP_1_0);
+
+    prev_buffer = ctx.buffer;
+    prev_index = ctx.index;
+    prev_size = ctx.size;
+    tag = kmip_peek_tag(&ctx);
+    if(tag != KMIP_TAG_ATTRIBUTE || ctx.buffer != prev_buffer || ctx.index != prev_index || ctx.size != prev_size)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_destroy(&ctx);
+    kmip_init(&ctx, overfull_encoding, ARRAY_LENGTH(overfull_encoding), KMIP_1_0);
+
+    prev_buffer = ctx.buffer;
+    prev_index = ctx.index;
+    prev_size = ctx.size;
+    tag = kmip_peek_tag(&ctx);
+    if(tag != KMIP_TAG_NAME || ctx.buffer != prev_buffer || ctx.index != prev_index || ctx.size != prev_size)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_destroy(&ctx);
+
+    TEST_PASSED(tracker, __func__);
+}
+
+int
+test_is_attribute_tag(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    if(!kmip_is_attribute_tag(KMIP_TAG_UNIQUE_IDENTIFIER))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_NAME))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_OBJECT_TYPE))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_CRYPTOGRAPHIC_LENGTH))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_CRYPTOGRAPHIC_PARAMETERS))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_CRYPTOGRAPHIC_DOMAIN_PARAMETERS))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_CERTIFICATE_TYPE))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_CERTIFICATE_LENGTH))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_X509_CERTIFICATE_IDENTIFIER))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_X509_CERTIFICATE_SUBJECT))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_X509_CERTIFICATE_ISSUER))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_CERTIFICATE_IDENTIFIER))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_CERTIFICATE_SUBJECT))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_CERTIFICATE_ISSUER))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_DIGITAL_SIGNATURE_ALGORITHM))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_DIGEST))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_OPERATION_POLICY_NAME))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_CRYPTOGRAPHIC_USAGE_MASK))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_LEASE_TIME))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_USAGE_LIMITS))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_STATE))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_INITIAL_DATE))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_ACTIVATION_DATE))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_PROCESS_START_DATE))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_PROTECT_STOP_DATE))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_DEACTIVATION_DATE))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_DESTROY_DATE))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_COMPROMISE_OCCURRENCE_DATE))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_COMPROMISE_DATE))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_REVOCATION_REASON))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_ARCHIVE_DATE))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_OBJECT_GROUP))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_FRESH))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_LINK))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_APPLICATION_SPECIFIC_INFORMATION))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_CONTACT_INFORMATION))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_LAST_CHANGE_DATE))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_ALTERNATIVE_NAME))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_KEY_VALUE_PRESENT))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_KEY_VALUE_LOCATION))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_ORIGINAL_CREATION_DATE))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_RANDOM_NUMBER_GENERATOR))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_PKCS_12_FRIENDLY_NAME))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_DESCRIPTION))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_COMMENT))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_SENSITIVE))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_ALWAYS_SENSITIVE))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_EXTRACTABLE))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_NEVER_EXTRACTABLE))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_is_attribute_tag(KMIP_TAG_KEY_FORMAT_TYPE))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_is_attribute_tag(KMIP_TAG_REQUEST_MESSAGE))
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    TEST_PASSED(tracker, __func__);
+}
+
+int
+test_get_enum_string_index(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    if(kmip_get_enum_string_index(KMIP_TAG_UNIQUE_IDENTIFIER) != 0)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_NAME) != 1)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_OBJECT_TYPE) != 2)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_CRYPTOGRAPHIC_ALGORITHM) != 3)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_CRYPTOGRAPHIC_LENGTH) != 4)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_CRYPTOGRAPHIC_PARAMETERS) != 5)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_CRYPTOGRAPHIC_DOMAIN_PARAMETERS) != 6)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_CERTIFICATE_TYPE) != 7)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_CERTIFICATE_LENGTH) != 8)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_X509_CERTIFICATE_IDENTIFIER) != 9)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_X509_CERTIFICATE_SUBJECT) != 10)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_X509_CERTIFICATE_ISSUER) != 11)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_CERTIFICATE_IDENTIFIER) != 12)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_CERTIFICATE_SUBJECT) != 13)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_CERTIFICATE_ISSUER) != 14)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_DIGITAL_SIGNATURE_ALGORITHM) != 15)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_DIGEST) != 16)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_OPERATION_POLICY_NAME) != 17)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_CRYPTOGRAPHIC_USAGE_MASK) != 18)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_LEASE_TIME) != 19)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_USAGE_LIMITS) != 20)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_STATE) != 21)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_INITIAL_DATE) != 22)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_ACTIVATION_DATE) != 23)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_PROCESS_START_DATE) != 24)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_PROTECT_STOP_DATE) != 25)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_DEACTIVATION_DATE) != 26)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_DESTROY_DATE) != 27)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_COMPROMISE_OCCURRENCE_DATE) != 28)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_COMPROMISE_DATE) != 29)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_REVOCATION_REASON) != 30)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_ARCHIVE_DATE) != 31)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_OBJECT_GROUP) != 32)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_FRESH) != 33)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_LINK) != 34)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_APPLICATION_SPECIFIC_INFORMATION) != 35)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_CONTACT_INFORMATION) != 36)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_LAST_CHANGE_DATE) != 37)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_ALTERNATIVE_NAME) != 38)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_KEY_VALUE_PRESENT) != 39)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_KEY_VALUE_LOCATION) != 40)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_ORIGINAL_CREATION_DATE) != 41)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_RANDOM_NUMBER_GENERATOR) != 42)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_PKCS_12_FRIENDLY_NAME) != 43)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_DESCRIPTION) != 44)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_COMMENT) != 45)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_SENSITIVE) != 46)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_ALWAYS_SENSITIVE) != 47)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_EXTRACTABLE) != 48)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_NEVER_EXTRACTABLE) != 49)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(KMIP_TAG_KEY_FORMAT_TYPE) != 50)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_get_enum_string_index(-1) != 51)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    TEST_PASSED(tracker, __func__);
+}
+
+int
+test_check_enum_value_protection_storage_masks(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    enum kmip_version v = KMIP_2_0;
+    enum tag t = KMIP_TAG_PROTECTION_STORAGE_MASK;
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_SOFTWARE) != KMIP_OK)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_HARDWARE) != KMIP_OK)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_ON_PROCESSOR) != KMIP_OK)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_ON_SYSTEM) != KMIP_OK)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_OFF_SYSTEM) != KMIP_OK)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_HYPERVISOR) != KMIP_OK)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_OPERATING_SYSTEM) != KMIP_OK)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_CONTAINER) != KMIP_OK)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_ON_PREMISES) != KMIP_OK)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_OFF_PREMISES) != KMIP_OK)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_SELF_MANAGED) != KMIP_OK)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_OUTSOURCED) != KMIP_OK)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_VALIDATED) != KMIP_OK)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_SAME_JURISDICTION) != KMIP_OK)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    v = KMIP_1_4;
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_SOFTWARE) != KMIP_INVALID_FOR_VERSION)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_HARDWARE) != KMIP_INVALID_FOR_VERSION)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_ON_PROCESSOR) != KMIP_INVALID_FOR_VERSION)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_ON_SYSTEM) != KMIP_INVALID_FOR_VERSION)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_OFF_SYSTEM) != KMIP_INVALID_FOR_VERSION)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_HYPERVISOR) != KMIP_INVALID_FOR_VERSION)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_OPERATING_SYSTEM) != KMIP_INVALID_FOR_VERSION)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_CONTAINER) != KMIP_INVALID_FOR_VERSION)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_ON_PREMISES) != KMIP_INVALID_FOR_VERSION)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_OFF_PREMISES) != KMIP_INVALID_FOR_VERSION)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_SELF_MANAGED) != KMIP_INVALID_FOR_VERSION)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_OUTSOURCED) != KMIP_INVALID_FOR_VERSION)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_VALIDATED) != KMIP_INVALID_FOR_VERSION)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, KMIP_PROTECT_SAME_JURISDICTION) != KMIP_INVALID_FOR_VERSION)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    if(kmip_check_enum_value(v, t, -1) != KMIP_ENUM_MISMATCH)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    TEST_PASSED(tracker, __func__);
+}
+
+int
+test_init_protocol_version(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    kmip_init_protocol_version(NULL, KMIP_1_0);
+
+    ProtocolVersion pv = {0};
+
+    if(pv.major != 0)
+        TEST_FAILED(tracker, __func__, __LINE__);
+    if(pv.minor != 0)
+        TEST_FAILED(tracker, __func__, __LINE__);
+
+    kmip_init_protocol_version(&pv, KMIP_1_0);
+
+    if(pv.major != 1)
+        TEST_FAILED(tracker, __func__, __LINE__);
+    if(pv.minor != 0)
+        TEST_FAILED(tracker, __func__, __LINE__);
+
+    kmip_init_protocol_version(&pv, KMIP_1_1);
+
+    if(pv.major != 1)
+        TEST_FAILED(tracker, __func__, __LINE__);
+    if(pv.minor != 1)
+        TEST_FAILED(tracker, __func__, __LINE__);
+
+    kmip_init_protocol_version(&pv, KMIP_1_2);
+
+    if(pv.major != 1)
+        TEST_FAILED(tracker, __func__, __LINE__);
+    if(pv.minor != 2)
+        TEST_FAILED(tracker, __func__, __LINE__);
+
+    kmip_init_protocol_version(&pv, KMIP_1_3);
+
+    if(pv.major != 1)
+        TEST_FAILED(tracker, __func__, __LINE__);
+    if(pv.minor != 3)
+        TEST_FAILED(tracker, __func__, __LINE__);
+
+    kmip_init_protocol_version(&pv, KMIP_1_4);
+
+    if(pv.major != 1)
+        TEST_FAILED(tracker, __func__, __LINE__);
+    if(pv.minor != 4)
+        TEST_FAILED(tracker, __func__, __LINE__);
+
+    kmip_init_protocol_version(&pv, KMIP_2_0);
+
+    if(pv.major != 2)
+        TEST_FAILED(tracker, __func__, __LINE__);
+    if(pv.minor != 0)
+        TEST_FAILED(tracker, __func__, __LINE__);
+
+    TEST_PASSED(tracker, __func__);
+}
+
+int
+test_init_request_batch_item(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    kmip_init_request_batch_item(NULL);
+
+    RequestBatchItem rbi = {0};
+
+    if(rbi.operation != 0)
+        TEST_FAILED(tracker, __func__, __LINE__);
+    if(rbi.unique_batch_item_id != NULL)
+        TEST_FAILED(tracker, __func__, __LINE__);
+    if(rbi.request_payload != NULL)
+        TEST_FAILED(tracker, __func__, __LINE__);
+    if(rbi.ephemeral != 0)
+        TEST_FAILED(tracker, __func__, __LINE__);
+
+    kmip_init_request_batch_item(&rbi);
+
+    if(rbi.operation != 0)
+        TEST_FAILED(tracker, __func__, __LINE__);
+    if(rbi.unique_batch_item_id != NULL)
+        TEST_FAILED(tracker, __func__, __LINE__);
+    if(rbi.request_payload != NULL)
+        TEST_FAILED(tracker, __func__, __LINE__);
+    if(rbi.ephemeral != KMIP_UNSET)
+        TEST_FAILED(tracker, __func__, __LINE__);
+
+    TEST_PASSED(tracker, __func__);
+}
+
+int
+test_print_attributes(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* For now this will probably be left as a placeholder for a
+       future test. Ideally the print functions would output to
+       an arbitrary buffer so that we can verify that they are
+       correctly displaying structure content and formatting.
+       Since they currently use printf directly, this may be hard
+       to do in the short term.
+    */
+    TEST_FAILED(tracker, __func__, __LINE__);
+}
+
+int
+test_free_attributes(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* Build a dynamically allocated Attributes structure. Free it
+       with this function. Verify that all internal pointers and
+       fields are correctly nullified.
+
+       Ideally, hook into the free function managed by the context
+       and use that hook to verify that the correct free calls are
+       made on the internal Attributes structure pointers. This
+       may require more infrastructure work than currently exists.
+    */
+    TEST_FAILED(tracker, __func__, __LINE__);
+}
+
+int
+test_compare_attributes(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* Build two separate identical Attributes structures. Compare
+       them with this function and confirm they match.
+
+       Build two separate different Attributes structures. Compare
+       them with this function and confirm they do not match. This
+       may require multiple rounds, changing different parts of the
+       underlying Attributes structure. It may make more sense to
+       split this into multiple test functions.
+    */
+    TEST_FAILED(tracker, __func__, __LINE__);
+}
+
+int
+test_deep_copy_int32(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    int32 expected = 42;
+    int32 *observed = NULL;
+
+    observed = kmip_deep_copy_int32(NULL, NULL);
+    if(observed != NULL)
+        TEST_FAILED(tracker, __func__, __LINE__);
+
+    KMIP ctx = {0};
+    kmip_init(&ctx, NULL, 0, KMIP_1_0);
+
+    observed = kmip_deep_copy_int32(&ctx, NULL);
+    if(observed != NULL)
+    {
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    observed = kmip_deep_copy_int32(&ctx, &expected);
+    if(observed == NULL)
+    {
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(*observed != expected)
+    {
+        kmip_print_integer(expected);
+        kmip_print_integer(*observed);
+        ctx.free_func(ctx.state, observed);
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    ctx.free_func(ctx.state, observed);
+    kmip_destroy(&ctx);
+
+    TEST_PASSED(tracker, __func__);
+}
+
+int
+test_deep_copy_text_string(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    TextString expected = {0};
+    expected.value = "example";
+    expected.size = 7;
+    TextString *observed = NULL;
+
+    observed = kmip_deep_copy_text_string(NULL, NULL);
+    if(observed != NULL)
+        TEST_FAILED(tracker, __func__, __LINE__);
+
+    KMIP ctx = {0};
+    kmip_init(&ctx, NULL, 0, KMIP_1_0);
+
+    observed = kmip_deep_copy_text_string(&ctx, NULL);
+    if(observed != NULL)
+    {
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    observed = kmip_deep_copy_text_string(&ctx, &expected);
+    if(observed == NULL)
+    {
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_compare_text_string(&expected, observed))
+    {
+        kmip_print_text_string(1, "Name Value", &expected);
+        kmip_print_text_string(1, "Name Value", observed);
+        kmip_free_text_string(&ctx, observed);
+        ctx.free_func(ctx.state, observed);
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_free_text_string(&ctx, observed);
+    ctx.free_func(ctx.state, observed);
+    kmip_destroy(&ctx);
+
+    TEST_PASSED(tracker, __func__);
+}
+
+int
+test_deep_copy_name(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    TextString value = {0};
+    value.value = "example";
+    value.size = 7;
+    Name expected = {0};
+    expected.value = &value;
+    expected.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING;
+    Name *observed = NULL;
+
+    observed = kmip_deep_copy_name(NULL, NULL);
+    if(observed != NULL)
+        TEST_FAILED(tracker, __func__, __LINE__);
+
+    KMIP ctx = {0};
+    kmip_init(&ctx, NULL, 0, KMIP_1_0);
+
+    observed = kmip_deep_copy_name(&ctx, NULL);
+    if(observed != NULL)
+    {
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    observed = kmip_deep_copy_name(&ctx, &expected);
+    if(observed == NULL)
+    {
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_compare_name(&expected, observed))
+    {
+        kmip_print_name(1, &expected);
+        kmip_print_name(1, observed);
+        kmip_free_name(&ctx, observed);
+        ctx.free_func(ctx.state, observed);
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_free_name(&ctx, observed);
+    ctx.free_func(ctx.state, observed);
+    kmip_destroy(&ctx);
+
+    TEST_PASSED(tracker, __func__);
+}
+
+int
+test_deep_copy_attribute(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    Attribute expected = {0};
+    kmip_init_attribute(&expected);
+    Attribute *observed = NULL;
+
+    observed = kmip_deep_copy_attribute(NULL, NULL);
+    if(observed != NULL)
+        TEST_FAILED(tracker, __func__, __LINE__);
+
+    KMIP ctx = {0};
+    kmip_init(&ctx, NULL, 0, KMIP_1_0);
+
+    observed = kmip_deep_copy_attribute(&ctx, NULL);
+    if(observed != NULL)
+    {
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    /* Test deep copying an "empty" attribute. */
+    observed = kmip_deep_copy_attribute(&ctx, &expected);
+    if(observed == NULL)
+    {
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_compare_attribute(&expected, observed))
+    {
+        kmip_print_attribute(1, &expected);
+        kmip_print_attribute(1, observed);
+        kmip_free_attribute(&ctx, observed);
+        ctx.free_func(ctx.state, observed);
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_free_attribute(&ctx, observed);
+    ctx.free_func(ctx.state, observed);
+
+    /* Test deep copying a Unique Identifier attribute. */
+    TextString uuid = {0};
+    uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038";
+    uuid.size = 36;
+    expected.type = KMIP_ATTR_UNIQUE_IDENTIFIER;
+    expected.value = &uuid;
+
+    observed = kmip_deep_copy_attribute(&ctx, &expected);
+    if(observed == NULL)
+    {
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_compare_attribute(&expected, observed))
+    {
+        kmip_print_attribute(1, &expected);
+        kmip_print_attribute(1, observed);
+        kmip_free_attribute(&ctx, observed);
+        ctx.free_func(ctx.state, observed);
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_free_attribute(&ctx, observed);
+    ctx.free_func(ctx.state, observed);
+
+    /* Test deep copying an Operation Policy Name attribute. */
+    TextString policy = {0};
+    policy.value = "default";
+    policy.size = 7;
+    expected.type = KMIP_ATTR_OPERATION_POLICY_NAME;
+    expected.value = &policy;
+
+    observed = kmip_deep_copy_attribute(&ctx, &expected);
+    if(observed == NULL)
+    {
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_compare_attribute(&expected, observed))
+    {
+        kmip_print_attribute(1, &expected);
+        kmip_print_attribute(1, observed);
+        kmip_free_attribute(&ctx, observed);
+        ctx.free_func(ctx.state, observed);
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_free_attribute(&ctx, observed);
+    ctx.free_func(ctx.state, observed);
+
+    /* Test deep copying a Name attribute. */
+    TextString name_value = {0};
+    name_value.value = "example";
+    name_value.size = 7;
+    Name name = {0};
+    name.value = &name_value;
+    name.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING;
+    expected.type = KMIP_ATTR_NAME;
+    expected.value = &name;
+
+    observed = kmip_deep_copy_attribute(&ctx, &expected);
+    if(observed == NULL)
+    {
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_compare_attribute(&expected, observed))
+    {
+        kmip_print_attribute(1, &expected);
+        kmip_print_attribute(1, observed);
+        kmip_free_attribute(&ctx, observed);
+        ctx.free_func(ctx.state, observed);
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_free_attribute(&ctx, observed);
+    ctx.free_func(ctx.state, observed);
+
+    /* Test deep copying an Object Type attribute. */
+    enum object_type object_type = KMIP_OBJTYPE_SYMMETRIC_KEY;
+    expected.type = KMIP_ATTR_OBJECT_TYPE;
+    expected.value = &object_type;
+
+    observed = kmip_deep_copy_attribute(&ctx, &expected);
+    if(observed == NULL)
+    {
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_compare_attribute(&expected, observed))
+    {
+        kmip_print_attribute(1, &expected);
+        kmip_print_attribute(1, observed);
+        kmip_free_attribute(&ctx, observed);
+        ctx.free_func(ctx.state, observed);
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_free_attribute(&ctx, observed);
+    ctx.free_func(ctx.state, observed);
+
+    /* Test deep copying a Cryptographic Algorithm attribute. */
+    enum cryptographic_algorithm cryptographic_algorithm = KMIP_CRYPTOALG_AES;
+    expected.type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM;
+    expected.value = &cryptographic_algorithm;
+
+    observed = kmip_deep_copy_attribute(&ctx, &expected);
+    if(observed == NULL)
+    {
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_compare_attribute(&expected, observed))
+    {
+        kmip_print_attribute(1, &expected);
+        kmip_print_attribute(1, observed);
+        kmip_free_attribute(&ctx, observed);
+        ctx.free_func(ctx.state, observed);
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_free_attribute(&ctx, observed);
+    ctx.free_func(ctx.state, observed);
+
+    /* Test deep copying a Cryptographic Length attribute. */
+    int32 cryptographic_length = 256;
+    expected.type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH;
+    expected.value = &cryptographic_length;
+
+    observed = kmip_deep_copy_attribute(&ctx, &expected);
+    if(observed == NULL)
+    {
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_compare_attribute(&expected, observed))
+    {
+        kmip_print_attribute(1, &expected);
+        kmip_print_attribute(1, observed);
+        kmip_free_attribute(&ctx, observed);
+        ctx.free_func(ctx.state, observed);
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_free_attribute(&ctx, observed);
+    ctx.free_func(ctx.state, observed);
+
+    /* Test deep copying a Cryptographic Usage Mask attribute. */
+    int32 cryptographic_usage_mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT;
+    expected.type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK;
+    expected.value = &cryptographic_usage_mask;
+
+    observed = kmip_deep_copy_attribute(&ctx, &expected);
+    if(observed == NULL)
+    {
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_compare_attribute(&expected, observed))
+    {
+        kmip_print_attribute(1, &expected);
+        kmip_print_attribute(1, observed);
+        kmip_free_attribute(&ctx, observed);
+        ctx.free_func(ctx.state, observed);
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_free_attribute(&ctx, observed);
+    ctx.free_func(ctx.state, observed);
+
+    /* Test deep copying a State attribute. */
+    enum state state = KMIP_STATE_ACTIVE;
+    expected.type = KMIP_ATTR_STATE;
+    expected.value = &state;
+
+    observed = kmip_deep_copy_attribute(&ctx, &expected);
+    if(observed == NULL)
+    {
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+    if(!kmip_compare_attribute(&expected, observed))
+    {
+        kmip_print_attribute(1, &expected);
+        kmip_print_attribute(1, observed);
+        kmip_free_attribute(&ctx, observed);
+        ctx.free_func(ctx.state, observed);
+        kmip_destroy(&ctx);
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_free_attribute(&ctx, observed);
+    ctx.free_func(ctx.state, observed);
+    kmip_destroy(&ctx);
+
+    TEST_PASSED(tracker, __func__);
+}
+
+int
+test_decode_int8_be(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[1] = {0x42};
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    int8 value = 0;
+    
+    int result = kmip_decode_int8_be(&ctx, &value);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        value == 0x42, 
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_int32_be(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[4] = {0x11, 0x22, 0x33, 0x44};
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+
+    int32 expected = 0x11223344;
+    int32 observed = 0;
+    
+    int result = kmip_decode_int32_be(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        observed == expected,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_int64_be(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[8] = {
+        0x01, 0xB6, 0x9B, 0x4B, 0xA5, 0x74, 0x92, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    int64 expected = 0x01B69B4BA5749200;
+    int64 observed = 0;
+    
+    int result = kmip_decode_int64_be(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        observed == expected,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_integer(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[16] = {
+        0x42, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[16] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    int result = kmip_encode_integer(&ctx, KMIP_TAG_DEFAULT, 8);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_integer(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[16] = {
+        0x42, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00
+    };
+
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    int32 expected = 8;
+    int32 observed = 0;
+    
+    int result = kmip_decode_integer(&ctx, KMIP_TAG_DEFAULT, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        observed == expected,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_long(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[16] = {
+        0x42, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08,
+        0x01, 0xB6, 0x9B, 0x4B, 0xA5, 0x74, 0x92, 0x00
+    };
+    
+    uint8 observed[16] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    int result = kmip_encode_long(&ctx, KMIP_TAG_DEFAULT, 123456789000000000);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_long(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[16] = {
+        0x42, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08,
+        0x01, 0xB6, 0x9B, 0x4B, 0xA5, 0x74, 0x92, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    int64 expected = 0x01B69B4BA5749200;
+    int64 observed = 0;
+    
+    int result = kmip_decode_long(&ctx, KMIP_TAG_DEFAULT, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        observed == expected,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_enum(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[16] = {
+        0x42, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[16] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    int result = kmip_encode_enum(&ctx, KMIP_TAG_DEFAULT, KMIP_CRYPTOALG_AES);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_enum(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[16] = {
+        0x42, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    enum cryptographic_algorithm expected = KMIP_CRYPTOALG_AES;
+    enum cryptographic_algorithm observed = 0;
+    
+    int result = kmip_decode_enum(&ctx, KMIP_TAG_DEFAULT, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        observed == expected,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_bool(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[16] = {
+        0x42, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
+    };
+    
+    uint8 observed[16] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    int result = kmip_encode_bool(&ctx, KMIP_TAG_DEFAULT, KMIP_TRUE);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_bool(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[16] = {
+        0x42, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    bool32 expected = KMIP_TRUE;
+    bool32 observed = 0;
+    
+    int result = kmip_decode_bool(&ctx, KMIP_TAG_DEFAULT, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        observed == expected,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_text_string(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[24] = {
+        0x42, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0B,
+        0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F,
+        0x72, 0x6C, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[24] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+
+    struct text_string example = {0};
+    example.value = "Hello World";
+    example.size = 11;
+    
+    int result = kmip_encode_text_string(&ctx, KMIP_TAG_DEFAULT, &example);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_text_string(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[24] = {
+        0x42, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0B,
+        0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F,
+        0x72, 0x6C, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+
+    struct text_string expected = {0};
+    expected.value = "Hello World";
+    expected.size = 11;
+    struct text_string observed = {0};
+    
+    int result = kmip_decode_text_string(&ctx, KMIP_TAG_DEFAULT, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_text_string(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_text_string(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_byte_string(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[16] = {
+        0x42, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03,
+        0x01, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[16] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    uint8 str[3] = {0x01, 0x02, 0x03};
+    
+    struct byte_string example = {0};
+    example.value = str;
+    example.size = 3;
+    
+    int result = kmip_encode_byte_string(&ctx, KMIP_TAG_DEFAULT, &example);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_byte_string(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[16] = {
+        0x42, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03,
+        0x01, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+
+    uint8 str[3] = {0x01, 0x02, 0x03};
+    
+    struct byte_string expected = {0};
+    expected.value = str;
+    expected.size = 3;
+    struct byte_string observed = {0};
+    
+    int result = kmip_decode_byte_string(&ctx, KMIP_TAG_DEFAULT, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_byte_string(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_byte_string(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_date_time(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[16] = {
+        0x42, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x08,
+        0x00, 0x00, 0x00, 0x00, 0x47, 0xDA, 0x67, 0xF8
+    };
+    
+    uint8 observed[16] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    int result = kmip_encode_date_time(&ctx, KMIP_TAG_DEFAULT, 1205495800);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_date_time(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[16] = {
+        0x42, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x08,
+        0x00, 0x00, 0x00, 0x00, 0x47, 0xDA, 0x67, 0xF8
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    uint64 expected = 1205495800;
+    uint64 observed = 0;
+    
+    int result = kmip_decode_date_time(&ctx, KMIP_TAG_DEFAULT, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        observed == expected,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_interval(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[16] = {
+        0x42, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x0D, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[16] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    int result = kmip_encode_interval(&ctx, KMIP_TAG_DEFAULT, 864000);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_interval(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[16] = {
+        0x42, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x0D, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    uint32 expected = 864000;
+    uint32 observed = 0;
+    
+    int result = kmip_decode_interval(&ctx, KMIP_TAG_DEFAULT, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        observed == expected,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_name(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[48] = {
+        0x42, 0x00, 0x53, 0x01, 0x00, 0x00, 0x00, 0x28,
+        0x42, 0x00, 0x55, 0x07, 0x00, 0x00, 0x00, 0x09,
+        0x54, 0x65, 0x6D, 0x70, 0x6C, 0x61, 0x74, 0x65,
+        0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[48] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct text_string value = {0};
+    value.value = "Template1";
+    value.size = 9;
+    
+    struct name n = {0};
+    n.value = &value;
+    n.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING;
+    
+    int result = kmip_encode_name(&ctx, &n);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_name(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[48] = {
+        0x42, 0x00, 0x53, 0x01, 0x00, 0x00, 0x00, 0x28,
+        0x42, 0x00, 0x55, 0x07, 0x00, 0x00, 0x00, 0x09,
+        0x54, 0x65, 0x6D, 0x70, 0x6C, 0x61, 0x74, 0x65,
+        0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct text_string value = {0};
+    value.value = "Template1";
+    value.size = 9;
+    
+    struct name expected = {0};
+    expected.value = &value;
+    expected.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING;
+    struct name observed = {0};
+    
+    int result = kmip_decode_name(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_name(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_name(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_protection_storage_masks(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following set of values:
+    *  Protection Storage Masks
+    *      Protection Storage Mask
+    *          Software
+    *          Hardware
+    *          On Processor
+    *          On System
+    *          Off System
+    *          Hypervisor
+    *          Operating System
+    *          Container
+    *          On Premises
+    *          Off Premises
+    *          Self Managed
+    *          Outsourced
+    *          Validated
+    *          Same Jurisdiction
+    *      Protection Storage Mask
+    *          Software
+    *          Hardware
+    */
+    uint8 expected[40] = {
+        0x42, 0x01, 0x5F, 0x01, 0x00, 0x00, 0x00, 0x20,
+        0x42, 0x01, 0x5E, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x01, 0x5E, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00
+    };
+
+    uint8 observed[40] = {0};
+    KMIP ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0);
+
+    LinkedList list = {0};
+    LinkedListItem item_1 = {0};
+    int32 mask_1 = 0x3FFF;
+    item_1.data = &mask_1;
+
+    LinkedListItem item_2 = {0};
+    int32 mask_2 = 0x0003;
+    item_2.data = &mask_2;
+
+    kmip_linked_list_enqueue(&list, &item_1);
+    kmip_linked_list_enqueue(&list, &item_2);
+
+    ProtectionStorageMasks psm = {0};
+    psm.masks = &list;
+
+    int result = kmip_encode_protection_storage_masks(&ctx, &psm);
+    result = report_encoding_test_result(tracker, &ctx, expected, observed, result, __func__);
+
+    kmip_destroy(&ctx);
+
+    return(result);
+}
+
+int
+test_decode_protection_storage_masks(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following set of values:
+    *  Protection Storage Masks
+    *      Protection Storage Mask
+    *          Software
+    *          Hardware
+    *          On Processor
+    *          On System
+    *          Off System
+    *          Hypervisor
+    *          Operating System
+    *          Container
+    *          On Premises
+    *          Off Premises
+    *          Self Managed
+    *          Outsourced
+    *          Validated
+    *          Same Jurisdiction
+    *      Protection Storage Mask
+    *          Software
+    *          Hardware
+    */
+    uint8 encoding[40] = {
+        0x42, 0x01, 0x5F, 0x01, 0x00, 0x00, 0x00, 0x20,
+        0x42, 0x01, 0x5E, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x01, 0x5E, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00
+    };
+
+    KMIP ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0);
+
+    LinkedList list = {0};
+    LinkedListItem item_1 = {0};
+    int32 mask_1 = 0x3FFF;
+    item_1.data = &mask_1;
+
+    LinkedListItem item_2 = {0};
+    int32 mask_2 = 0x0003;
+    item_2.data = &mask_2;
+
+    kmip_linked_list_enqueue(&list, &item_1);
+    kmip_linked_list_enqueue(&list, &item_2);
+
+    ProtectionStorageMasks expected = {0};
+    expected.masks = &list;
+
+    ProtectionStorageMasks observed = {0};
+    int result = kmip_decode_protection_storage_masks(&ctx, &observed);
+    int comparison = kmip_compare_protection_storage_masks(&expected, &observed);
+    if(!comparison)
+    {
+        kmip_print_protection_storage_masks(1, &expected);
+        kmip_print_protection_storage_masks(1, &observed);
+    }
+    result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__);
+
+    kmip_free_protection_storage_masks(&ctx, &observed);
+    kmip_destroy(&ctx);
+
+    return(result);
+}
+
+int
+test_encode_attribute_unique_identifier(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[88] = {
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x50,
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x11,
+        0x55, 0x6E, 0x69, 0x71, 0x75, 0x65, 0x20, 0x49,
+        0x64, 0x65, 0x6E, 0x74, 0x69, 0x66, 0x69, 0x65,
+        0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x0B, 0x07, 0x00, 0x00, 0x00, 0x24,
+        0x34, 0x39, 0x61, 0x31, 0x63, 0x61, 0x38, 0x38,
+        0x2D, 0x36, 0x62, 0x65, 0x61, 0x2D, 0x34, 0x66,
+        0x62, 0x32, 0x2D, 0x62, 0x34, 0x35, 0x30, 0x2D,
+        0x37, 0x65, 0x35, 0x38, 0x38, 0x30, 0x32, 0x63,
+        0x33, 0x30, 0x33, 0x38, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[88] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038";
+    uuid.size = 36;
+    
+    struct attribute attr = {0};
+    kmip_init_attribute(&attr);
+    
+    attr.type = KMIP_ATTR_UNIQUE_IDENTIFIER;
+    attr.value = &uuid;
+    
+    int result = kmip_encode_attribute(&ctx, &attr);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_attribute_unique_identifier(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[88] = {
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x50,
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x11,
+        0x55, 0x6E, 0x69, 0x71, 0x75, 0x65, 0x20, 0x49,
+        0x64, 0x65, 0x6E, 0x74, 0x69, 0x66, 0x69, 0x65,
+        0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x0B, 0x07, 0x00, 0x00, 0x00, 0x24,
+        0x34, 0x39, 0x61, 0x31, 0x63, 0x61, 0x38, 0x38,
+        0x2D, 0x36, 0x62, 0x65, 0x61, 0x2D, 0x34, 0x66,
+        0x62, 0x32, 0x2D, 0x62, 0x34, 0x35, 0x30, 0x2D,
+        0x37, 0x65, 0x35, 0x38, 0x38, 0x30, 0x32, 0x63,
+        0x33, 0x30, 0x33, 0x38, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038";
+    uuid.size = 36;
+    
+    struct attribute expected = {0};
+    kmip_init_attribute(&expected);
+    expected.type = KMIP_ATTR_UNIQUE_IDENTIFIER;
+    expected.value = &uuid;
+    struct attribute observed = {0};
+    kmip_init_attribute(&observed);
+    
+    int result = kmip_decode_attribute(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_attribute(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_attribute(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_attribute_name(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[72] = {
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x40,
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x04,
+        0x4E, 0x61, 0x6D, 0x65, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x0B, 0x01, 0x00, 0x00, 0x00, 0x28,
+        0x42, 0x00, 0x55, 0x07, 0x00, 0x00, 0x00, 0x09,
+        0x54, 0x65, 0x6D, 0x70, 0x6C, 0x61, 0x74, 0x65,
+        0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[72] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct text_string value = {0};
+    value.value = "Template1";
+    value.size = 9;
+    
+    struct name n = {0};
+    n.value = &value;
+    n.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING;
+    
+    struct attribute attr = {0};
+    kmip_init_attribute(&attr);
+    
+    attr.type = KMIP_ATTR_NAME;
+    attr.value = &n;
+    
+    int result = kmip_encode_attribute(&ctx, &attr);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_attribute_name(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[72] = {
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x40,
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x04,
+        0x4E, 0x61, 0x6D, 0x65, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x0B, 0x01, 0x00, 0x00, 0x00, 0x28,
+        0x42, 0x00, 0x55, 0x07, 0x00, 0x00, 0x00, 0x09,
+        0x54, 0x65, 0x6D, 0x70, 0x6C, 0x61, 0x74, 0x65,
+        0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct text_string value = {0};
+    value.value = "Template1";
+    value.size = 9;
+    
+    struct name n = {0};
+    n.value = &value;
+    n.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING;
+    
+    struct attribute expected = {0};
+    kmip_init_attribute(&expected);
+    expected.type = KMIP_ATTR_NAME;
+    expected.value = &n;
+    struct attribute observed = {0};
+    kmip_init_attribute(&observed);
+    
+    int result = kmip_decode_attribute(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_attribute(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_attribute(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_attribute_object_type(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[48] = {
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x28,
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x0B,
+        0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x54,
+        0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[48] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    enum object_type t = KMIP_OBJTYPE_SYMMETRIC_KEY;
+    struct attribute attr = {0};
+    kmip_init_attribute(&attr);
+    
+    attr.type = KMIP_ATTR_OBJECT_TYPE;
+    attr.value = &t;
+    
+    int result = kmip_encode_attribute(&ctx, &attr);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_attribute_object_type(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[48] = {
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x28,
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x0B,
+        0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x54,
+        0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    enum object_type t = KMIP_OBJTYPE_SYMMETRIC_KEY;
+    struct attribute expected = {0};
+    kmip_init_attribute(&expected);
+    expected.type = KMIP_ATTR_OBJECT_TYPE;
+    expected.value = &t;
+    struct attribute observed = {0};
+    kmip_init_attribute(&observed);
+    
+    int result = kmip_decode_attribute(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_attribute(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_attribute(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_attribute_cryptographic_algorithm(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[56] = {
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30,
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x17,
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72,
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C,
+        0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00,
+        0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[56] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    enum cryptographic_algorithm a = KMIP_CRYPTOALG_AES;
+    struct attribute attr = {0};
+    kmip_init_attribute(&attr);
+    
+    attr.type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM;
+    attr.value = &a;
+    
+    int result = kmip_encode_attribute(&ctx, &attr);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_attribute_cryptographic_algorithm(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[56] = {
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30,
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x17,
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72,
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C,
+        0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00,
+        0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    enum cryptographic_algorithm a = KMIP_CRYPTOALG_AES;
+    struct attribute expected = {0};
+    kmip_init_attribute(&expected);
+    expected.type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM;
+    expected.value = &a;
+    struct attribute observed = {0};
+    kmip_init_attribute(&observed);
+    
+    int result = kmip_decode_attribute(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_attribute(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_attribute(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_attribute_cryptographic_length(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[56] = {
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30,
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x14,
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72,
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x4C, 0x65,
+        0x6E, 0x67, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[56] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    int32 length = 128;
+    struct attribute attr = {0};
+    kmip_init_attribute(&attr);
+    
+    attr.type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH;
+    attr.value = &length;
+    
+    int result = kmip_encode_attribute(&ctx, &attr);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_attribute_cryptographic_length(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[56] = {
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30,
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x14,
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72,
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x4C, 0x65,
+        0x6E, 0x67, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    int32 length = 128;
+    struct attribute expected = {0};
+    kmip_init_attribute(&expected);
+    expected.type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH;
+    expected.value = &length;
+    struct attribute observed = {0};
+    kmip_init_attribute(&observed);
+    
+    int result = kmip_decode_attribute(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_attribute(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_attribute(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_attribute_operation_policy_name(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[56] = {
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30,
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x15,
+        0x4F, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F,
+        0x6E, 0x20, 0x50, 0x6F, 0x6C, 0x69, 0x63, 0x79,
+        0x20, 0x4E, 0x61, 0x6D, 0x65, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x0B, 0x07, 0x00, 0x00, 0x00, 0x07,
+        0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x00
+    };
+    
+    uint8 observed[56] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct text_string policy = {0};
+    policy.value = "default";
+    policy.size = 7;
+    
+    struct attribute attr = {0};
+    kmip_init_attribute(&attr);
+    
+    attr.type = KMIP_ATTR_OPERATION_POLICY_NAME;
+    attr.value = &policy;
+    
+    int result = kmip_encode_attribute(&ctx, &attr);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_attribute_operation_policy_name(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[56] = {
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30,
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x15,
+        0x4F, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F,
+        0x6E, 0x20, 0x50, 0x6F, 0x6C, 0x69, 0x63, 0x79,
+        0x20, 0x4E, 0x61, 0x6D, 0x65, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x0B, 0x07, 0x00, 0x00, 0x00, 0x07,
+        0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct text_string policy = {0};
+    policy.value = "default";
+    policy.size = 7;
+    
+    struct attribute expected = {0};
+    kmip_init_attribute(&expected);
+    expected.type = KMIP_ATTR_OPERATION_POLICY_NAME;
+    expected.value = &policy;
+    struct attribute observed = {0};
+    kmip_init_attribute(&observed);
+    
+    int result = kmip_decode_attribute(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_attribute(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_attribute(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_attribute_cryptographic_usage_mask(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[56] = {
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30,
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18,
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72,
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73,
+        0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B,
+        0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[56] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT;
+    struct attribute attr = {0};
+    kmip_init_attribute(&attr);
+    
+    attr.type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK;
+    attr.value = &mask;
+    
+    int result = kmip_encode_attribute(&ctx, &attr);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_attribute_cryptographic_usage_mask(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[56] = {
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30,
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18,
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72,
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73,
+        0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B,
+        0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT;
+    struct attribute expected = {0};
+    kmip_init_attribute(&expected);
+    expected.type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK;
+    expected.value = &mask;
+    struct attribute observed = {0};
+    kmip_init_attribute(&observed);
+    
+    int result = kmip_decode_attribute(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_attribute(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_attribute(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_attribute_state(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[40] = {
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x20,
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x05, 
+        0x53, 0x74, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[40] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    enum state s = KMIP_STATE_PRE_ACTIVE;
+    struct attribute attr = {0};
+    kmip_init_attribute(&attr);
+    
+    attr.type = KMIP_ATTR_STATE;
+    attr.value = &s;
+    
+    int result = kmip_encode_attribute(&ctx, &attr);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_attribute_state(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[40] = {
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x20,
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x05, 
+        0x53, 0x74, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    enum state s = KMIP_STATE_PRE_ACTIVE;
+    struct attribute expected = {0};
+    kmip_init_attribute(&expected);
+    expected.type = KMIP_ATTR_STATE;
+    expected.value = &s;
+    struct attribute observed = {0};
+    kmip_init_attribute(&observed);
+    
+    int result = kmip_decode_attribute(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_attribute(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_attribute(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_protocol_version(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[40] = {
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20,
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[40] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct protocol_version pv = {0};
+    pv.major = 1;
+    pv.minor = 0;
+    
+    int result = kmip_encode_protocol_version(&ctx, &pv);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_protocol_version(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[40] = {
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20,
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct protocol_version expected = {0};
+    expected.major = 1;
+    expected.minor = 0;
+    struct protocol_version observed = {0};
+    
+    int result = kmip_decode_protocol_version(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_protocol_version(&expected, &observed),
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_cryptographic_parameters(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[72] = {
+        0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x40,
+        0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x5F, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x38, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x83, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[72] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct cryptographic_parameters cp = {0};
+    cp.block_cipher_mode = KMIP_BLOCK_CBC;
+    cp.padding_method = KMIP_PAD_PKCS5;
+    cp.hashing_algorithm = KMIP_HASH_SHA1;
+    cp.key_role_type = KMIP_ROLE_KEK;
+    
+    int result = kmip_encode_cryptographic_parameters(&ctx, &cp);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_cryptographic_parameters(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[72] = {
+        0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x40,
+        0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x5F, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x38, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x83, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct cryptographic_parameters expected = {0};
+    kmip_init_cryptographic_parameters(&expected);
+    expected.block_cipher_mode = KMIP_BLOCK_CBC;
+    expected.padding_method = KMIP_PAD_PKCS5;
+    expected.hashing_algorithm = KMIP_HASH_SHA1;
+    expected.key_role_type = KMIP_ROLE_KEK;
+    struct cryptographic_parameters observed = {0};
+    kmip_init_cryptographic_parameters(&observed);
+    
+    int result = kmip_decode_cryptographic_parameters(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_cryptographic_parameters(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_cryptographic_parameters(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_encryption_key_information(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[80] = {
+        0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48,
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24,
+        0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35,
+        0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, 
+        0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D,
+        0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, 
+        0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, 
+        0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[80] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "100182d5-72b8-47aa-8383-4d97d512e98a";
+    uuid.size = 36;
+    
+    struct cryptographic_parameters cp = {0};
+    cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP;
+    
+    struct encryption_key_information eki = {0};
+    eki.unique_identifier = &uuid;
+    eki.cryptographic_parameters = &cp;
+    
+    int result = kmip_encode_encryption_key_information(&ctx, &eki);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_encryption_key_information(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[80] = {
+        0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48,
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24,
+        0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35,
+        0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, 
+        0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D,
+        0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, 
+        0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, 
+        0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "100182d5-72b8-47aa-8383-4d97d512e98a";
+    uuid.size = 36;
+    
+    struct cryptographic_parameters cp = {0};
+    kmip_init_cryptographic_parameters(&cp);
+    
+    cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP;
+    
+    struct encryption_key_information expected = {0};
+    expected.unique_identifier = &uuid;
+    expected.cryptographic_parameters = &cp;
+    
+    struct encryption_key_information observed = {0};
+    
+    int result = kmip_decode_encryption_key_information(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_encryption_key_information(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_encryption_key_information(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_mac_signature_key_information(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[80] = {
+        0x42, 0x00, 0x4E, 0x01, 0x00, 0x00, 0x00, 0x48,
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24,
+        0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35,
+        0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, 
+        0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D,
+        0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, 
+        0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, 
+        0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[80] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "100182d5-72b8-47aa-8383-4d97d512e98a";
+    uuid.size = 36;
+
+    struct cryptographic_parameters cp = {0};
+    cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP;
+
+    struct mac_signature_key_information mski = {0};
+    mski.unique_identifier = &uuid;
+    mski.cryptographic_parameters = &cp;
+    
+    int result = kmip_encode_mac_signature_key_information(&ctx, &mski);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_mac_signature_key_information(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[80] = {
+        0x42, 0x00, 0x4E, 0x01, 0x00, 0x00, 0x00, 0x48,
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24,
+        0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35,
+        0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, 
+        0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D,
+        0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, 
+        0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, 
+        0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "100182d5-72b8-47aa-8383-4d97d512e98a";
+    uuid.size = 36;
+
+    struct cryptographic_parameters cp = {0};
+    kmip_init_cryptographic_parameters(&cp);
+    
+    cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP;
+
+    struct mac_signature_key_information expected = {0};
+    expected.unique_identifier = &uuid;
+    expected.cryptographic_parameters = &cp;
+    
+    struct mac_signature_key_information observed = {0};
+    
+    int result = kmip_decode_mac_signature_key_information(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_mac_signature_key_information(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_mac_signature_key_information(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_key_wrapping_data(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[104] = {
+        0x42, 0x00, 0x46, 0x01, 0x00, 0x00, 0x00, 0x60, 
+        0x42, 0x00, 0x9E, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35,
+        0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, 
+        0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, 
+        0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, 
+        0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10,
+        0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[104] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "100182d5-72b8-47aa-8383-4d97d512e98a";
+    uuid.size = 36;
+    
+    struct cryptographic_parameters cp = {0};
+    cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP;
+    
+    struct encryption_key_information eki = {0};
+    eki.unique_identifier = &uuid;
+    eki.cryptographic_parameters = &cp;
+    
+    struct key_wrapping_data kwd = {0};
+    kwd.wrapping_method = KMIP_WRAP_ENCRYPT;
+    kwd.encryption_key_info = &eki;
+    
+    int result = kmip_encode_key_wrapping_data(&ctx, &kwd);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_key_wrapping_data(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[104] = {
+        0x42, 0x00, 0x46, 0x01, 0x00, 0x00, 0x00, 0x60, 
+        0x42, 0x00, 0x9E, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35,
+        0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, 
+        0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, 
+        0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, 
+        0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10,
+        0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "100182d5-72b8-47aa-8383-4d97d512e98a";
+    uuid.size = 36;
+    
+    struct cryptographic_parameters cp = {0};
+    kmip_init_cryptographic_parameters(&cp);
+    
+    cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP;
+    
+    struct encryption_key_information eki = {0};
+    eki.unique_identifier = &uuid;
+    eki.cryptographic_parameters = &cp;
+    
+    struct key_wrapping_data expected = {0};
+    expected.wrapping_method = KMIP_WRAP_ENCRYPT;
+    expected.encryption_key_info = &eki;
+    
+    struct key_wrapping_data observed = {0};
+    
+    int result = kmip_decode_key_wrapping_data(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_key_wrapping_data(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_key_wrapping_data(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_key_material_byte_string(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[24] = {
+        0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x10,
+        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+        0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
+    };
+    
+    uint8 observed[24] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    uint8 value[16] = {
+        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+        0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
+    };
+    struct byte_string key = {0};
+    key.value = value;
+    key.size = ARRAY_LENGTH(value);
+    
+    int result = kmip_encode_key_material(&ctx, KMIP_KEYFORMAT_RAW, &key);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_key_material_byte_string(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[24] = {
+        0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x10,
+        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+        0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    uint8 value[16] = {
+        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+        0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
+    };
+    struct byte_string expected = {0};
+    expected.value = value;
+    expected.size = ARRAY_LENGTH(value);
+    
+    struct byte_string *expected_ptr = &expected;
+    struct byte_string *observed_ptr = NULL;
+    
+    int result = kmip_decode_key_material(
+        &ctx,
+        KMIP_KEYFORMAT_RAW,
+        (void**)&observed_ptr);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_key_material(KMIP_KEYFORMAT_RAW, (void**)&expected_ptr, (void**)&observed_ptr),
+        result,
+        __func__);
+    kmip_free_key_material(&ctx, KMIP_KEYFORMAT_RAW, (void**)&observed_ptr);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_key_material_transparent_symmetric_key(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[48] = {
+        0x42, 0x00, 0x43, 0x01, 0x00, 0x00, 0x00, 0x28, 
+        0x42, 0x00, 0x3F, 0x08, 0x00, 0x00, 0x00, 0x20, 
+        0x00, 0x00, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33, 
+        0x44, 0x44, 0x55, 0x55, 0x66, 0x66, 0x77, 0x77,
+        0x88, 0x88, 0x99, 0x99, 0xAA, 0xAA, 0xBB, 0xBB,
+        0xCC, 0xCC, 0xDD, 0xDD, 0xEE, 0xEE, 0xFF, 0xFF
+    };
+    
+    uint8 observed[48] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    uint8 value[32] = {
+        0x00, 0x00, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33, 
+        0x44, 0x44, 0x55, 0x55, 0x66, 0x66, 0x77, 0x77,
+        0x88, 0x88, 0x99, 0x99, 0xAA, 0xAA, 0xBB, 0xBB,
+        0xCC, 0xCC, 0xDD, 0xDD, 0xEE, 0xEE, 0xFF, 0xFF
+    };
+    struct byte_string key = {0};
+    key.value = value;
+    key.size = ARRAY_LENGTH(value);
+    struct transparent_symmetric_key tsk = {0};
+    tsk.key = &key;
+    
+    int result = kmip_encode_key_material(&ctx, KMIP_KEYFORMAT_TRANS_SYMMETRIC_KEY, &tsk);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_key_material_transparent_symmetric_key(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[48] = {
+        0x42, 0x00, 0x43, 0x01, 0x00, 0x00, 0x00, 0x28, 
+        0x42, 0x00, 0x3F, 0x08, 0x00, 0x00, 0x00, 0x20, 
+        0x00, 0x00, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33, 
+        0x44, 0x44, 0x55, 0x55, 0x66, 0x66, 0x77, 0x77,
+        0x88, 0x88, 0x99, 0x99, 0xAA, 0xAA, 0xBB, 0xBB,
+        0xCC, 0xCC, 0xDD, 0xDD, 0xEE, 0xEE, 0xFF, 0xFF
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    uint8 value[32] = {
+        0x00, 0x00, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33, 
+        0x44, 0x44, 0x55, 0x55, 0x66, 0x66, 0x77, 0x77,
+        0x88, 0x88, 0x99, 0x99, 0xAA, 0xAA, 0xBB, 0xBB,
+        0xCC, 0xCC, 0xDD, 0xDD, 0xEE, 0xEE, 0xFF, 0xFF
+    };
+    struct byte_string key = {0};
+    key.value = value;
+    key.size = ARRAY_LENGTH(value);
+    struct transparent_symmetric_key expected = {0};
+    expected.key = &key;
+    
+    struct transparent_symmetric_key *expected_ptr = &expected;
+    struct transparent_symmetric_key *observed_ptr = NULL;
+    
+    int result = kmip_decode_key_material(
+        &ctx,
+        KMIP_KEYFORMAT_TRANS_SYMMETRIC_KEY,
+        (void**)&observed_ptr);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_key_material(KMIP_KEYFORMAT_TRANS_SYMMETRIC_KEY, (void**)&expected_ptr, (void**)&observed_ptr),
+        result,
+        __func__);
+    kmip_free_key_material(
+        &ctx,
+        KMIP_KEYFORMAT_TRANS_SYMMETRIC_KEY,
+        (void**)&observed_ptr);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_key_value(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[32] = {
+        0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x18,
+        0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x10,
+        0xD3, 0x51, 0x91, 0x0F, 0x1D, 0x79, 0x34, 0xD6,
+        0xE2, 0xAE, 0x17, 0x57, 0x65, 0x64, 0xE2, 0xBC
+    };
+    
+    uint8 observed[32] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    uint8 value[16] = {
+        0xD3, 0x51, 0x91, 0x0F, 0x1D, 0x79, 0x34, 0xD6,
+        0xE2, 0xAE, 0x17, 0x57, 0x65, 0x64, 0xE2, 0xBC
+    };
+    struct byte_string key = {0};
+    key.value = value;
+    key.size = ARRAY_LENGTH(value);
+    
+    struct key_value kv = {0};
+    kv.key_material = &key;
+    
+    int result = kmip_encode_key_value(&ctx, KMIP_KEYFORMAT_RAW, &kv);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_key_value(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[32] = {
+        0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x18,
+        0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x10,
+        0xD3, 0x51, 0x91, 0x0F, 0x1D, 0x79, 0x34, 0xD6,
+        0xE2, 0xAE, 0x17, 0x57, 0x65, 0x64, 0xE2, 0xBC
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    uint8 value[16] = {
+        0xD3, 0x51, 0x91, 0x0F, 0x1D, 0x79, 0x34, 0xD6,
+        0xE2, 0xAE, 0x17, 0x57, 0x65, 0x64, 0xE2, 0xBC
+    };
+    struct byte_string key = {0};
+    key.value = value;
+    key.size = ARRAY_LENGTH(value);
+    
+    struct key_value expected = {0};
+    expected.key_material = &key;
+    struct key_value observed = {0};
+    
+    int result = kmip_decode_key_value(&ctx, KMIP_KEYFORMAT_RAW, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_key_value(KMIP_KEYFORMAT_RAW, &expected, &observed),
+        result,
+        __func__);
+    kmip_free_key_value(&ctx, KMIP_KEYFORMAT_RAW, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_key_value_with_attributes(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[144] = {
+        0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x88, 
+        0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x10, 
+        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+        0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x17, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C, 
+        0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, 
+        0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x14,
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x4C, 0x65, 
+        0x6E, 0x67, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[144] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    uint8 value[16] = {
+        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+        0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
+    };
+    struct byte_string key = {0};
+    key.value = value;
+    key.size = ARRAY_LENGTH(value);
+    
+    struct attribute attributes[2] = {0};
+    for(int i = 0; i < 2; i++)
+    {
+        kmip_init_attribute(&attributes[i]);
+    }
+    
+    enum cryptographic_algorithm ca = KMIP_CRYPTOALG_AES;
+    int length = 128;
+    attributes[0].type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM;
+    attributes[0].value = &ca;
+    attributes[1].type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH;
+    attributes[1].value = &length;
+    
+    struct key_value kv = {0};
+    kv.key_material = &key;
+    kv.attributes = attributes;
+    kv.attribute_count = ARRAY_LENGTH(attributes);
+    
+    int result = kmip_encode_key_value(&ctx, KMIP_KEYFORMAT_RAW, &kv);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_key_value_with_attributes(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[144] = {
+        0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x88, 
+        0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x10, 
+        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+        0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x17, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C, 
+        0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, 
+        0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x14,
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x4C, 0x65, 
+        0x6E, 0x67, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    uint8 value[16] = {
+        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+        0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
+    };
+    struct byte_string key = {0};
+    key.value = value;
+    key.size = ARRAY_LENGTH(value);
+    
+    struct attribute attributes[2] = {0};
+    for(size_t i = 0; i < 2; i++)
+    {
+        kmip_init_attribute(&attributes[i]);
+    }
+    
+    enum cryptographic_algorithm ca = KMIP_CRYPTOALG_AES;
+    int length = 128;
+    attributes[0].type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM;
+    attributes[0].value = &ca;
+    attributes[1].type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH;
+    attributes[1].value = &length;
+    
+    struct key_value expected = {0};
+    expected.key_material = &key;
+    expected.attributes = attributes;
+    expected.attribute_count = ARRAY_LENGTH(attributes);
+    struct key_value observed = {0};
+    
+    int result = kmip_decode_key_value(&ctx, KMIP_KEYFORMAT_RAW, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_key_value(KMIP_KEYFORMAT_RAW, &expected, &observed),
+        result,
+        __func__);
+    kmip_free_key_value(&ctx, KMIP_KEYFORMAT_RAW, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_key_block_key_value_byte_string(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[192] = {
+        0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0xB8, 
+        0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x45, 0x08, 0x00, 0x00, 0x00, 0x18, 
+        0x1F, 0xA6, 0x8B, 0x0A, 0x81, 0x12, 0xB4, 0x47, 
+        0xAE, 0xF3, 0x4B, 0xD8, 0xFB, 0x5A, 0x7B, 0x82, 
+        0x9D, 0x3E, 0x86, 0x23, 0x71, 0xD2, 0xCF, 0xE5, 
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x46, 0x01, 0x00, 0x00, 0x00, 0x60, 
+        0x42, 0x00, 0x9E, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24,
+        0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35, 
+        0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, 
+        0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, 
+        0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, 
+        0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, 
+        0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[192] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    uint8 value[24] = {
+        0x1F, 0xA6, 0x8B, 0x0A, 0x81, 0x12, 0xB4, 0x47,
+        0xAE, 0xF3, 0x4B, 0xD8, 0xFB, 0x5A, 0x7B, 0x82,
+        0x9D, 0x3E, 0x86, 0x23, 0x71, 0xD2, 0xCF, 0xE5
+    };
+    struct byte_string key = {0};
+    key.value = value;
+    key.size = ARRAY_LENGTH(value);
+    
+    struct text_string uuid = {0};
+    uuid.value = "100182d5-72b8-47aa-8383-4d97d512e98a";
+    uuid.size = 36;
+    
+    struct cryptographic_parameters cp = {0};
+    cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP;
+    
+    struct encryption_key_information eki = {0};
+    eki.unique_identifier = &uuid;
+    eki.cryptographic_parameters = &cp;
+    
+    struct key_wrapping_data kwd = {0};
+    kwd.wrapping_method = KMIP_WRAP_ENCRYPT;
+    kwd.encryption_key_info = &eki;
+    
+    struct key_block kb = {0};
+    kb.key_format_type = KMIP_KEYFORMAT_RAW;
+    kb.key_value = &key;
+    kb.cryptographic_algorithm = KMIP_CRYPTOALG_AES;
+    kb.cryptographic_length = 128;
+    kb.key_wrapping_data = &kwd;
+    
+    int result = kmip_encode_key_block(&ctx, &kb);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_key_block_key_value_byte_string(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[192] = {
+        0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0xB8, 
+        0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x45, 0x08, 0x00, 0x00, 0x00, 0x18, 
+        0x1F, 0xA6, 0x8B, 0x0A, 0x81, 0x12, 0xB4, 0x47, 
+        0xAE, 0xF3, 0x4B, 0xD8, 0xFB, 0x5A, 0x7B, 0x82, 
+        0x9D, 0x3E, 0x86, 0x23, 0x71, 0xD2, 0xCF, 0xE5, 
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x46, 0x01, 0x00, 0x00, 0x00, 0x60, 
+        0x42, 0x00, 0x9E, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24,
+        0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35, 
+        0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, 
+        0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, 
+        0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, 
+        0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, 
+        0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    uint8 value[24] = {
+        0x1F, 0xA6, 0x8B, 0x0A, 0x81, 0x12, 0xB4, 0x47,
+        0xAE, 0xF3, 0x4B, 0xD8, 0xFB, 0x5A, 0x7B, 0x82,
+        0x9D, 0x3E, 0x86, 0x23, 0x71, 0xD2, 0xCF, 0xE5
+    };
+    struct byte_string key = {0};
+    key.value = value;
+    key.size = ARRAY_LENGTH(value);
+    
+    struct text_string uuid = {0};
+    uuid.value = "100182d5-72b8-47aa-8383-4d97d512e98a";
+    uuid.size = 36;
+    
+    struct cryptographic_parameters cp = {0};
+    kmip_init_cryptographic_parameters(&cp);
+    
+    cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP;
+    
+    struct encryption_key_information eki = {0};
+    eki.unique_identifier = &uuid;
+    eki.cryptographic_parameters = &cp;
+    
+    struct key_wrapping_data kwd = {0};
+    kwd.wrapping_method = KMIP_WRAP_ENCRYPT;
+    kwd.encryption_key_info = &eki;
+    
+    struct key_block expected = {0};
+    kmip_init_key_block(&expected);
+    
+    expected.key_format_type = KMIP_KEYFORMAT_RAW;
+    expected.key_value = &key;
+    expected.key_value_type = KMIP_TYPE_BYTE_STRING;
+    expected.cryptographic_algorithm = KMIP_CRYPTOALG_AES;
+    expected.cryptographic_length = 128;
+    expected.key_wrapping_data = &kwd;
+    
+    struct key_block observed = {0};
+    kmip_init_key_block(&observed);
+    
+    int result = kmip_decode_key_block(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_key_block(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_key_block(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_key_block_key_value_structure(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[88] = {
+        0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x50, 
+        0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x18, 
+        0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x10, 
+        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+        0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[88] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    uint8 value[16] = {
+        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+        0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
+    };
+    struct byte_string key = {0};
+    key.value = value;
+    key.size = ARRAY_LENGTH(value);
+    
+    struct key_value kv = {0};
+    kv.key_material = &key;
+    
+    struct key_block kb = {0};
+    kb.key_format_type = KMIP_KEYFORMAT_RAW;
+    kb.key_value = &kv;
+    kb.cryptographic_algorithm = KMIP_CRYPTOALG_AES;
+    kb.cryptographic_length = 128;
+    
+    int result = kmip_encode_key_block(&ctx, &kb);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_key_block_key_value_structure(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[88] = {
+        0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x50, 
+        0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x18, 
+        0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x10, 
+        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+        0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    uint8 value[16] = {
+        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+        0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
+    };
+    struct byte_string key = {0};
+    key.value = value;
+    key.size = ARRAY_LENGTH(value);
+    
+    struct key_value kv = {0};
+    kv.key_material = &key;
+    
+    struct key_block expected = {0};
+    kmip_init_key_block(&expected);
+    
+    expected.key_format_type = KMIP_KEYFORMAT_RAW;
+    expected.key_value = &kv;
+    expected.key_value_type = KMIP_TYPE_STRUCTURE;
+    expected.cryptographic_algorithm = KMIP_CRYPTOALG_AES;
+    expected.cryptographic_length = 128;
+    
+    struct key_block observed = {0};
+    kmip_init_key_block(&observed);
+    
+    int result = kmip_decode_key_block(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_key_block(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_key_block(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_symmetric_key(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[96] = {
+        0x42, 0x00, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x58, 
+        0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x50, 
+        0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x18, 
+        0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x10, 
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
+        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[96] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    uint8 value[16] = {
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+    };
+    struct byte_string key = {0};
+    key.value = value;
+    key.size = ARRAY_LENGTH(value);
+    
+    struct key_value kv = {0};
+    kv.key_material = &key;
+    
+    struct key_block kb = {0};
+    kb.key_format_type = KMIP_KEYFORMAT_RAW;
+    kb.key_value = &kv;
+    kb.cryptographic_algorithm = KMIP_CRYPTOALG_AES;
+    kb.cryptographic_length = 128;
+    
+    struct symmetric_key sk = {0};
+    sk.key_block = &kb;
+    
+    int result = kmip_encode_symmetric_key(&ctx, &sk);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_symmetric_key(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[96] = {
+        0x42, 0x00, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x58, 
+        0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x50, 
+        0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x18, 
+        0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x10, 
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
+        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    uint8 value[16] = {
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+    };
+    struct byte_string key = {0};
+    key.value = value;
+    key.size = ARRAY_LENGTH(value);
+    
+    struct key_value kv = {0};
+    kv.key_material = &key;
+    
+    struct key_block kb = {0};
+    kb.key_format_type = KMIP_KEYFORMAT_RAW;
+    kb.key_value = &kv;
+    kb.key_value_type = KMIP_TYPE_STRUCTURE;
+    kb.cryptographic_algorithm = KMIP_CRYPTOALG_AES;
+    kb.cryptographic_length = 128;
+    
+    struct symmetric_key expected = {0};
+    expected.key_block = &kb;
+    
+    struct symmetric_key observed = {0};
+    
+    int result = kmip_decode_symmetric_key(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_symmetric_key(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_symmetric_key(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_public_key(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[248] = {
+        0x42, 0x00, 0x6D, 0x01, 0x00, 0x00, 0x00, 0xF0, 
+        0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0xE8, 
+        0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0xB0, 
+        0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0xA2,
+        0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, 0x2A,
+        0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 
+        0x05, 0x00, 0x03, 0x81, 0x8D, 0x00, 0x30, 0x81, 
+        0x89, 0x02, 0x81, 0x81, 0x00, 0x93, 0x04, 0x51,
+        0xC9, 0xEC, 0xD9, 0x4F, 0x5B, 0xB9, 0xDA, 0x17, 
+        0xDD, 0x09, 0x38, 0x1B, 0xD2, 0x3B, 0xE4, 0x3E, 
+        0xCA, 0x8C, 0x75, 0x39, 0xF3, 0x01, 0xFC, 0x8A, 
+        0x8C, 0xD5, 0xD5, 0x27, 0x4C, 0x3E, 0x76, 0x99, 
+        0xDB, 0xDC, 0x71, 0x1C, 0x97, 0xA7, 0xAA, 0x91, 
+        0xE2, 0xC5, 0x0A, 0x82, 0xBD, 0x0B, 0x10, 0x34, 
+        0xF0, 0xDF, 0x49, 0x3D, 0xEC, 0x16, 0x36, 0x24,
+        0x27, 0xE5, 0x8A, 0xCC, 0xE7, 0xF6, 0xCE, 0x0F, 
+        0x9B, 0xCC, 0x61, 0x7B, 0xBD, 0x8C, 0x90, 0xD0, 
+        0x09, 0x4A, 0x27, 0x03, 0xBA, 0x0D, 0x09, 0xEB, 
+        0x19, 0xD1, 0x00, 0x5F, 0x2F, 0xB2, 0x65, 0x52, 
+        0x6A, 0xAC, 0x75, 0xAF, 0x32, 0xF8, 0xBC, 0x78, 
+        0x2C, 0xDE, 0xD2, 0xA5, 0x7F, 0x81, 0x1E, 0x03,
+        0xEA, 0xF6, 0x7A, 0x94, 0x4D, 0xE5, 0xE7, 0x84, 
+        0x13, 0xDC, 0xA8, 0xF2, 0x32, 0xD0, 0x74, 0xE6,
+        0xDC, 0xEA, 0x4C, 0xEC, 0x9F, 0x02, 0x03, 0x01, 
+        0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[248] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    uint8 value[162] = {
+        0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, 0x2A, 
+        0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 
+        0x05, 0x00, 0x03, 0x81, 0x8D, 0x00, 0x30, 0x81, 
+        0x89, 0x02, 0x81, 0x81, 0x00, 0x93, 0x04, 0x51,
+        0xC9, 0xEC, 0xD9, 0x4F, 0x5B, 0xB9, 0xDA, 0x17, 
+        0xDD, 0x09, 0x38, 0x1B, 0xD2, 0x3B, 0xE4, 0x3E, 
+        0xCA, 0x8C, 0x75, 0x39, 0xF3, 0x01, 0xFC, 0x8A, 
+        0x8C, 0xD5, 0xD5, 0x27, 0x4C, 0x3E, 0x76, 0x99,
+        0xDB, 0xDC, 0x71, 0x1C, 0x97, 0xA7, 0xAA, 0x91, 
+        0xE2, 0xC5, 0x0A, 0x82, 0xBD, 0x0B, 0x10, 0x34, 
+        0xF0, 0xDF, 0x49, 0x3D, 0xEC, 0x16, 0x36, 0x24, 
+        0x27, 0xE5, 0x8A, 0xCC, 0xE7, 0xF6, 0xCE, 0x0F, 
+        0x9B, 0xCC, 0x61, 0x7B, 0xBD, 0x8C, 0x90, 0xD0, 
+        0x09, 0x4A, 0x27, 0x03, 0xBA, 0x0D, 0x09, 0xEB, 
+        0x19, 0xD1, 0x00, 0x5F, 0x2F, 0xB2, 0x65, 0x52, 
+        0x6A, 0xAC, 0x75, 0xAF, 0x32, 0xF8, 0xBC, 0x78, 
+        0x2C, 0xDE, 0xD2, 0xA5, 0x7F, 0x81, 0x1E, 0x03, 
+        0xEA, 0xF6, 0x7A, 0x94, 0x4D, 0xE5, 0xE7, 0x84,
+        0x13, 0xDC, 0xA8, 0xF2, 0x32, 0xD0, 0x74, 0xE6,
+        0xDC, 0xEA, 0x4C, 0xEC, 0x9F, 0x02, 0x03, 0x01,
+        0x00, 0x01
+    };
+    struct byte_string key = {0};
+    key.value = value;
+    key.size = ARRAY_LENGTH(value);
+    
+    struct key_value kv = {0};
+    kv.key_material = &key;
+    
+    struct key_block kb = {0};
+    kb.key_format_type = KMIP_KEYFORMAT_X509;
+    kb.key_value = &kv;
+    kb.cryptographic_algorithm = KMIP_CRYPTOALG_RSA;
+    kb.cryptographic_length = 1024;
+    
+    struct public_key pk = {0};
+    pk.key_block = &kb;
+    
+    int result = kmip_encode_public_key(&ctx, &pk);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_public_key(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[248] = {
+        0x42, 0x00, 0x6D, 0x01, 0x00, 0x00, 0x00, 0xF0, 
+        0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0xE8, 
+        0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0xB0, 
+        0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0xA2,
+        0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, 0x2A,
+        0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 
+        0x05, 0x00, 0x03, 0x81, 0x8D, 0x00, 0x30, 0x81, 
+        0x89, 0x02, 0x81, 0x81, 0x00, 0x93, 0x04, 0x51,
+        0xC9, 0xEC, 0xD9, 0x4F, 0x5B, 0xB9, 0xDA, 0x17, 
+        0xDD, 0x09, 0x38, 0x1B, 0xD2, 0x3B, 0xE4, 0x3E, 
+        0xCA, 0x8C, 0x75, 0x39, 0xF3, 0x01, 0xFC, 0x8A, 
+        0x8C, 0xD5, 0xD5, 0x27, 0x4C, 0x3E, 0x76, 0x99, 
+        0xDB, 0xDC, 0x71, 0x1C, 0x97, 0xA7, 0xAA, 0x91, 
+        0xE2, 0xC5, 0x0A, 0x82, 0xBD, 0x0B, 0x10, 0x34, 
+        0xF0, 0xDF, 0x49, 0x3D, 0xEC, 0x16, 0x36, 0x24,
+        0x27, 0xE5, 0x8A, 0xCC, 0xE7, 0xF6, 0xCE, 0x0F, 
+        0x9B, 0xCC, 0x61, 0x7B, 0xBD, 0x8C, 0x90, 0xD0, 
+        0x09, 0x4A, 0x27, 0x03, 0xBA, 0x0D, 0x09, 0xEB, 
+        0x19, 0xD1, 0x00, 0x5F, 0x2F, 0xB2, 0x65, 0x52, 
+        0x6A, 0xAC, 0x75, 0xAF, 0x32, 0xF8, 0xBC, 0x78, 
+        0x2C, 0xDE, 0xD2, 0xA5, 0x7F, 0x81, 0x1E, 0x03,
+        0xEA, 0xF6, 0x7A, 0x94, 0x4D, 0xE5, 0xE7, 0x84, 
+        0x13, 0xDC, 0xA8, 0xF2, 0x32, 0xD0, 0x74, 0xE6,
+        0xDC, 0xEA, 0x4C, 0xEC, 0x9F, 0x02, 0x03, 0x01, 
+        0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    uint8 value[162] = {
+        0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, 0x2A, 
+        0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 
+        0x05, 0x00, 0x03, 0x81, 0x8D, 0x00, 0x30, 0x81, 
+        0x89, 0x02, 0x81, 0x81, 0x00, 0x93, 0x04, 0x51,
+        0xC9, 0xEC, 0xD9, 0x4F, 0x5B, 0xB9, 0xDA, 0x17, 
+        0xDD, 0x09, 0x38, 0x1B, 0xD2, 0x3B, 0xE4, 0x3E, 
+        0xCA, 0x8C, 0x75, 0x39, 0xF3, 0x01, 0xFC, 0x8A, 
+        0x8C, 0xD5, 0xD5, 0x27, 0x4C, 0x3E, 0x76, 0x99,
+        0xDB, 0xDC, 0x71, 0x1C, 0x97, 0xA7, 0xAA, 0x91, 
+        0xE2, 0xC5, 0x0A, 0x82, 0xBD, 0x0B, 0x10, 0x34, 
+        0xF0, 0xDF, 0x49, 0x3D, 0xEC, 0x16, 0x36, 0x24, 
+        0x27, 0xE5, 0x8A, 0xCC, 0xE7, 0xF6, 0xCE, 0x0F, 
+        0x9B, 0xCC, 0x61, 0x7B, 0xBD, 0x8C, 0x90, 0xD0, 
+        0x09, 0x4A, 0x27, 0x03, 0xBA, 0x0D, 0x09, 0xEB, 
+        0x19, 0xD1, 0x00, 0x5F, 0x2F, 0xB2, 0x65, 0x52, 
+        0x6A, 0xAC, 0x75, 0xAF, 0x32, 0xF8, 0xBC, 0x78, 
+        0x2C, 0xDE, 0xD2, 0xA5, 0x7F, 0x81, 0x1E, 0x03, 
+        0xEA, 0xF6, 0x7A, 0x94, 0x4D, 0xE5, 0xE7, 0x84,
+        0x13, 0xDC, 0xA8, 0xF2, 0x32, 0xD0, 0x74, 0xE6,
+        0xDC, 0xEA, 0x4C, 0xEC, 0x9F, 0x02, 0x03, 0x01,
+        0x00, 0x01
+    };
+    struct byte_string key = {0};
+    key.value = value;
+    key.size = ARRAY_LENGTH(value);
+    
+    struct key_value kv = {0};
+    kv.key_material = &key;
+    
+    struct key_block kb = {0};
+    kb.key_format_type = KMIP_KEYFORMAT_X509;
+    kb.key_value = &kv;
+    kb.key_value_type = KMIP_TYPE_STRUCTURE;
+    kb.cryptographic_algorithm = KMIP_CRYPTOALG_RSA;
+    kb.cryptographic_length = 1024;
+    
+    struct public_key expected = {0};
+    expected.key_block = &kb;
+    
+    struct public_key observed = {0};
+    
+    int result = kmip_decode_public_key(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_public_key(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_public_key(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_private_key(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[1280] = {
+        0x42, 0x00, 0x64, 0x01, 0x00, 0x00, 0x04, 0xF8, 
+        0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x04, 0xF0, 
+        0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x04, 0xB8, 
+        0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x04, 0xA9,
+        0x30, 0x82, 0x04, 0xA5, 0x02, 0x01, 0x00, 0x02, 
+        0x82, 0x01, 0x01, 0x00, 0xAB, 0x7F, 0x16, 0x1C, 
+        0x00, 0x42, 0x49, 0x6C, 0xCD, 0x6C, 0x6D, 0x4D, 
+        0xAD, 0xB9, 0x19, 0x97, 0x34, 0x35, 0x35, 0x77, 
+        0x76, 0x00, 0x3A, 0xCF, 0x54, 0xB7, 0xAF, 0x1E, 
+        0x44, 0x0A, 0xFB, 0x80, 0xB6, 0x4A, 0x87, 0x55, 
+        0xF8, 0x00, 0x2C, 0xFE, 0xBA, 0x6B, 0x18, 0x45, 
+        0x40, 0xA2, 0xD6, 0x60, 0x86, 0xD7, 0x46, 0x48, 
+        0x34, 0x6D, 0x75, 0xB8, 0xD7, 0x18, 0x12, 0xB2, 
+        0x05, 0x38, 0x7C, 0x0F, 0x65, 0x83, 0xBC, 0x4D, 
+        0x7D, 0xC7, 0xEC, 0x11, 0x4F, 0x3B, 0x17, 0x6B, 
+        0x79, 0x57, 0xC4, 0x22, 0xE7, 0xD0, 0x3F, 0xC6,
+        0x26, 0x7F, 0xA2, 0xA6, 0xF8, 0x9B, 0x9B, 0xEE, 
+        0x9E, 0x60, 0xA1, 0xD7, 0xC2, 0xD8, 0x33, 0xE5, 
+        0xA5, 0xF4, 0xBB, 0x0B, 0x14, 0x34, 0xF4, 0xE7, 
+        0x95, 0xA4, 0x11, 0x00, 0xF8, 0xAA, 0x21, 0x49, 
+        0x00, 0xDF, 0x8B, 0x65, 0x08, 0x9F, 0x98, 0x13, 
+        0x5B, 0x1C, 0x67, 0xB7, 0x01, 0x67, 0x5A, 0xBD, 
+        0xBC, 0x7D, 0x57, 0x21, 0xAA, 0xC9, 0xD1, 0x4A, 
+        0x7F, 0x08, 0x1F, 0xCE, 0xC8, 0x0B, 0x64, 0xE8, 
+        0xA0, 0xEC, 0xC8, 0x29, 0x53, 0x53, 0xC7, 0x95, 
+        0x32, 0x8A, 0xBF, 0x70, 0xE1, 0xB4, 0x2E, 0x7B, 
+        0xB8, 0xB7, 0xF4, 0xE8, 0xAC, 0x8C, 0x81, 0x0C, 
+        0xDB, 0x66, 0xE3, 0xD2, 0x11, 0x26, 0xEB, 0xA8, 
+        0xDA, 0x7D, 0x0C, 0xA3, 0x41, 0x42, 0xCB, 0x76, 
+        0xF9, 0x1F, 0x01, 0x3D, 0xA8, 0x09, 0xE9, 0xC1, 
+        0xB7, 0xAE, 0x64, 0xC5, 0x41, 0x30, 0xFB, 0xC2, 
+        0x1D, 0x80, 0xE9, 0xC2, 0xCB, 0x06, 0xC5, 0xC8, 
+        0xD7, 0xCC, 0xE8, 0x94, 0x6A, 0x9A, 0xC9, 0x9B,
+        0x1C, 0x28, 0x15, 0xC3, 0x61, 0x2A, 0x29, 0xA8, 
+        0x2D, 0x73, 0xA1, 0xF9, 0x93, 0x74, 0xFE, 0x30, 
+        0xE5, 0x49, 0x51, 0x66, 0x2A, 0x6E, 0xDA, 0x29, 
+        0xC6, 0xFC, 0x41, 0x13, 0x35, 0xD5, 0xDC, 0x74, 
+        0x26, 0xB0, 0xF6, 0x05, 0x02, 0x03, 0x01, 0x00, 
+        0x01, 0x02, 0x82, 0x01, 0x00, 0x3B, 0x12, 0x45, 
+        0x5D, 0x53, 0xC1, 0x81, 0x65, 0x16, 0xC5, 0x18, 
+        0x49, 0x3F, 0x63, 0x98, 0xAA, 0xFA, 0x72, 0xB1, 
+        0x7D, 0xFA, 0x89, 0x4D, 0xB8, 0x88, 0xA7, 0xD4, 
+        0x8C, 0x0A, 0x47, 0xF6, 0x25, 0x79, 0xA4, 0xE6, 
+        0x44, 0xF8, 0x6D, 0xA7, 0x11, 0xFE, 0xC8, 0x50, 
+        0xCD, 0xD9, 0xDB, 0xBD, 0x17, 0xF6, 0x9A, 0x44, 
+        0x3D, 0x2E, 0xC1, 0xDD, 0x60, 0xD3, 0xC6, 0x18, 
+        0xFA, 0x74, 0xCD, 0xE5, 0xFD, 0xAF, 0xAB, 0xD6, 
+        0xBA, 0xA2, 0x6E, 0xB0, 0xA3, 0xAD, 0xB4, 0xDE, 
+        0xF6, 0x48, 0x0F, 0xB1, 0x21, 0x8C, 0xD3, 0xB0,
+        0x83, 0xE2, 0x52, 0xE8, 0x85, 0xB6, 0xF0, 0x72, 
+        0x9F, 0x98, 0xB2, 0x14, 0x4D, 0x2B, 0x72, 0x29, 
+        0x3E, 0x1B, 0x11, 0xD7, 0x33, 0x93, 0xBC, 0x41, 
+        0xF7, 0x5B, 0x15, 0xEE, 0x3D, 0x75, 0x69, 0xB4, 
+        0x99, 0x5E, 0xD1, 0xA1, 0x44, 0x25, 0xDA, 0x43, 
+        0x19, 0xB7, 0xB2, 0x6B, 0x0E, 0x8F, 0xEF, 0x17, 
+        0xC3, 0x75, 0x42, 0xAE, 0x5C, 0x6D, 0x58, 0x49, 
+        0xF8, 0x72, 0x09, 0x56, 0x7F, 0x39, 0x25, 0xA4, 
+        0x7B, 0x01, 0x6D, 0x56, 0x48, 0x59, 0x71, 0x7B, 
+        0xC5, 0x7F, 0xCB, 0x45, 0x22, 0xD0, 0xAA, 0x49, 
+        0xCE, 0x81, 0x6E, 0x5B, 0xE7, 0xB3, 0x08, 0x81, 
+        0x93, 0x23, 0x6E, 0xC9, 0xEF, 0xFF, 0x14, 0x08, 
+        0x58, 0x04, 0x5B, 0x73, 0xC5, 0xD7, 0x9B, 0xAF, 
+        0x38, 0xF7, 0xC6, 0x7F, 0x04, 0xC5, 0xDC, 0xF0, 
+        0xE3, 0x80, 0x6A, 0xD9, 0x82, 0xD1, 0x25, 0x90, 
+        0x58, 0xC3, 0x47, 0x3E, 0x84, 0x71, 0x79, 0xA8, 
+        0x78, 0xF2, 0xC6, 0xB3, 0xBD, 0x96, 0x8F, 0xB9,
+        0x9E, 0xA4, 0x6E, 0x91, 0x85, 0x89, 0x2F, 0x36,
+        0x76, 0xE7, 0x89, 0x65, 0xC2, 0xAE, 0xD4, 0x87,
+        0x7B, 0xA3, 0x91, 0x7D, 0xF0, 0x7C, 0x5E, 0x92, 
+        0x74, 0x74, 0xF1, 0x9E, 0x76, 0x4B, 0xA6, 0x1D, 
+        0xC3, 0x8D, 0x63, 0xBF, 0x29, 0x02, 0x81, 0x81, 
+        0x00, 0xD5, 0xC6, 0x9C, 0x8C, 0x3C, 0xDC, 0x24, 
+        0x64, 0x74, 0x4A, 0x79, 0x37, 0x13, 0xDA, 0xFB, 
+        0x9F, 0x1D, 0xBC, 0x79, 0x9F, 0xF9, 0x64, 0x23, 
+        0xFE, 0xCD, 0x3C, 0xBA, 0x79, 0x42, 0x86, 0xBC, 
+        0xE9, 0x20, 0xF4, 0xB5, 0xC1, 0x83, 0xF9, 0x9E, 
+        0xE9, 0x02, 0x8D, 0xB6, 0x21, 0x2C, 0x62, 0x77, 
+        0xC4, 0xC8, 0x29, 0x7F, 0xCF, 0xBC, 0xE7, 0xF7,
+        0xC2, 0x4C, 0xA4, 0xC5, 0x1F, 0xC7, 0x18, 0x2F, 
+        0xB8, 0xF4, 0x01, 0x9F, 0xB1, 0xD5, 0x65, 0x96, 
+        0x74, 0xC5, 0xCB, 0xE6, 0xD5, 0xFA, 0x99, 0x20, 
+        0x51, 0x34, 0x17, 0x60, 0xCD, 0x00, 0x73, 0x57, 
+        0x29, 0xA0, 0x70, 0xA9, 0xE5, 0x4D, 0x34, 0x2B, 
+        0xEB, 0xA8, 0xEF, 0x47, 0xEE, 0x82, 0xD3, 0xA0, 
+        0x1B, 0x04, 0xCE, 0xC4, 0xA0, 0x0D, 0x4D, 0xDB,
+        0x41, 0xE3, 0x51, 0x16, 0xFC, 0x22, 0x1E, 0x85, 
+        0x4B, 0x43, 0xA6, 0x96, 0xC0, 0xE6, 0x41, 0x9B, 
+        0x1B, 0x02, 0x81, 0x81, 0x00, 0xCD, 0x5E, 0xA7, 
+        0x70, 0x27, 0x89, 0x06, 0x4B, 0x67, 0x35, 0x40, 
+        0xCB, 0xFF, 0x09, 0x35, 0x6A, 0xD8, 0x0B, 0xC3, 
+        0xD5, 0x92, 0x81, 0x2E, 0xBA, 0x47, 0x61, 0x0B,
+        0x9F, 0xAC, 0x6A, 0xEC, 0xEF, 0xE2, 0x2A, 0xCA, 
+        0xE4, 0x38, 0x45, 0x9C, 0xDA, 0x74, 0xE5, 0x96, 
+        0x53, 0xD8, 0x8C, 0x04, 0x18, 0x9D, 0x34, 0x39, 
+        0x9B, 0xF5, 0xB1, 0x4B, 0x92, 0x0E, 0x34, 0xEF, 
+        0x38, 0xA7, 0xD0, 0x9F, 0xE6, 0x95, 0x93, 0x39, 
+        0x6E, 0x8F, 0xE7, 0x35, 0xE6, 0xF0, 0xA6, 0xAE, 
+        0x49, 0x90, 0x40, 0x10, 0x41, 0xD8, 0xA4, 0x06, 
+        0xB6, 0xFD, 0x86, 0xA1, 0x16, 0x1E, 0x45, 0xF9,
+        0x5A, 0x3E, 0xAA, 0x5C, 0x10, 0x12, 0xE6, 0x66,
+        0x2E, 0x44, 0xF1, 0x5F, 0x33, 0x5A, 0xC9, 0x71, 
+        0xE1, 0x76, 0x6B, 0x2B, 0xB9, 0xC9, 0x85, 0x10, 
+        0x99, 0x74, 0x14, 0x1B, 0x44, 0xD3, 0x7E, 0x1E, 
+        0x31, 0x98, 0x20, 0xA5, 0x5F, 0x02, 0x81, 0x81, 
+        0x00, 0xB2, 0x87, 0x12, 0x37, 0xBF, 0x9F, 0xAD, 
+        0x38, 0xC3, 0x31, 0x6A, 0xB7, 0x87, 0x7A, 0x6A, 
+        0x86, 0x80, 0x63, 0xE5, 0x42, 0xA7, 0x18, 0x6D, 
+        0x43, 0x1E, 0x8D, 0x27, 0xC1, 0x9A, 0xC0, 0x41, 
+        0x45, 0x84, 0x03, 0x39, 0x42, 0xE9, 0xFF, 0x6E, 
+        0x29, 0x73, 0xBB, 0x7B, 0x2D, 0x8B, 0x0E, 0x94, 
+        0xAD, 0x1E, 0xE8, 0x21, 0x58, 0x10, 0x8F, 0xBC,
+        0x86, 0x64, 0x51, 0x7A, 0x5A, 0x46, 0x7F, 0xB9, 
+        0x63, 0x01, 0x4B, 0xD5, 0xDC, 0xC2, 0xB4, 0xFB, 
+        0x08, 0x7C, 0x23, 0x03, 0x9D, 0x11, 0x92, 0x0D, 
+        0xBE, 0x22, 0xFD, 0x9F, 0x16, 0xB4, 0xD8, 0x9E, 
+        0x23, 0x22, 0x5C, 0xD4, 0x55, 0xAD, 0xBA, 0xF3, 
+        0x2E, 0xF4, 0x3F, 0x18, 0x58, 0x64, 0xA3, 0x6D,
+        0x63, 0x03, 0x09, 0xD6, 0x85, 0x3F, 0x77, 0x14,
+        0xB3, 0x9A, 0xAE, 0x1E, 0xBE, 0xE3, 0x93, 0x8F, 
+        0x87, 0xC2, 0x70, 0x7E, 0x17, 0x8C, 0x73, 0x9F, 
+        0x9F, 0x02, 0x81, 0x81, 0x00, 0x96, 0x90, 0xBE,
+        0xD1, 0x4B, 0x2A, 0xFA, 0xA2, 0x6D, 0x98, 0x6D, 
+        0x59, 0x22, 0x31, 0xEE, 0x27, 0xD7, 0x1D, 0x49, 
+        0x06, 0x5B, 0xD2, 0xBA, 0x1F, 0x78, 0x15, 0x7E, 
+        0x20, 0x22, 0x98, 0x81, 0xFD, 0x9D, 0x23, 0x22, 
+        0x7D, 0x0F, 0x84, 0x79, 0xEA, 0xEF, 0xA9, 0x22, 
+        0xFD, 0x75, 0xD5, 0xB1, 0x6B, 0x1A, 0x56, 0x1F,
+        0xA6, 0x68, 0x0B, 0x04, 0x0C, 0xA0, 0xBD, 0xCE, 
+        0x65, 0x0B, 0x23, 0xB9, 0x17, 0xA4, 0xB1, 0xBB, 
+        0x79, 0x83, 0xA7, 0x4F, 0xAD, 0x70, 0xE1, 0xC3, 
+        0x05, 0xCB, 0xEC, 0x2B, 0xFF, 0x1A, 0x85, 0xA7,
+        0x26, 0xA1, 0xD9, 0x02, 0x60, 0xE4, 0xF1, 0x08, 
+        0x4F, 0x51, 0x82, 0x34, 0xDC, 0xD3, 0xFE, 0x77, 
+        0x0B, 0x95, 0x20, 0x21, 0x5B, 0xD5, 0x43, 0xBB, 
+        0x6A, 0x41, 0x17, 0x71, 0x87, 0x54, 0x67, 0x6A, 
+        0x34, 0x17, 0x16, 0x66, 0xA7, 0x9F, 0x26, 0xE7, 
+        0x9C, 0x14, 0x9C, 0x5A, 0xA1, 0x02, 0x81, 0x81, 
+        0x00, 0xA0, 0xC9, 0x85, 0xA0, 0xA0, 0xA7, 0x91, 
+        0xA6, 0x59, 0xF9, 0x97, 0x31, 0x13, 0x4C, 0x44, 
+        0xF3, 0x7B, 0x2E, 0x52, 0x0A, 0x2C, 0xEA, 0x35, 
+        0x80, 0x0A, 0xD2, 0x72, 0x41, 0xED, 0x36, 0x0D, 
+        0xFD, 0xE6, 0xE8, 0xCA, 0x61, 0x4F, 0x12, 0x04, 
+        0x7F, 0xD0, 0x8B, 0x76, 0xAC, 0x4D, 0x13, 0xC0, 
+        0x56, 0xA0, 0x69, 0x9E, 0x2F, 0x98, 0xA1, 0xCA, 
+        0xC9, 0x10, 0x11, 0x29, 0x4D, 0x71, 0x20, 0x8F, 
+        0x4A, 0xBA, 0xB3, 0x3B, 0xA8, 0x7A, 0xA0, 0x51, 
+        0x7F, 0x41, 0x5B, 0xAC, 0xA8, 0x8D, 0x6B, 0xAC, 
+        0x00, 0x60, 0x88, 0xFA, 0x60, 0x1D, 0x34, 0x94, 
+        0x17, 0xE1, 0xF0, 0xC9, 0xB2, 0x3A, 0xFF, 0xA4, 
+        0xD4, 0x96, 0x61, 0x8D, 0xBC, 0x02, 0x49, 0x86, 
+        0xED, 0x69, 0x0B, 0xBB, 0x7B, 0x02, 0x57, 0x68, 
+        0xFF, 0x9D, 0xF8, 0xAC, 0x15, 0x41, 0x6F, 0x48, 
+        0x9F, 0x81, 0x29, 0xC3, 0x23, 0x41, 0xA8, 0xB4, 
+        0x4F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[1280] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    uint8 value[1193] = {
+        0x30, 0x82, 0x04, 0xA5, 0x02, 0x01, 0x00, 0x02, 
+        0x82, 0x01, 0x01, 0x00, 0xAB, 0x7F, 0x16, 0x1C, 
+        0x00, 0x42, 0x49, 0x6C, 0xCD, 0x6C, 0x6D, 0x4D, 
+        0xAD, 0xB9, 0x19, 0x97, 0x34, 0x35, 0x35, 0x77, 
+        0x76, 0x00, 0x3A, 0xCF, 0x54, 0xB7, 0xAF, 0x1E, 
+        0x44, 0x0A, 0xFB, 0x80, 0xB6, 0x4A, 0x87, 0x55, 
+        0xF8, 0x00, 0x2C, 0xFE, 0xBA, 0x6B, 0x18, 0x45, 
+        0x40, 0xA2, 0xD6, 0x60, 0x86, 0xD7, 0x46, 0x48, 
+        0x34, 0x6D, 0x75, 0xB8, 0xD7, 0x18, 0x12, 0xB2, 
+        0x05, 0x38, 0x7C, 0x0F, 0x65, 0x83, 0xBC, 0x4D, 
+        0x7D, 0xC7, 0xEC, 0x11, 0x4F, 0x3B, 0x17, 0x6B, 
+        0x79, 0x57, 0xC4, 0x22, 0xE7, 0xD0, 0x3F, 0xC6,
+        0x26, 0x7F, 0xA2, 0xA6, 0xF8, 0x9B, 0x9B, 0xEE, 
+        0x9E, 0x60, 0xA1, 0xD7, 0xC2, 0xD8, 0x33, 0xE5, 
+        0xA5, 0xF4, 0xBB, 0x0B, 0x14, 0x34, 0xF4, 0xE7, 
+        0x95, 0xA4, 0x11, 0x00, 0xF8, 0xAA, 0x21, 0x49, 
+        0x00, 0xDF, 0x8B, 0x65, 0x08, 0x9F, 0x98, 0x13, 
+        0x5B, 0x1C, 0x67, 0xB7, 0x01, 0x67, 0x5A, 0xBD, 
+        0xBC, 0x7D, 0x57, 0x21, 0xAA, 0xC9, 0xD1, 0x4A, 
+        0x7F, 0x08, 0x1F, 0xCE, 0xC8, 0x0B, 0x64, 0xE8, 
+        0xA0, 0xEC, 0xC8, 0x29, 0x53, 0x53, 0xC7, 0x95, 
+        0x32, 0x8A, 0xBF, 0x70, 0xE1, 0xB4, 0x2E, 0x7B, 
+        0xB8, 0xB7, 0xF4, 0xE8, 0xAC, 0x8C, 0x81, 0x0C, 
+        0xDB, 0x66, 0xE3, 0xD2, 0x11, 0x26, 0xEB, 0xA8, 
+        0xDA, 0x7D, 0x0C, 0xA3, 0x41, 0x42, 0xCB, 0x76, 
+        0xF9, 0x1F, 0x01, 0x3D, 0xA8, 0x09, 0xE9, 0xC1, 
+        0xB7, 0xAE, 0x64, 0xC5, 0x41, 0x30, 0xFB, 0xC2, 
+        0x1D, 0x80, 0xE9, 0xC2, 0xCB, 0x06, 0xC5, 0xC8, 
+        0xD7, 0xCC, 0xE8, 0x94, 0x6A, 0x9A, 0xC9, 0x9B,
+        0x1C, 0x28, 0x15, 0xC3, 0x61, 0x2A, 0x29, 0xA8, 
+        0x2D, 0x73, 0xA1, 0xF9, 0x93, 0x74, 0xFE, 0x30, 
+        0xE5, 0x49, 0x51, 0x66, 0x2A, 0x6E, 0xDA, 0x29, 
+        0xC6, 0xFC, 0x41, 0x13, 0x35, 0xD5, 0xDC, 0x74, 
+        0x26, 0xB0, 0xF6, 0x05, 0x02, 0x03, 0x01, 0x00, 
+        0x01, 0x02, 0x82, 0x01, 0x00, 0x3B, 0x12, 0x45, 
+        0x5D, 0x53, 0xC1, 0x81, 0x65, 0x16, 0xC5, 0x18, 
+        0x49, 0x3F, 0x63, 0x98, 0xAA, 0xFA, 0x72, 0xB1, 
+        0x7D, 0xFA, 0x89, 0x4D, 0xB8, 0x88, 0xA7, 0xD4, 
+        0x8C, 0x0A, 0x47, 0xF6, 0x25, 0x79, 0xA4, 0xE6, 
+        0x44, 0xF8, 0x6D, 0xA7, 0x11, 0xFE, 0xC8, 0x50, 
+        0xCD, 0xD9, 0xDB, 0xBD, 0x17, 0xF6, 0x9A, 0x44, 
+        0x3D, 0x2E, 0xC1, 0xDD, 0x60, 0xD3, 0xC6, 0x18, 
+        0xFA, 0x74, 0xCD, 0xE5, 0xFD, 0xAF, 0xAB, 0xD6, 
+        0xBA, 0xA2, 0x6E, 0xB0, 0xA3, 0xAD, 0xB4, 0xDE, 
+        0xF6, 0x48, 0x0F, 0xB1, 0x21, 0x8C, 0xD3, 0xB0,
+        0x83, 0xE2, 0x52, 0xE8, 0x85, 0xB6, 0xF0, 0x72, 
+        0x9F, 0x98, 0xB2, 0x14, 0x4D, 0x2B, 0x72, 0x29, 
+        0x3E, 0x1B, 0x11, 0xD7, 0x33, 0x93, 0xBC, 0x41, 
+        0xF7, 0x5B, 0x15, 0xEE, 0x3D, 0x75, 0x69, 0xB4, 
+        0x99, 0x5E, 0xD1, 0xA1, 0x44, 0x25, 0xDA, 0x43, 
+        0x19, 0xB7, 0xB2, 0x6B, 0x0E, 0x8F, 0xEF, 0x17, 
+        0xC3, 0x75, 0x42, 0xAE, 0x5C, 0x6D, 0x58, 0x49, 
+        0xF8, 0x72, 0x09, 0x56, 0x7F, 0x39, 0x25, 0xA4, 
+        0x7B, 0x01, 0x6D, 0x56, 0x48, 0x59, 0x71, 0x7B, 
+        0xC5, 0x7F, 0xCB, 0x45, 0x22, 0xD0, 0xAA, 0x49, 
+        0xCE, 0x81, 0x6E, 0x5B, 0xE7, 0xB3, 0x08, 0x81, 
+        0x93, 0x23, 0x6E, 0xC9, 0xEF, 0xFF, 0x14, 0x08, 
+        0x58, 0x04, 0x5B, 0x73, 0xC5, 0xD7, 0x9B, 0xAF, 
+        0x38, 0xF7, 0xC6, 0x7F, 0x04, 0xC5, 0xDC, 0xF0, 
+        0xE3, 0x80, 0x6A, 0xD9, 0x82, 0xD1, 0x25, 0x90, 
+        0x58, 0xC3, 0x47, 0x3E, 0x84, 0x71, 0x79, 0xA8, 
+        0x78, 0xF2, 0xC6, 0xB3, 0xBD, 0x96, 0x8F, 0xB9,
+        0x9E, 0xA4, 0x6E, 0x91, 0x85, 0x89, 0x2F, 0x36,
+        0x76, 0xE7, 0x89, 0x65, 0xC2, 0xAE, 0xD4, 0x87,
+        0x7B, 0xA3, 0x91, 0x7D, 0xF0, 0x7C, 0x5E, 0x92, 
+        0x74, 0x74, 0xF1, 0x9E, 0x76, 0x4B, 0xA6, 0x1D, 
+        0xC3, 0x8D, 0x63, 0xBF, 0x29, 0x02, 0x81, 0x81, 
+        0x00, 0xD5, 0xC6, 0x9C, 0x8C, 0x3C, 0xDC, 0x24, 
+        0x64, 0x74, 0x4A, 0x79, 0x37, 0x13, 0xDA, 0xFB, 
+        0x9F, 0x1D, 0xBC, 0x79, 0x9F, 0xF9, 0x64, 0x23, 
+        0xFE, 0xCD, 0x3C, 0xBA, 0x79, 0x42, 0x86, 0xBC, 
+        0xE9, 0x20, 0xF4, 0xB5, 0xC1, 0x83, 0xF9, 0x9E, 
+        0xE9, 0x02, 0x8D, 0xB6, 0x21, 0x2C, 0x62, 0x77, 
+        0xC4, 0xC8, 0x29, 0x7F, 0xCF, 0xBC, 0xE7, 0xF7,
+        0xC2, 0x4C, 0xA4, 0xC5, 0x1F, 0xC7, 0x18, 0x2F, 
+        0xB8, 0xF4, 0x01, 0x9F, 0xB1, 0xD5, 0x65, 0x96, 
+        0x74, 0xC5, 0xCB, 0xE6, 0xD5, 0xFA, 0x99, 0x20, 
+        0x51, 0x34, 0x17, 0x60, 0xCD, 0x00, 0x73, 0x57, 
+        0x29, 0xA0, 0x70, 0xA9, 0xE5, 0x4D, 0x34, 0x2B, 
+        0xEB, 0xA8, 0xEF, 0x47, 0xEE, 0x82, 0xD3, 0xA0, 
+        0x1B, 0x04, 0xCE, 0xC4, 0xA0, 0x0D, 0x4D, 0xDB,
+        0x41, 0xE3, 0x51, 0x16, 0xFC, 0x22, 0x1E, 0x85, 
+        0x4B, 0x43, 0xA6, 0x96, 0xC0, 0xE6, 0x41, 0x9B, 
+        0x1B, 0x02, 0x81, 0x81, 0x00, 0xCD, 0x5E, 0xA7, 
+        0x70, 0x27, 0x89, 0x06, 0x4B, 0x67, 0x35, 0x40, 
+        0xCB, 0xFF, 0x09, 0x35, 0x6A, 0xD8, 0x0B, 0xC3, 
+        0xD5, 0x92, 0x81, 0x2E, 0xBA, 0x47, 0x61, 0x0B,
+        0x9F, 0xAC, 0x6A, 0xEC, 0xEF, 0xE2, 0x2A, 0xCA, 
+        0xE4, 0x38, 0x45, 0x9C, 0xDA, 0x74, 0xE5, 0x96, 
+        0x53, 0xD8, 0x8C, 0x04, 0x18, 0x9D, 0x34, 0x39, 
+        0x9B, 0xF5, 0xB1, 0x4B, 0x92, 0x0E, 0x34, 0xEF, 
+        0x38, 0xA7, 0xD0, 0x9F, 0xE6, 0x95, 0x93, 0x39, 
+        0x6E, 0x8F, 0xE7, 0x35, 0xE6, 0xF0, 0xA6, 0xAE, 
+        0x49, 0x90, 0x40, 0x10, 0x41, 0xD8, 0xA4, 0x06, 
+        0xB6, 0xFD, 0x86, 0xA1, 0x16, 0x1E, 0x45, 0xF9,
+        0x5A, 0x3E, 0xAA, 0x5C, 0x10, 0x12, 0xE6, 0x66,
+        0x2E, 0x44, 0xF1, 0x5F, 0x33, 0x5A, 0xC9, 0x71, 
+        0xE1, 0x76, 0x6B, 0x2B, 0xB9, 0xC9, 0x85, 0x10, 
+        0x99, 0x74, 0x14, 0x1B, 0x44, 0xD3, 0x7E, 0x1E, 
+        0x31, 0x98, 0x20, 0xA5, 0x5F, 0x02, 0x81, 0x81, 
+        0x00, 0xB2, 0x87, 0x12, 0x37, 0xBF, 0x9F, 0xAD, 
+        0x38, 0xC3, 0x31, 0x6A, 0xB7, 0x87, 0x7A, 0x6A, 
+        0x86, 0x80, 0x63, 0xE5, 0x42, 0xA7, 0x18, 0x6D, 
+        0x43, 0x1E, 0x8D, 0x27, 0xC1, 0x9A, 0xC0, 0x41, 
+        0x45, 0x84, 0x03, 0x39, 0x42, 0xE9, 0xFF, 0x6E, 
+        0x29, 0x73, 0xBB, 0x7B, 0x2D, 0x8B, 0x0E, 0x94, 
+        0xAD, 0x1E, 0xE8, 0x21, 0x58, 0x10, 0x8F, 0xBC,
+        0x86, 0x64, 0x51, 0x7A, 0x5A, 0x46, 0x7F, 0xB9, 
+        0x63, 0x01, 0x4B, 0xD5, 0xDC, 0xC2, 0xB4, 0xFB, 
+        0x08, 0x7C, 0x23, 0x03, 0x9D, 0x11, 0x92, 0x0D, 
+        0xBE, 0x22, 0xFD, 0x9F, 0x16, 0xB4, 0xD8, 0x9E, 
+        0x23, 0x22, 0x5C, 0xD4, 0x55, 0xAD, 0xBA, 0xF3, 
+        0x2E, 0xF4, 0x3F, 0x18, 0x58, 0x64, 0xA3, 0x6D,
+        0x63, 0x03, 0x09, 0xD6, 0x85, 0x3F, 0x77, 0x14,
+        0xB3, 0x9A, 0xAE, 0x1E, 0xBE, 0xE3, 0x93, 0x8F, 
+        0x87, 0xC2, 0x70, 0x7E, 0x17, 0x8C, 0x73, 0x9F, 
+        0x9F, 0x02, 0x81, 0x81, 0x00, 0x96, 0x90, 0xBE,
+        0xD1, 0x4B, 0x2A, 0xFA, 0xA2, 0x6D, 0x98, 0x6D, 
+        0x59, 0x22, 0x31, 0xEE, 0x27, 0xD7, 0x1D, 0x49, 
+        0x06, 0x5B, 0xD2, 0xBA, 0x1F, 0x78, 0x15, 0x7E, 
+        0x20, 0x22, 0x98, 0x81, 0xFD, 0x9D, 0x23, 0x22, 
+        0x7D, 0x0F, 0x84, 0x79, 0xEA, 0xEF, 0xA9, 0x22, 
+        0xFD, 0x75, 0xD5, 0xB1, 0x6B, 0x1A, 0x56, 0x1F,
+        0xA6, 0x68, 0x0B, 0x04, 0x0C, 0xA0, 0xBD, 0xCE, 
+        0x65, 0x0B, 0x23, 0xB9, 0x17, 0xA4, 0xB1, 0xBB, 
+        0x79, 0x83, 0xA7, 0x4F, 0xAD, 0x70, 0xE1, 0xC3, 
+        0x05, 0xCB, 0xEC, 0x2B, 0xFF, 0x1A, 0x85, 0xA7,
+        0x26, 0xA1, 0xD9, 0x02, 0x60, 0xE4, 0xF1, 0x08, 
+        0x4F, 0x51, 0x82, 0x34, 0xDC, 0xD3, 0xFE, 0x77, 
+        0x0B, 0x95, 0x20, 0x21, 0x5B, 0xD5, 0x43, 0xBB, 
+        0x6A, 0x41, 0x17, 0x71, 0x87, 0x54, 0x67, 0x6A, 
+        0x34, 0x17, 0x16, 0x66, 0xA7, 0x9F, 0x26, 0xE7, 
+        0x9C, 0x14, 0x9C, 0x5A, 0xA1, 0x02, 0x81, 0x81, 
+        0x00, 0xA0, 0xC9, 0x85, 0xA0, 0xA0, 0xA7, 0x91, 
+        0xA6, 0x59, 0xF9, 0x97, 0x31, 0x13, 0x4C, 0x44, 
+        0xF3, 0x7B, 0x2E, 0x52, 0x0A, 0x2C, 0xEA, 0x35, 
+        0x80, 0x0A, 0xD2, 0x72, 0x41, 0xED, 0x36, 0x0D, 
+        0xFD, 0xE6, 0xE8, 0xCA, 0x61, 0x4F, 0x12, 0x04, 
+        0x7F, 0xD0, 0x8B, 0x76, 0xAC, 0x4D, 0x13, 0xC0, 
+        0x56, 0xA0, 0x69, 0x9E, 0x2F, 0x98, 0xA1, 0xCA, 
+        0xC9, 0x10, 0x11, 0x29, 0x4D, 0x71, 0x20, 0x8F, 
+        0x4A, 0xBA, 0xB3, 0x3B, 0xA8, 0x7A, 0xA0, 0x51, 
+        0x7F, 0x41, 0x5B, 0xAC, 0xA8, 0x8D, 0x6B, 0xAC, 
+        0x00, 0x60, 0x88, 0xFA, 0x60, 0x1D, 0x34, 0x94, 
+        0x17, 0xE1, 0xF0, 0xC9, 0xB2, 0x3A, 0xFF, 0xA4, 
+        0xD4, 0x96, 0x61, 0x8D, 0xBC, 0x02, 0x49, 0x86, 
+        0xED, 0x69, 0x0B, 0xBB, 0x7B, 0x02, 0x57, 0x68, 
+        0xFF, 0x9D, 0xF8, 0xAC, 0x15, 0x41, 0x6F, 0x48, 
+        0x9F, 0x81, 0x29, 0xC3, 0x23, 0x41, 0xA8, 0xB4, 
+        0x4F
+    };
+    struct byte_string key = {0};
+    key.value = value;
+    key.size = ARRAY_LENGTH(value);
+    
+    struct key_value kv = {0};
+    kv.key_material = &key;
+    
+    struct key_block kb = {0};
+    kb.key_format_type = KMIP_KEYFORMAT_PKCS1;
+    kb.key_value = &kv;
+    kb.cryptographic_algorithm = KMIP_CRYPTOALG_RSA;
+    kb.cryptographic_length = 2048;
+    
+    struct private_key pk = {0};
+    pk.key_block = &kb;
+    
+    int result = kmip_encode_private_key(&ctx, &pk);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_private_key(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[1280] = {
+        0x42, 0x00, 0x64, 0x01, 0x00, 0x00, 0x04, 0xF8, 
+        0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x04, 0xF0, 
+        0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x04, 0xB8, 
+        0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x04, 0xA9,
+        0x30, 0x82, 0x04, 0xA5, 0x02, 0x01, 0x00, 0x02, 
+        0x82, 0x01, 0x01, 0x00, 0xAB, 0x7F, 0x16, 0x1C, 
+        0x00, 0x42, 0x49, 0x6C, 0xCD, 0x6C, 0x6D, 0x4D, 
+        0xAD, 0xB9, 0x19, 0x97, 0x34, 0x35, 0x35, 0x77, 
+        0x76, 0x00, 0x3A, 0xCF, 0x54, 0xB7, 0xAF, 0x1E, 
+        0x44, 0x0A, 0xFB, 0x80, 0xB6, 0x4A, 0x87, 0x55, 
+        0xF8, 0x00, 0x2C, 0xFE, 0xBA, 0x6B, 0x18, 0x45, 
+        0x40, 0xA2, 0xD6, 0x60, 0x86, 0xD7, 0x46, 0x48, 
+        0x34, 0x6D, 0x75, 0xB8, 0xD7, 0x18, 0x12, 0xB2, 
+        0x05, 0x38, 0x7C, 0x0F, 0x65, 0x83, 0xBC, 0x4D, 
+        0x7D, 0xC7, 0xEC, 0x11, 0x4F, 0x3B, 0x17, 0x6B, 
+        0x79, 0x57, 0xC4, 0x22, 0xE7, 0xD0, 0x3F, 0xC6,
+        0x26, 0x7F, 0xA2, 0xA6, 0xF8, 0x9B, 0x9B, 0xEE, 
+        0x9E, 0x60, 0xA1, 0xD7, 0xC2, 0xD8, 0x33, 0xE5, 
+        0xA5, 0xF4, 0xBB, 0x0B, 0x14, 0x34, 0xF4, 0xE7, 
+        0x95, 0xA4, 0x11, 0x00, 0xF8, 0xAA, 0x21, 0x49, 
+        0x00, 0xDF, 0x8B, 0x65, 0x08, 0x9F, 0x98, 0x13, 
+        0x5B, 0x1C, 0x67, 0xB7, 0x01, 0x67, 0x5A, 0xBD, 
+        0xBC, 0x7D, 0x57, 0x21, 0xAA, 0xC9, 0xD1, 0x4A, 
+        0x7F, 0x08, 0x1F, 0xCE, 0xC8, 0x0B, 0x64, 0xE8, 
+        0xA0, 0xEC, 0xC8, 0x29, 0x53, 0x53, 0xC7, 0x95, 
+        0x32, 0x8A, 0xBF, 0x70, 0xE1, 0xB4, 0x2E, 0x7B, 
+        0xB8, 0xB7, 0xF4, 0xE8, 0xAC, 0x8C, 0x81, 0x0C, 
+        0xDB, 0x66, 0xE3, 0xD2, 0x11, 0x26, 0xEB, 0xA8, 
+        0xDA, 0x7D, 0x0C, 0xA3, 0x41, 0x42, 0xCB, 0x76, 
+        0xF9, 0x1F, 0x01, 0x3D, 0xA8, 0x09, 0xE9, 0xC1, 
+        0xB7, 0xAE, 0x64, 0xC5, 0x41, 0x30, 0xFB, 0xC2, 
+        0x1D, 0x80, 0xE9, 0xC2, 0xCB, 0x06, 0xC5, 0xC8, 
+        0xD7, 0xCC, 0xE8, 0x94, 0x6A, 0x9A, 0xC9, 0x9B,
+        0x1C, 0x28, 0x15, 0xC3, 0x61, 0x2A, 0x29, 0xA8, 
+        0x2D, 0x73, 0xA1, 0xF9, 0x93, 0x74, 0xFE, 0x30, 
+        0xE5, 0x49, 0x51, 0x66, 0x2A, 0x6E, 0xDA, 0x29, 
+        0xC6, 0xFC, 0x41, 0x13, 0x35, 0xD5, 0xDC, 0x74, 
+        0x26, 0xB0, 0xF6, 0x05, 0x02, 0x03, 0x01, 0x00, 
+        0x01, 0x02, 0x82, 0x01, 0x00, 0x3B, 0x12, 0x45, 
+        0x5D, 0x53, 0xC1, 0x81, 0x65, 0x16, 0xC5, 0x18, 
+        0x49, 0x3F, 0x63, 0x98, 0xAA, 0xFA, 0x72, 0xB1, 
+        0x7D, 0xFA, 0x89, 0x4D, 0xB8, 0x88, 0xA7, 0xD4, 
+        0x8C, 0x0A, 0x47, 0xF6, 0x25, 0x79, 0xA4, 0xE6, 
+        0x44, 0xF8, 0x6D, 0xA7, 0x11, 0xFE, 0xC8, 0x50, 
+        0xCD, 0xD9, 0xDB, 0xBD, 0x17, 0xF6, 0x9A, 0x44, 
+        0x3D, 0x2E, 0xC1, 0xDD, 0x60, 0xD3, 0xC6, 0x18, 
+        0xFA, 0x74, 0xCD, 0xE5, 0xFD, 0xAF, 0xAB, 0xD6, 
+        0xBA, 0xA2, 0x6E, 0xB0, 0xA3, 0xAD, 0xB4, 0xDE, 
+        0xF6, 0x48, 0x0F, 0xB1, 0x21, 0x8C, 0xD3, 0xB0,
+        0x83, 0xE2, 0x52, 0xE8, 0x85, 0xB6, 0xF0, 0x72, 
+        0x9F, 0x98, 0xB2, 0x14, 0x4D, 0x2B, 0x72, 0x29, 
+        0x3E, 0x1B, 0x11, 0xD7, 0x33, 0x93, 0xBC, 0x41, 
+        0xF7, 0x5B, 0x15, 0xEE, 0x3D, 0x75, 0x69, 0xB4, 
+        0x99, 0x5E, 0xD1, 0xA1, 0x44, 0x25, 0xDA, 0x43, 
+        0x19, 0xB7, 0xB2, 0x6B, 0x0E, 0x8F, 0xEF, 0x17, 
+        0xC3, 0x75, 0x42, 0xAE, 0x5C, 0x6D, 0x58, 0x49, 
+        0xF8, 0x72, 0x09, 0x56, 0x7F, 0x39, 0x25, 0xA4, 
+        0x7B, 0x01, 0x6D, 0x56, 0x48, 0x59, 0x71, 0x7B, 
+        0xC5, 0x7F, 0xCB, 0x45, 0x22, 0xD0, 0xAA, 0x49, 
+        0xCE, 0x81, 0x6E, 0x5B, 0xE7, 0xB3, 0x08, 0x81, 
+        0x93, 0x23, 0x6E, 0xC9, 0xEF, 0xFF, 0x14, 0x08, 
+        0x58, 0x04, 0x5B, 0x73, 0xC5, 0xD7, 0x9B, 0xAF, 
+        0x38, 0xF7, 0xC6, 0x7F, 0x04, 0xC5, 0xDC, 0xF0, 
+        0xE3, 0x80, 0x6A, 0xD9, 0x82, 0xD1, 0x25, 0x90, 
+        0x58, 0xC3, 0x47, 0x3E, 0x84, 0x71, 0x79, 0xA8, 
+        0x78, 0xF2, 0xC6, 0xB3, 0xBD, 0x96, 0x8F, 0xB9,
+        0x9E, 0xA4, 0x6E, 0x91, 0x85, 0x89, 0x2F, 0x36,
+        0x76, 0xE7, 0x89, 0x65, 0xC2, 0xAE, 0xD4, 0x87,
+        0x7B, 0xA3, 0x91, 0x7D, 0xF0, 0x7C, 0x5E, 0x92, 
+        0x74, 0x74, 0xF1, 0x9E, 0x76, 0x4B, 0xA6, 0x1D, 
+        0xC3, 0x8D, 0x63, 0xBF, 0x29, 0x02, 0x81, 0x81, 
+        0x00, 0xD5, 0xC6, 0x9C, 0x8C, 0x3C, 0xDC, 0x24, 
+        0x64, 0x74, 0x4A, 0x79, 0x37, 0x13, 0xDA, 0xFB, 
+        0x9F, 0x1D, 0xBC, 0x79, 0x9F, 0xF9, 0x64, 0x23, 
+        0xFE, 0xCD, 0x3C, 0xBA, 0x79, 0x42, 0x86, 0xBC, 
+        0xE9, 0x20, 0xF4, 0xB5, 0xC1, 0x83, 0xF9, 0x9E, 
+        0xE9, 0x02, 0x8D, 0xB6, 0x21, 0x2C, 0x62, 0x77, 
+        0xC4, 0xC8, 0x29, 0x7F, 0xCF, 0xBC, 0xE7, 0xF7,
+        0xC2, 0x4C, 0xA4, 0xC5, 0x1F, 0xC7, 0x18, 0x2F, 
+        0xB8, 0xF4, 0x01, 0x9F, 0xB1, 0xD5, 0x65, 0x96, 
+        0x74, 0xC5, 0xCB, 0xE6, 0xD5, 0xFA, 0x99, 0x20, 
+        0x51, 0x34, 0x17, 0x60, 0xCD, 0x00, 0x73, 0x57, 
+        0x29, 0xA0, 0x70, 0xA9, 0xE5, 0x4D, 0x34, 0x2B, 
+        0xEB, 0xA8, 0xEF, 0x47, 0xEE, 0x82, 0xD3, 0xA0, 
+        0x1B, 0x04, 0xCE, 0xC4, 0xA0, 0x0D, 0x4D, 0xDB,
+        0x41, 0xE3, 0x51, 0x16, 0xFC, 0x22, 0x1E, 0x85, 
+        0x4B, 0x43, 0xA6, 0x96, 0xC0, 0xE6, 0x41, 0x9B, 
+        0x1B, 0x02, 0x81, 0x81, 0x00, 0xCD, 0x5E, 0xA7, 
+        0x70, 0x27, 0x89, 0x06, 0x4B, 0x67, 0x35, 0x40, 
+        0xCB, 0xFF, 0x09, 0x35, 0x6A, 0xD8, 0x0B, 0xC3, 
+        0xD5, 0x92, 0x81, 0x2E, 0xBA, 0x47, 0x61, 0x0B,
+        0x9F, 0xAC, 0x6A, 0xEC, 0xEF, 0xE2, 0x2A, 0xCA, 
+        0xE4, 0x38, 0x45, 0x9C, 0xDA, 0x74, 0xE5, 0x96, 
+        0x53, 0xD8, 0x8C, 0x04, 0x18, 0x9D, 0x34, 0x39, 
+        0x9B, 0xF5, 0xB1, 0x4B, 0x92, 0x0E, 0x34, 0xEF, 
+        0x38, 0xA7, 0xD0, 0x9F, 0xE6, 0x95, 0x93, 0x39, 
+        0x6E, 0x8F, 0xE7, 0x35, 0xE6, 0xF0, 0xA6, 0xAE, 
+        0x49, 0x90, 0x40, 0x10, 0x41, 0xD8, 0xA4, 0x06, 
+        0xB6, 0xFD, 0x86, 0xA1, 0x16, 0x1E, 0x45, 0xF9,
+        0x5A, 0x3E, 0xAA, 0x5C, 0x10, 0x12, 0xE6, 0x66,
+        0x2E, 0x44, 0xF1, 0x5F, 0x33, 0x5A, 0xC9, 0x71, 
+        0xE1, 0x76, 0x6B, 0x2B, 0xB9, 0xC9, 0x85, 0x10, 
+        0x99, 0x74, 0x14, 0x1B, 0x44, 0xD3, 0x7E, 0x1E, 
+        0x31, 0x98, 0x20, 0xA5, 0x5F, 0x02, 0x81, 0x81, 
+        0x00, 0xB2, 0x87, 0x12, 0x37, 0xBF, 0x9F, 0xAD, 
+        0x38, 0xC3, 0x31, 0x6A, 0xB7, 0x87, 0x7A, 0x6A, 
+        0x86, 0x80, 0x63, 0xE5, 0x42, 0xA7, 0x18, 0x6D, 
+        0x43, 0x1E, 0x8D, 0x27, 0xC1, 0x9A, 0xC0, 0x41, 
+        0x45, 0x84, 0x03, 0x39, 0x42, 0xE9, 0xFF, 0x6E, 
+        0x29, 0x73, 0xBB, 0x7B, 0x2D, 0x8B, 0x0E, 0x94, 
+        0xAD, 0x1E, 0xE8, 0x21, 0x58, 0x10, 0x8F, 0xBC,
+        0x86, 0x64, 0x51, 0x7A, 0x5A, 0x46, 0x7F, 0xB9, 
+        0x63, 0x01, 0x4B, 0xD5, 0xDC, 0xC2, 0xB4, 0xFB, 
+        0x08, 0x7C, 0x23, 0x03, 0x9D, 0x11, 0x92, 0x0D, 
+        0xBE, 0x22, 0xFD, 0x9F, 0x16, 0xB4, 0xD8, 0x9E, 
+        0x23, 0x22, 0x5C, 0xD4, 0x55, 0xAD, 0xBA, 0xF3, 
+        0x2E, 0xF4, 0x3F, 0x18, 0x58, 0x64, 0xA3, 0x6D,
+        0x63, 0x03, 0x09, 0xD6, 0x85, 0x3F, 0x77, 0x14,
+        0xB3, 0x9A, 0xAE, 0x1E, 0xBE, 0xE3, 0x93, 0x8F, 
+        0x87, 0xC2, 0x70, 0x7E, 0x17, 0x8C, 0x73, 0x9F, 
+        0x9F, 0x02, 0x81, 0x81, 0x00, 0x96, 0x90, 0xBE,
+        0xD1, 0x4B, 0x2A, 0xFA, 0xA2, 0x6D, 0x98, 0x6D, 
+        0x59, 0x22, 0x31, 0xEE, 0x27, 0xD7, 0x1D, 0x49, 
+        0x06, 0x5B, 0xD2, 0xBA, 0x1F, 0x78, 0x15, 0x7E, 
+        0x20, 0x22, 0x98, 0x81, 0xFD, 0x9D, 0x23, 0x22, 
+        0x7D, 0x0F, 0x84, 0x79, 0xEA, 0xEF, 0xA9, 0x22, 
+        0xFD, 0x75, 0xD5, 0xB1, 0x6B, 0x1A, 0x56, 0x1F,
+        0xA6, 0x68, 0x0B, 0x04, 0x0C, 0xA0, 0xBD, 0xCE, 
+        0x65, 0x0B, 0x23, 0xB9, 0x17, 0xA4, 0xB1, 0xBB, 
+        0x79, 0x83, 0xA7, 0x4F, 0xAD, 0x70, 0xE1, 0xC3, 
+        0x05, 0xCB, 0xEC, 0x2B, 0xFF, 0x1A, 0x85, 0xA7,
+        0x26, 0xA1, 0xD9, 0x02, 0x60, 0xE4, 0xF1, 0x08, 
+        0x4F, 0x51, 0x82, 0x34, 0xDC, 0xD3, 0xFE, 0x77, 
+        0x0B, 0x95, 0x20, 0x21, 0x5B, 0xD5, 0x43, 0xBB, 
+        0x6A, 0x41, 0x17, 0x71, 0x87, 0x54, 0x67, 0x6A, 
+        0x34, 0x17, 0x16, 0x66, 0xA7, 0x9F, 0x26, 0xE7, 
+        0x9C, 0x14, 0x9C, 0x5A, 0xA1, 0x02, 0x81, 0x81, 
+        0x00, 0xA0, 0xC9, 0x85, 0xA0, 0xA0, 0xA7, 0x91, 
+        0xA6, 0x59, 0xF9, 0x97, 0x31, 0x13, 0x4C, 0x44, 
+        0xF3, 0x7B, 0x2E, 0x52, 0x0A, 0x2C, 0xEA, 0x35, 
+        0x80, 0x0A, 0xD2, 0x72, 0x41, 0xED, 0x36, 0x0D, 
+        0xFD, 0xE6, 0xE8, 0xCA, 0x61, 0x4F, 0x12, 0x04, 
+        0x7F, 0xD0, 0x8B, 0x76, 0xAC, 0x4D, 0x13, 0xC0, 
+        0x56, 0xA0, 0x69, 0x9E, 0x2F, 0x98, 0xA1, 0xCA, 
+        0xC9, 0x10, 0x11, 0x29, 0x4D, 0x71, 0x20, 0x8F, 
+        0x4A, 0xBA, 0xB3, 0x3B, 0xA8, 0x7A, 0xA0, 0x51, 
+        0x7F, 0x41, 0x5B, 0xAC, 0xA8, 0x8D, 0x6B, 0xAC, 
+        0x00, 0x60, 0x88, 0xFA, 0x60, 0x1D, 0x34, 0x94, 
+        0x17, 0xE1, 0xF0, 0xC9, 0xB2, 0x3A, 0xFF, 0xA4, 
+        0xD4, 0x96, 0x61, 0x8D, 0xBC, 0x02, 0x49, 0x86, 
+        0xED, 0x69, 0x0B, 0xBB, 0x7B, 0x02, 0x57, 0x68, 
+        0xFF, 0x9D, 0xF8, 0xAC, 0x15, 0x41, 0x6F, 0x48, 
+        0x9F, 0x81, 0x29, 0xC3, 0x23, 0x41, 0xA8, 0xB4, 
+        0x4F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    uint8 value[1193] = {
+        0x30, 0x82, 0x04, 0xA5, 0x02, 0x01, 0x00, 0x02, 
+        0x82, 0x01, 0x01, 0x00, 0xAB, 0x7F, 0x16, 0x1C, 
+        0x00, 0x42, 0x49, 0x6C, 0xCD, 0x6C, 0x6D, 0x4D, 
+        0xAD, 0xB9, 0x19, 0x97, 0x34, 0x35, 0x35, 0x77, 
+        0x76, 0x00, 0x3A, 0xCF, 0x54, 0xB7, 0xAF, 0x1E, 
+        0x44, 0x0A, 0xFB, 0x80, 0xB6, 0x4A, 0x87, 0x55, 
+        0xF8, 0x00, 0x2C, 0xFE, 0xBA, 0x6B, 0x18, 0x45, 
+        0x40, 0xA2, 0xD6, 0x60, 0x86, 0xD7, 0x46, 0x48, 
+        0x34, 0x6D, 0x75, 0xB8, 0xD7, 0x18, 0x12, 0xB2, 
+        0x05, 0x38, 0x7C, 0x0F, 0x65, 0x83, 0xBC, 0x4D, 
+        0x7D, 0xC7, 0xEC, 0x11, 0x4F, 0x3B, 0x17, 0x6B, 
+        0x79, 0x57, 0xC4, 0x22, 0xE7, 0xD0, 0x3F, 0xC6,
+        0x26, 0x7F, 0xA2, 0xA6, 0xF8, 0x9B, 0x9B, 0xEE, 
+        0x9E, 0x60, 0xA1, 0xD7, 0xC2, 0xD8, 0x33, 0xE5, 
+        0xA5, 0xF4, 0xBB, 0x0B, 0x14, 0x34, 0xF4, 0xE7, 
+        0x95, 0xA4, 0x11, 0x00, 0xF8, 0xAA, 0x21, 0x49, 
+        0x00, 0xDF, 0x8B, 0x65, 0x08, 0x9F, 0x98, 0x13, 
+        0x5B, 0x1C, 0x67, 0xB7, 0x01, 0x67, 0x5A, 0xBD, 
+        0xBC, 0x7D, 0x57, 0x21, 0xAA, 0xC9, 0xD1, 0x4A, 
+        0x7F, 0x08, 0x1F, 0xCE, 0xC8, 0x0B, 0x64, 0xE8, 
+        0xA0, 0xEC, 0xC8, 0x29, 0x53, 0x53, 0xC7, 0x95, 
+        0x32, 0x8A, 0xBF, 0x70, 0xE1, 0xB4, 0x2E, 0x7B, 
+        0xB8, 0xB7, 0xF4, 0xE8, 0xAC, 0x8C, 0x81, 0x0C, 
+        0xDB, 0x66, 0xE3, 0xD2, 0x11, 0x26, 0xEB, 0xA8, 
+        0xDA, 0x7D, 0x0C, 0xA3, 0x41, 0x42, 0xCB, 0x76, 
+        0xF9, 0x1F, 0x01, 0x3D, 0xA8, 0x09, 0xE9, 0xC1, 
+        0xB7, 0xAE, 0x64, 0xC5, 0x41, 0x30, 0xFB, 0xC2, 
+        0x1D, 0x80, 0xE9, 0xC2, 0xCB, 0x06, 0xC5, 0xC8, 
+        0xD7, 0xCC, 0xE8, 0x94, 0x6A, 0x9A, 0xC9, 0x9B,
+        0x1C, 0x28, 0x15, 0xC3, 0x61, 0x2A, 0x29, 0xA8, 
+        0x2D, 0x73, 0xA1, 0xF9, 0x93, 0x74, 0xFE, 0x30, 
+        0xE5, 0x49, 0x51, 0x66, 0x2A, 0x6E, 0xDA, 0x29, 
+        0xC6, 0xFC, 0x41, 0x13, 0x35, 0xD5, 0xDC, 0x74, 
+        0x26, 0xB0, 0xF6, 0x05, 0x02, 0x03, 0x01, 0x00, 
+        0x01, 0x02, 0x82, 0x01, 0x00, 0x3B, 0x12, 0x45, 
+        0x5D, 0x53, 0xC1, 0x81, 0x65, 0x16, 0xC5, 0x18, 
+        0x49, 0x3F, 0x63, 0x98, 0xAA, 0xFA, 0x72, 0xB1, 
+        0x7D, 0xFA, 0x89, 0x4D, 0xB8, 0x88, 0xA7, 0xD4, 
+        0x8C, 0x0A, 0x47, 0xF6, 0x25, 0x79, 0xA4, 0xE6, 
+        0x44, 0xF8, 0x6D, 0xA7, 0x11, 0xFE, 0xC8, 0x50, 
+        0xCD, 0xD9, 0xDB, 0xBD, 0x17, 0xF6, 0x9A, 0x44, 
+        0x3D, 0x2E, 0xC1, 0xDD, 0x60, 0xD3, 0xC6, 0x18, 
+        0xFA, 0x74, 0xCD, 0xE5, 0xFD, 0xAF, 0xAB, 0xD6, 
+        0xBA, 0xA2, 0x6E, 0xB0, 0xA3, 0xAD, 0xB4, 0xDE, 
+        0xF6, 0x48, 0x0F, 0xB1, 0x21, 0x8C, 0xD3, 0xB0,
+        0x83, 0xE2, 0x52, 0xE8, 0x85, 0xB6, 0xF0, 0x72, 
+        0x9F, 0x98, 0xB2, 0x14, 0x4D, 0x2B, 0x72, 0x29, 
+        0x3E, 0x1B, 0x11, 0xD7, 0x33, 0x93, 0xBC, 0x41, 
+        0xF7, 0x5B, 0x15, 0xEE, 0x3D, 0x75, 0x69, 0xB4, 
+        0x99, 0x5E, 0xD1, 0xA1, 0x44, 0x25, 0xDA, 0x43, 
+        0x19, 0xB7, 0xB2, 0x6B, 0x0E, 0x8F, 0xEF, 0x17, 
+        0xC3, 0x75, 0x42, 0xAE, 0x5C, 0x6D, 0x58, 0x49, 
+        0xF8, 0x72, 0x09, 0x56, 0x7F, 0x39, 0x25, 0xA4, 
+        0x7B, 0x01, 0x6D, 0x56, 0x48, 0x59, 0x71, 0x7B, 
+        0xC5, 0x7F, 0xCB, 0x45, 0x22, 0xD0, 0xAA, 0x49, 
+        0xCE, 0x81, 0x6E, 0x5B, 0xE7, 0xB3, 0x08, 0x81, 
+        0x93, 0x23, 0x6E, 0xC9, 0xEF, 0xFF, 0x14, 0x08, 
+        0x58, 0x04, 0x5B, 0x73, 0xC5, 0xD7, 0x9B, 0xAF, 
+        0x38, 0xF7, 0xC6, 0x7F, 0x04, 0xC5, 0xDC, 0xF0, 
+        0xE3, 0x80, 0x6A, 0xD9, 0x82, 0xD1, 0x25, 0x90, 
+        0x58, 0xC3, 0x47, 0x3E, 0x84, 0x71, 0x79, 0xA8, 
+        0x78, 0xF2, 0xC6, 0xB3, 0xBD, 0x96, 0x8F, 0xB9,
+        0x9E, 0xA4, 0x6E, 0x91, 0x85, 0x89, 0x2F, 0x36,
+        0x76, 0xE7, 0x89, 0x65, 0xC2, 0xAE, 0xD4, 0x87,
+        0x7B, 0xA3, 0x91, 0x7D, 0xF0, 0x7C, 0x5E, 0x92, 
+        0x74, 0x74, 0xF1, 0x9E, 0x76, 0x4B, 0xA6, 0x1D, 
+        0xC3, 0x8D, 0x63, 0xBF, 0x29, 0x02, 0x81, 0x81, 
+        0x00, 0xD5, 0xC6, 0x9C, 0x8C, 0x3C, 0xDC, 0x24, 
+        0x64, 0x74, 0x4A, 0x79, 0x37, 0x13, 0xDA, 0xFB, 
+        0x9F, 0x1D, 0xBC, 0x79, 0x9F, 0xF9, 0x64, 0x23, 
+        0xFE, 0xCD, 0x3C, 0xBA, 0x79, 0x42, 0x86, 0xBC, 
+        0xE9, 0x20, 0xF4, 0xB5, 0xC1, 0x83, 0xF9, 0x9E, 
+        0xE9, 0x02, 0x8D, 0xB6, 0x21, 0x2C, 0x62, 0x77, 
+        0xC4, 0xC8, 0x29, 0x7F, 0xCF, 0xBC, 0xE7, 0xF7,
+        0xC2, 0x4C, 0xA4, 0xC5, 0x1F, 0xC7, 0x18, 0x2F, 
+        0xB8, 0xF4, 0x01, 0x9F, 0xB1, 0xD5, 0x65, 0x96, 
+        0x74, 0xC5, 0xCB, 0xE6, 0xD5, 0xFA, 0x99, 0x20, 
+        0x51, 0x34, 0x17, 0x60, 0xCD, 0x00, 0x73, 0x57, 
+        0x29, 0xA0, 0x70, 0xA9, 0xE5, 0x4D, 0x34, 0x2B, 
+        0xEB, 0xA8, 0xEF, 0x47, 0xEE, 0x82, 0xD3, 0xA0, 
+        0x1B, 0x04, 0xCE, 0xC4, 0xA0, 0x0D, 0x4D, 0xDB,
+        0x41, 0xE3, 0x51, 0x16, 0xFC, 0x22, 0x1E, 0x85, 
+        0x4B, 0x43, 0xA6, 0x96, 0xC0, 0xE6, 0x41, 0x9B, 
+        0x1B, 0x02, 0x81, 0x81, 0x00, 0xCD, 0x5E, 0xA7, 
+        0x70, 0x27, 0x89, 0x06, 0x4B, 0x67, 0x35, 0x40, 
+        0xCB, 0xFF, 0x09, 0x35, 0x6A, 0xD8, 0x0B, 0xC3, 
+        0xD5, 0x92, 0x81, 0x2E, 0xBA, 0x47, 0x61, 0x0B,
+        0x9F, 0xAC, 0x6A, 0xEC, 0xEF, 0xE2, 0x2A, 0xCA, 
+        0xE4, 0x38, 0x45, 0x9C, 0xDA, 0x74, 0xE5, 0x96, 
+        0x53, 0xD8, 0x8C, 0x04, 0x18, 0x9D, 0x34, 0x39, 
+        0x9B, 0xF5, 0xB1, 0x4B, 0x92, 0x0E, 0x34, 0xEF, 
+        0x38, 0xA7, 0xD0, 0x9F, 0xE6, 0x95, 0x93, 0x39, 
+        0x6E, 0x8F, 0xE7, 0x35, 0xE6, 0xF0, 0xA6, 0xAE, 
+        0x49, 0x90, 0x40, 0x10, 0x41, 0xD8, 0xA4, 0x06, 
+        0xB6, 0xFD, 0x86, 0xA1, 0x16, 0x1E, 0x45, 0xF9,
+        0x5A, 0x3E, 0xAA, 0x5C, 0x10, 0x12, 0xE6, 0x66,
+        0x2E, 0x44, 0xF1, 0x5F, 0x33, 0x5A, 0xC9, 0x71, 
+        0xE1, 0x76, 0x6B, 0x2B, 0xB9, 0xC9, 0x85, 0x10, 
+        0x99, 0x74, 0x14, 0x1B, 0x44, 0xD3, 0x7E, 0x1E, 
+        0x31, 0x98, 0x20, 0xA5, 0x5F, 0x02, 0x81, 0x81, 
+        0x00, 0xB2, 0x87, 0x12, 0x37, 0xBF, 0x9F, 0xAD, 
+        0x38, 0xC3, 0x31, 0x6A, 0xB7, 0x87, 0x7A, 0x6A, 
+        0x86, 0x80, 0x63, 0xE5, 0x42, 0xA7, 0x18, 0x6D, 
+        0x43, 0x1E, 0x8D, 0x27, 0xC1, 0x9A, 0xC0, 0x41, 
+        0x45, 0x84, 0x03, 0x39, 0x42, 0xE9, 0xFF, 0x6E, 
+        0x29, 0x73, 0xBB, 0x7B, 0x2D, 0x8B, 0x0E, 0x94, 
+        0xAD, 0x1E, 0xE8, 0x21, 0x58, 0x10, 0x8F, 0xBC,
+        0x86, 0x64, 0x51, 0x7A, 0x5A, 0x46, 0x7F, 0xB9, 
+        0x63, 0x01, 0x4B, 0xD5, 0xDC, 0xC2, 0xB4, 0xFB, 
+        0x08, 0x7C, 0x23, 0x03, 0x9D, 0x11, 0x92, 0x0D, 
+        0xBE, 0x22, 0xFD, 0x9F, 0x16, 0xB4, 0xD8, 0x9E, 
+        0x23, 0x22, 0x5C, 0xD4, 0x55, 0xAD, 0xBA, 0xF3, 
+        0x2E, 0xF4, 0x3F, 0x18, 0x58, 0x64, 0xA3, 0x6D,
+        0x63, 0x03, 0x09, 0xD6, 0x85, 0x3F, 0x77, 0x14,
+        0xB3, 0x9A, 0xAE, 0x1E, 0xBE, 0xE3, 0x93, 0x8F, 
+        0x87, 0xC2, 0x70, 0x7E, 0x17, 0x8C, 0x73, 0x9F, 
+        0x9F, 0x02, 0x81, 0x81, 0x00, 0x96, 0x90, 0xBE,
+        0xD1, 0x4B, 0x2A, 0xFA, 0xA2, 0x6D, 0x98, 0x6D, 
+        0x59, 0x22, 0x31, 0xEE, 0x27, 0xD7, 0x1D, 0x49, 
+        0x06, 0x5B, 0xD2, 0xBA, 0x1F, 0x78, 0x15, 0x7E, 
+        0x20, 0x22, 0x98, 0x81, 0xFD, 0x9D, 0x23, 0x22, 
+        0x7D, 0x0F, 0x84, 0x79, 0xEA, 0xEF, 0xA9, 0x22, 
+        0xFD, 0x75, 0xD5, 0xB1, 0x6B, 0x1A, 0x56, 0x1F,
+        0xA6, 0x68, 0x0B, 0x04, 0x0C, 0xA0, 0xBD, 0xCE, 
+        0x65, 0x0B, 0x23, 0xB9, 0x17, 0xA4, 0xB1, 0xBB, 
+        0x79, 0x83, 0xA7, 0x4F, 0xAD, 0x70, 0xE1, 0xC3, 
+        0x05, 0xCB, 0xEC, 0x2B, 0xFF, 0x1A, 0x85, 0xA7,
+        0x26, 0xA1, 0xD9, 0x02, 0x60, 0xE4, 0xF1, 0x08, 
+        0x4F, 0x51, 0x82, 0x34, 0xDC, 0xD3, 0xFE, 0x77, 
+        0x0B, 0x95, 0x20, 0x21, 0x5B, 0xD5, 0x43, 0xBB, 
+        0x6A, 0x41, 0x17, 0x71, 0x87, 0x54, 0x67, 0x6A, 
+        0x34, 0x17, 0x16, 0x66, 0xA7, 0x9F, 0x26, 0xE7, 
+        0x9C, 0x14, 0x9C, 0x5A, 0xA1, 0x02, 0x81, 0x81, 
+        0x00, 0xA0, 0xC9, 0x85, 0xA0, 0xA0, 0xA7, 0x91, 
+        0xA6, 0x59, 0xF9, 0x97, 0x31, 0x13, 0x4C, 0x44, 
+        0xF3, 0x7B, 0x2E, 0x52, 0x0A, 0x2C, 0xEA, 0x35, 
+        0x80, 0x0A, 0xD2, 0x72, 0x41, 0xED, 0x36, 0x0D, 
+        0xFD, 0xE6, 0xE8, 0xCA, 0x61, 0x4F, 0x12, 0x04, 
+        0x7F, 0xD0, 0x8B, 0x76, 0xAC, 0x4D, 0x13, 0xC0, 
+        0x56, 0xA0, 0x69, 0x9E, 0x2F, 0x98, 0xA1, 0xCA, 
+        0xC9, 0x10, 0x11, 0x29, 0x4D, 0x71, 0x20, 0x8F, 
+        0x4A, 0xBA, 0xB3, 0x3B, 0xA8, 0x7A, 0xA0, 0x51, 
+        0x7F, 0x41, 0x5B, 0xAC, 0xA8, 0x8D, 0x6B, 0xAC, 
+        0x00, 0x60, 0x88, 0xFA, 0x60, 0x1D, 0x34, 0x94, 
+        0x17, 0xE1, 0xF0, 0xC9, 0xB2, 0x3A, 0xFF, 0xA4, 
+        0xD4, 0x96, 0x61, 0x8D, 0xBC, 0x02, 0x49, 0x86, 
+        0xED, 0x69, 0x0B, 0xBB, 0x7B, 0x02, 0x57, 0x68, 
+        0xFF, 0x9D, 0xF8, 0xAC, 0x15, 0x41, 0x6F, 0x48, 
+        0x9F, 0x81, 0x29, 0xC3, 0x23, 0x41, 0xA8, 0xB4, 
+        0x4F
+    };
+    struct byte_string key = {0};
+    key.value = value;
+    key.size = ARRAY_LENGTH(value);
+    
+    struct key_value kv = {0};
+    kv.key_material = &key;
+    
+    struct key_block kb = {0};
+    kb.key_format_type = KMIP_KEYFORMAT_PKCS1;
+    kb.key_value = &kv;
+    kb.key_value_type = KMIP_TYPE_STRUCTURE;
+    kb.cryptographic_algorithm = KMIP_CRYPTOALG_RSA;
+    kb.cryptographic_length = 2048;
+    
+    struct private_key expected = {0};
+    expected.key_block = &kb;
+    
+    struct private_key observed = {0};
+    
+    int result = kmip_decode_private_key(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_private_key(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_private_key(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_key_wrapping_specification(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[136] = {
+        0x42, 0x00, 0x47, 0x01, 0x00, 0x00, 0x00, 0x80, 
+        0x42, 0x00, 0x9E, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x66, 0x34, 0x62, 0x32, 0x62, 0x34, 0x63, 0x33, 
+        0x2D, 0x34, 0x63, 0x31, 0x39, 0x2D, 0x34, 0x65, 
+        0x63, 0x66, 0x2D, 0x38, 0x32, 0x37, 0x61, 0x2D, 
+        0x30, 0x31, 0x31, 0x63, 0x61, 0x36, 0x30, 0x35, 
+        0x37, 0x64, 0x33, 0x65, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, 
+        0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, 
+        0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B
+    };
+    
+    uint8 observed[136] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "f4b2b4c3-4c19-4ecf-827a-011ca6057d3e";
+    uuid.size = 36;
+    
+    struct cryptographic_parameters cp = {0};
+    cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP;
+    
+    struct encryption_key_information eki = {0};
+    eki.unique_identifier = &uuid;
+    eki.cryptographic_parameters = &cp;
+    
+    struct text_string attribute_name = {0};
+    attribute_name.value = "Cryptographic Usage Mask";
+    attribute_name.size = 24;
+    
+    struct key_wrapping_specification kws = {0};
+    kws.wrapping_method = KMIP_WRAP_ENCRYPT;
+    kws.encryption_key_info = &eki;
+    kws.attribute_names = &attribute_name;
+    kws.attribute_name_count = 1;
+    
+    int result = kmip_encode_key_wrapping_specification(&ctx, &kws);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_key_wrapping_specification(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[136] = {
+        0x42, 0x00, 0x47, 0x01, 0x00, 0x00, 0x00, 0x80, 
+        0x42, 0x00, 0x9E, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x66, 0x34, 0x62, 0x32, 0x62, 0x34, 0x63, 0x33, 
+        0x2D, 0x34, 0x63, 0x31, 0x39, 0x2D, 0x34, 0x65, 
+        0x63, 0x66, 0x2D, 0x38, 0x32, 0x37, 0x61, 0x2D, 
+        0x30, 0x31, 0x31, 0x63, 0x61, 0x36, 0x30, 0x35, 
+        0x37, 0x64, 0x33, 0x65, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, 
+        0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, 
+        0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "f4b2b4c3-4c19-4ecf-827a-011ca6057d3e";
+    uuid.size = 36;
+    
+    struct cryptographic_parameters cp = {0};
+    kmip_init_cryptographic_parameters(&cp);
+    
+    cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP;
+    
+    struct encryption_key_information eki = {0};
+    eki.unique_identifier = &uuid;
+    eki.cryptographic_parameters = &cp;
+    
+    struct text_string attribute_name = {0};
+    attribute_name.value = "Cryptographic Usage Mask";
+    attribute_name.size = 24;
+    
+    struct key_wrapping_specification expected = {0};
+    expected.wrapping_method = KMIP_WRAP_ENCRYPT;
+    expected.encryption_key_info = &eki;
+    expected.attribute_names = &attribute_name;
+    expected.attribute_name_count = 1;
+    
+    struct key_wrapping_specification observed = {0};
+    
+    int result = kmip_decode_key_wrapping_specification(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_key_wrapping_specification(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_key_wrapping_specification(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_create_request_payload(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following set of values:
+    *  Request Payload
+    *      Object Type - Symmetric Key
+    *      Template Attribute
+    *          Attribute
+    *              Attribute Name - Cryptographic Algorithm
+    *              Attribute Value - AES
+    *          Attribute
+    *              Attribute Name - Cryptographic Length
+    *              Attribute Value - 128
+    *          Attribute
+    *              Attribute Name - Cryptographic Usage Mask
+    *              Attribute Value - Encrypt | Decrypt
+    */
+    uint8 expected[200] = {
+        0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0xC0, 
+        0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x91, 0x01, 0x00, 0x00, 0x00, 0xA8, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x17, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C, 
+        0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, 
+        0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x14, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x4C, 0x65, 
+        0x6E, 0x67, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, 
+        0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B, 
+        0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[200] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct attribute a[3] = {0};
+    for(int i = 0; i < 3; i++)
+    {
+        kmip_init_attribute(&a[i]);
+    }
+    
+    enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES;
+    a[0].type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM;
+    a[0].value = &algorithm;
+    
+    int32 length = 128;
+    a[1].type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH;
+    a[1].value = &length;
+    
+    int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT;
+    a[2].type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK;
+    a[2].value = &mask;
+    
+    struct template_attribute ta = {0};
+    ta.attributes = a;
+    ta.attribute_count = ARRAY_LENGTH(a);
+    
+    struct create_request_payload crp = {0};
+    crp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY;
+    crp.template_attribute = &ta;
+    
+    int result = kmip_encode_create_request_payload(&ctx, &crp);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_create_request_payload_kmip_2_0(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following set of values:
+    *  Request Payload
+    *      Object Type - Symmetric Key
+    *      Attributes
+    *          Cryptographic Algorithm - AES
+    *          Cryptographic Length - 128
+    *          Cryptographic Usage Mask - Encrypt | Decrypt
+    *      Protection Storage Masks
+    *          Protection Storage Mask - Software | On System
+    *          Protection Storage Mask - Off System | Off Premises
+    */
+    uint8 expected[120] = {
+        0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x70, 
+        0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x01, 0x25, 0x01, 0x00, 0x00, 0x00, 0x30,
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x2C, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x01, 0x5F, 0x01, 0x00, 0x00, 0x00, 0x20,
+        0x42, 0x01, 0x5E, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x01, 0x5E, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[120] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0);
+    
+    Attribute a[3] = {0};
+    for(int i = 0; i < 3; i++)
+    {
+        kmip_init_attribute(&a[i]);
+    }
+    
+    enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES;
+    a[0].type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM;
+    a[0].value = &algorithm;
+    
+    int32 length = 128;
+    a[1].type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH;
+    a[1].value = &length;
+    
+    int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT;
+    a[2].type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK;
+    a[2].value = &mask;
+    
+    Attributes attributes = {0};
+    LinkedList list = {0};
+    LinkedListItem item_1, item_2, item_3 = {0};
+    item_1.data = &a[0];
+    item_2.data = &a[1];
+    item_3.data = &a[2];
+    kmip_linked_list_enqueue(&list, &item_1);
+    kmip_linked_list_enqueue(&list, &item_2);
+    kmip_linked_list_enqueue(&list, &item_3);
+    attributes.attribute_list = &list;
+
+    ProtectionStorageMasks psm = {0};
+    LinkedList masks = {0};
+    LinkedListItem mask_1, mask_2 = {0};
+    int32 m1 = KMIP_PROTECT_SOFTWARE | KMIP_PROTECT_ON_SYSTEM;
+    int32 m2 = KMIP_PROTECT_OFF_SYSTEM | KMIP_PROTECT_OFF_PREMISES;
+    mask_1.data = &m1;
+    mask_2.data = &m2;
+    kmip_linked_list_enqueue(&masks, &mask_1);
+    kmip_linked_list_enqueue(&masks, &mask_2);
+    psm.masks = &masks;
+
+    CreateRequestPayload payload = {0};
+    payload.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY;
+    payload.attributes = &attributes;
+    payload.protection_storage_masks = &psm;
+    
+    int result = kmip_encode_create_request_payload(&ctx, &payload);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_create_request_payload(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[200] = {
+        0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0xC0, 
+        0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x91, 0x01, 0x00, 0x00, 0x00, 0xA8, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x17, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C, 
+        0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, 
+        0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x14, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x4C, 0x65, 
+        0x6E, 0x67, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, 
+        0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B, 
+        0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct attribute a[3] = {0};
+    for(int i = 0; i < 3; i++)
+    {
+        kmip_init_attribute(&a[i]);
+    }
+    
+    enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES;
+    a[0].type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM;
+    a[0].value = &algorithm;
+    
+    int32 length = 128;
+    a[1].type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH;
+    a[1].value = &length;
+    
+    int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT;
+    a[2].type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK;
+    a[2].value = &mask;
+    
+    struct template_attribute ta = {0};
+    ta.attributes = a;
+    ta.attribute_count = ARRAY_LENGTH(a);
+    
+    struct create_request_payload expected = {0};
+    expected.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY;
+    expected.template_attribute = &ta;
+    
+    struct create_request_payload observed = {0};
+    
+    int result = kmip_decode_create_request_payload(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_create_request_payload(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_create_request_payload(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_create_request_payload_kmip_2_0(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following set of values:
+    *  Request Payload
+    *      Object Type - Symmetric Key
+    *      Attributes
+    *          Cryptographic Algorithm - AES
+    *          Cryptographic Length - 128
+    *          Cryptographic Usage Mask - Encrypt | Decrypt
+    *      Protection Storage Masks
+    *          Protection Storage Mask - Software | On System
+    *          Protection Storage Mask - Off System | Off Premises
+    */
+    uint8 encoding[120] = {
+        0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x70, 
+        0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x01, 0x25, 0x01, 0x00, 0x00, 0x00, 0x30,
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x2C, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x01, 0x5F, 0x01, 0x00, 0x00, 0x00, 0x20,
+        0x42, 0x01, 0x5E, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x01, 0x5E, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0);
+    
+    Attribute a[3] = {0};
+    for(int i = 0; i < 3; i++)
+    {
+        kmip_init_attribute(&a[i]);
+    }
+    
+    enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES;
+    a[0].type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM;
+    a[0].value = &algorithm;
+    
+    int32 length = 128;
+    a[1].type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH;
+    a[1].value = &length;
+    
+    int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT;
+    a[2].type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK;
+    a[2].value = &mask;
+    
+    Attributes attributes = {0};
+    LinkedList list = {0};
+    LinkedListItem item_1, item_2, item_3 = {0};
+    item_1.data = &a[0];
+    item_2.data = &a[1];
+    item_3.data = &a[2];
+    kmip_linked_list_enqueue(&list, &item_1);
+    kmip_linked_list_enqueue(&list, &item_2);
+    kmip_linked_list_enqueue(&list, &item_3);
+    attributes.attribute_list = &list;
+
+    ProtectionStorageMasks psm = {0};
+    LinkedList masks = {0};
+    LinkedListItem mask_1, mask_2 = {0};
+    int32 m1 = KMIP_PROTECT_SOFTWARE | KMIP_PROTECT_ON_SYSTEM;
+    int32 m2 = KMIP_PROTECT_OFF_SYSTEM | KMIP_PROTECT_OFF_PREMISES;
+    mask_1.data = &m1;
+    mask_2.data = &m2;
+    kmip_linked_list_enqueue(&masks, &mask_1);
+    kmip_linked_list_enqueue(&masks, &mask_2);
+    psm.masks = &masks;
+
+    CreateRequestPayload expected = {0};
+    expected.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY;
+    expected.attributes = &attributes;
+    expected.protection_storage_masks = &psm;
+    
+    CreateRequestPayload observed = {0};
+    
+    int result = kmip_decode_create_request_payload(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_create_request_payload(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_create_request_payload(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_create_response_payload(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[72] = {
+        0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x40, 
+        0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, 
+        0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, 
+        0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, 
+        0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, 
+        0x32, 0x39, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[72] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "fb4b5b9c-6188-4c63-8142-fe9c328129fc";
+    uuid.size = 36;
+    
+    struct create_response_payload crp = {0};
+    crp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY;
+    crp.unique_identifier = &uuid;
+    
+    int result = kmip_encode_create_response_payload(&ctx, &crp);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_create_response_payload(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[72] = {
+        0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x40, 
+        0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, 
+        0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, 
+        0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, 
+        0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, 
+        0x32, 0x39, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "fb4b5b9c-6188-4c63-8142-fe9c328129fc";
+    uuid.size = 36;
+    
+    struct create_response_payload expected = {0};
+    expected.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY;
+    expected.unique_identifier = &uuid;
+    
+    struct create_response_payload observed = {0};
+    
+    int result = kmip_decode_create_response_payload(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_create_response_payload(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_create_response_payload(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_create_response_payload_with_template_attribute(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[136] = {
+        0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x80, 
+        0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, 
+        0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, 
+        0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, 
+        0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, 
+        0x32, 0x39, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x91, 0x01, 0x00, 0x00, 0x00, 0x38, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x17, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C, 
+        0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, 
+        0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 
+    };
+    
+    uint8 observed[136] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "fb4b5b9c-6188-4c63-8142-fe9c328129fc";
+    uuid.size = 36;
+    
+    struct attribute a = {0};
+    kmip_init_attribute(&a);
+    
+    enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES;
+    a.type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM;
+    a.value = &algorithm;
+    
+    struct template_attribute ta = {0};
+    ta.attributes = &a;
+    ta.attribute_count = 1;
+    
+    struct create_response_payload crp = {0};
+    crp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY;
+    crp.unique_identifier = &uuid;
+    crp.template_attribute = &ta;
+    
+    int result = kmip_encode_create_response_payload(&ctx, &crp);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_create_response_payload_with_template_attribute(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[136] = {
+        0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x80, 
+        0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, 
+        0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, 
+        0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, 
+        0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, 
+        0x32, 0x39, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x91, 0x01, 0x00, 0x00, 0x00, 0x38, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x17, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C, 
+        0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, 
+        0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "fb4b5b9c-6188-4c63-8142-fe9c328129fc";
+    uuid.size = 36;
+    
+    struct attribute a = {0};
+    kmip_init_attribute(&a);
+    
+    enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES;
+    a.type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM;
+    a.value = &algorithm;
+    
+    struct template_attribute ta = {0};
+    ta.attributes = &a;
+    ta.attribute_count = 1;
+    
+    struct create_response_payload expected = {0};
+    expected.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY;
+    expected.unique_identifier = &uuid;
+    expected.template_attribute = &ta;
+    
+    struct create_response_payload observed = {0};
+    
+    int result = kmip_decode_create_response_payload(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_create_response_payload(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_create_response_payload(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_get_request_payload(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[56] = {
+        0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x34, 0x39, 0x61, 0x31, 0x63, 0x61, 0x38, 0x38, 
+        0x2D, 0x36, 0x62, 0x65, 0x61, 0x2D, 0x34, 0x66, 
+        0x62, 0x32, 0x2D, 0x62, 0x34, 0x35, 0x30, 0x2D, 
+        0x37, 0x65, 0x35, 0x38, 0x38, 0x30, 0x32, 0x63, 
+        0x33, 0x30, 0x33, 0x38, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[56] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038";
+    uuid.size = 36;
+    
+    struct get_request_payload grp = {0};
+    grp.unique_identifier = &uuid;
+    
+    int result = kmip_encode_get_request_payload(&ctx, &grp);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_get_request_payload(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[56] = {
+        0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x34, 0x39, 0x61, 0x31, 0x63, 0x61, 0x38, 0x38, 
+        0x2D, 0x36, 0x62, 0x65, 0x61, 0x2D, 0x34, 0x66, 
+        0x62, 0x32, 0x2D, 0x62, 0x34, 0x35, 0x30, 0x2D, 
+        0x37, 0x65, 0x35, 0x38, 0x38, 0x30, 0x32, 0x63, 
+        0x33, 0x30, 0x33, 0x38, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038";
+    uuid.size = 36;
+    
+    struct get_request_payload expected = {0};
+    expected.unique_identifier = &uuid;
+    
+    struct get_request_payload observed = {0};
+    
+    int result = kmip_decode_get_request_payload(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_get_request_payload(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_get_request_payload(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_get_request_payload_with_format_compression(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[88] = {
+        0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x50, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x37, 0x63, 0x66, 0x35, 0x32, 0x30, 0x39, 0x62, 
+        0x2D, 0x36, 0x66, 0x66, 0x36, 0x2D, 0x34, 0x34, 
+        0x32, 0x36, 0x2D, 0x38, 0x39, 0x39, 0x65, 0x2D, 
+        0x32, 0x32, 0x62, 0x30, 0x36, 0x37, 0x38, 0x35, 
+        0x39, 0x33, 0x37, 0x32, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x41, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[88] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "7cf5209b-6ff6-4426-899e-22b067859372";
+    uuid.size = 36;
+    
+    struct get_request_payload grp = {0};
+    grp.unique_identifier = &uuid;
+    grp.key_format_type = KMIP_KEYFORMAT_PKCS1;
+    grp.key_compression_type = KMIP_KEYCOMP_EC_PUB_UNCOMPRESSED;
+    
+    int result = kmip_encode_get_request_payload(&ctx, &grp);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_get_request_payload_with_wrapping_spec(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[160] = {
+        0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x98, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x62, 0x66, 0x66, 0x37, 0x33, 0x34, 0x37, 0x62, 
+        0x2D, 0x33, 0x61, 0x33, 0x39, 0x2D, 0x34, 0x63, 
+        0x63, 0x62, 0x2D, 0x38, 0x32, 0x33, 0x34, 0x2D, 
+        0x62, 0x61, 0x32, 0x35, 0x36, 0x30, 0x63, 0x61, 
+        0x31, 0x35, 0x39, 0x38, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x47, 0x01, 0x00, 0x00, 0x00, 0x60, 
+        0x42, 0x00, 0x9E, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35, 
+        0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, 
+        0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, 
+        0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, 
+        0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, 
+        0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[160] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct text_string wrapping_uuid = {0};
+    wrapping_uuid.value = "100182d5-72b8-47aa-8383-4d97d512e98a";
+    wrapping_uuid.size = 36;
+    struct text_string uuid = {0};
+    uuid.value = "bff7347b-3a39-4ccb-8234-ba2560ca1598";
+    uuid.size = 36;
+    
+    struct cryptographic_parameters cp = {0};
+    cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP;
+    
+    struct encryption_key_information eki = {0};
+    eki.unique_identifier = &wrapping_uuid;
+    eki.cryptographic_parameters = &cp;
+    
+    struct key_wrapping_specification kws = {0};
+    kws.wrapping_method = KMIP_WRAP_ENCRYPT;
+    kws.encryption_key_info = &eki;
+    
+    struct get_request_payload grp = {0};
+    grp.unique_identifier = &uuid;
+    grp.key_wrapping_spec = &kws;
+    
+    int result = kmip_encode_get_request_payload(&ctx, &grp);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_get_response_payload(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[176] = {
+        0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0xA8, 
+        0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x34, 0x39, 0x61, 0x31, 0x63, 0x61, 0x38, 0x38, 
+        0x2D, 0x36, 0x62, 0x65, 0x61, 0x2D, 0x34, 0x66, 
+        0x62, 0x32, 0x2D, 0x62, 0x34, 0x35, 0x30, 0x2D, 
+        0x37, 0x65, 0x35, 0x38, 0x38, 0x30, 0x32, 0x63, 
+        0x33, 0x30, 0x33, 0x38, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x60, 
+        0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x58, 
+        0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x18, 
+        0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, 
+        0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, 
+        0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8, 
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[176] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038";
+    uuid.size = 36;
+    
+    uint8 value[24] = {
+        0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, 
+        0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, 
+        0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8
+    };
+    struct byte_string v = {0};
+    v.value = value;
+    v.size = ARRAY_LENGTH(value);
+    
+    struct key_value kv = {0};
+    kv.key_material = &v;
+    
+    struct key_block kb = {0};
+    kb.key_format_type = KMIP_KEYFORMAT_RAW;
+    kb.key_value = &kv;
+    kb.cryptographic_algorithm = KMIP_CRYPTOALG_TRIPLE_DES;
+    kb.cryptographic_length = 168;
+    
+    struct symmetric_key key = {0};
+    key.key_block = &kb;
+    
+    struct get_response_payload grp = {0};
+    grp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY;
+    grp.unique_identifier = &uuid;
+    grp.object = &key;
+    
+    int result = kmip_encode_get_response_payload(&ctx, &grp);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_get_response_payload(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[176] = {
+        0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0xA8, 
+        0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x34, 0x39, 0x61, 0x31, 0x63, 0x61, 0x38, 0x38, 
+        0x2D, 0x36, 0x62, 0x65, 0x61, 0x2D, 0x34, 0x66, 
+        0x62, 0x32, 0x2D, 0x62, 0x34, 0x35, 0x30, 0x2D, 
+        0x37, 0x65, 0x35, 0x38, 0x38, 0x30, 0x32, 0x63, 
+        0x33, 0x30, 0x33, 0x38, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x60, 
+        0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x58, 
+        0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x18, 
+        0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, 
+        0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, 
+        0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8, 
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038";
+    uuid.size = 36;
+    
+    uint8 value[24] = {
+        0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, 
+        0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, 
+        0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8
+    };
+    struct byte_string v = {0};
+    v.value = value;
+    v.size = ARRAY_LENGTH(value);
+    
+    struct key_value kv = {0};
+    kv.key_material = &v;
+    
+    struct key_block kb = {0};
+    kb.key_format_type = KMIP_KEYFORMAT_RAW;
+    kb.key_value = &kv;
+    kb.key_value_type = KMIP_TYPE_STRUCTURE;
+    kb.cryptographic_algorithm = KMIP_CRYPTOALG_TRIPLE_DES;
+    kb.cryptographic_length = 168;
+    
+    struct symmetric_key key = {0};
+    key.key_block = &kb;
+    
+    struct get_response_payload expected = {0};
+    expected.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY;
+    expected.unique_identifier = &uuid;
+    expected.object = &key;
+    
+    struct get_response_payload observed = {0};
+    
+    int result = kmip_decode_get_response_payload(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_get_response_payload(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_get_response_payload(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_destroy_request_payload(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[56] = {
+        0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, 
+        0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, 
+        0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, 
+        0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, 
+        0x32, 0x39, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[56] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "fb4b5b9c-6188-4c63-8142-fe9c328129fc";
+    uuid.size = 36;
+    
+    struct destroy_request_payload drp = {0};
+    drp.unique_identifier = &uuid;
+    
+    int result = kmip_encode_destroy_request_payload(&ctx, &drp);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_destroy_request_payload(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[56] = {
+        0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, 
+        0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, 
+        0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, 
+        0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, 
+        0x32, 0x39, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "fb4b5b9c-6188-4c63-8142-fe9c328129fc";
+    uuid.size = 36;
+    
+    struct destroy_request_payload expected = {0};
+    expected.unique_identifier = &uuid;
+    
+    struct destroy_request_payload observed = {0};
+    
+    int result = kmip_decode_destroy_request_payload(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_destroy_request_payload(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_destroy_request_payload(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_destroy_response_payload(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[56] = {
+        0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x30,
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, 
+        0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, 
+        0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, 
+        0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, 
+        0x32, 0x39, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[56] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "fb4b5b9c-6188-4c63-8142-fe9c328129fc";
+    uuid.size = 36;
+    
+    struct destroy_response_payload drp = {0};
+    drp.unique_identifier = &uuid;
+    
+    int result = kmip_encode_destroy_response_payload(&ctx, &drp);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_destroy_response_payload(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[56] = {
+        0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x30,
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, 
+        0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, 
+        0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, 
+        0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, 
+        0x32, 0x39, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "fb4b5b9c-6188-4c63-8142-fe9c328129fc";
+    uuid.size = 36;
+    
+    struct destroy_response_payload expected = {0};
+    expected.unique_identifier = &uuid;
+    
+    struct destroy_response_payload observed = {0};
+    
+    int result = kmip_decode_destroy_response_payload(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_destroy_response_payload(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_destroy_response_payload(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_username_password_credential(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[48] = {
+        0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x28, 
+        0x42, 0x00, 0x99, 0x07, 0x00, 0x00, 0x00, 0x04, 
+        0x46, 0x72, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x09, 
+        0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 
+        0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[48] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct text_string username = {0};
+    username.value = "Fred";
+    username.size = 4;
+    struct text_string password = {0};
+    password.value = "password1";
+    password.size = 9;
+    
+    struct username_password_credential upc = {0};
+    upc.username = &username;
+    upc.password = &password;
+    
+    int result = kmip_encode_username_password_credential(&ctx, &upc);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_username_password_credential(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[48] = {
+        0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x28, 
+        0x42, 0x00, 0x99, 0x07, 0x00, 0x00, 0x00, 0x04, 
+        0x46, 0x72, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x09, 
+        0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 
+        0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct text_string username = {0};
+    username.value = "Fred";
+    username.size = 4;
+    struct text_string password = {0};
+    password.value = "password1";
+    password.size = 9;
+    
+    struct username_password_credential expected = {0};
+    expected.username = &username;
+    expected.password = &password;
+    
+    struct username_password_credential observed = {0};
+    
+    int result = kmip_decode_username_password_credential(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_username_password_credential(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_username_password_credential(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_credential_username_password_credential(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[64] = {
+        0x42, 0x00, 0x23, 0x01, 0x00, 0x00, 0x00, 0x38, 
+        0x42, 0x00, 0x24, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x99, 0x07, 0x00, 0x00, 0x00, 0x06, 
+        0x42, 0x61, 0x72, 0x6E, 0x65, 0x79, 0x00, 0x00, 
+        0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x07, 
+        0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x32, 0x00
+    };
+    
+    uint8 observed[64] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct text_string username = {0};
+    username.value = "Barney";
+    username.size = 6;
+    struct text_string password = {0};
+    password.value = "secret2";
+    password.size = 7;
+    
+    struct username_password_credential upc = {0};
+    upc.username = &username;
+    upc.password = &password;
+    
+    struct credential c = {0};
+    c.credential_type = KMIP_CRED_USERNAME_AND_PASSWORD;
+    c.credential_value = &upc;
+    
+    int result = kmip_encode_credential(&ctx, &c);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_credential_username_password_credential(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[64] = {
+        0x42, 0x00, 0x23, 0x01, 0x00, 0x00, 0x00, 0x38, 
+        0x42, 0x00, 0x24, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x99, 0x07, 0x00, 0x00, 0x00, 0x06, 
+        0x42, 0x61, 0x72, 0x6E, 0x65, 0x79, 0x00, 0x00, 
+        0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x07, 
+        0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x32, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct text_string username = {0};
+    username.value = "Barney";
+    username.size = 6;
+    struct text_string password = {0};
+    password.value = "secret2";
+    password.size = 7;
+    
+    struct username_password_credential upc = {0};
+    upc.username = &username;
+    upc.password = &password;
+    
+    struct credential expected = {0};
+    expected.credential_type = KMIP_CRED_USERNAME_AND_PASSWORD;
+    expected.credential_value = &upc;
+
+    struct credential observed = {0};
+    
+    int result = kmip_decode_credential(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_credential(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_credential(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_authentication_username_password_credential(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[80] = {
+        0x42, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x23, 0x01, 0x00, 0x00, 0x00, 0x40, 
+        0x42, 0x00, 0x24, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x28, 
+        0x42, 0x00, 0x99, 0x07, 0x00, 0x00, 0x00, 0x04, 
+        0x46, 0x72, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x09, 
+        0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 
+        0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[80] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct text_string username = {0};
+    username.value = "Fred";
+    username.size = 4;
+    struct text_string password = {0};
+    password.value = "password1";
+    password.size = 9;
+    
+    struct username_password_credential upc = {0};
+    upc.username = &username;
+    upc.password = &password;
+    
+    struct credential c = {0};
+    c.credential_type = KMIP_CRED_USERNAME_AND_PASSWORD;
+    c.credential_value = &upc;
+    
+    struct authentication a = {0};
+    a.credential = &c;
+    
+    int result = kmip_encode_authentication(&ctx, &a);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_authentication_username_password_credential(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[80] = {
+        0x42, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x23, 0x01, 0x00, 0x00, 0x00, 0x40, 
+        0x42, 0x00, 0x24, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x28, 
+        0x42, 0x00, 0x99, 0x07, 0x00, 0x00, 0x00, 0x04, 
+        0x46, 0x72, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x09, 
+        0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 
+        0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct text_string username = {0};
+    username.value = "Fred";
+    username.size = 4;
+    struct text_string password = {0};
+    password.value = "password1";
+    password.size = 9;
+    
+    struct username_password_credential upc = {0};
+    upc.username = &username;
+    upc.password = &password;
+    
+    struct credential c = {0};
+    c.credential_type = KMIP_CRED_USERNAME_AND_PASSWORD;
+    c.credential_value = &upc;
+    
+    struct authentication expected = {0};
+    expected.credential = &c;
+    
+    struct authentication observed = {0};
+    
+    int result = kmip_decode_authentication(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_authentication(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_authentication(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_request_header(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[168] = {
+        0x42, 0x00, 0x77, 0x01, 0x00, 0x00, 0x00, 0xA0, 
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x40, 
+        0x42, 0x00, 0x23, 0x01, 0x00, 0x00, 0x00, 0x38, 
+        0x42, 0x00, 0x24, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x99, 0x07, 0x00, 0x00, 0x00, 0x06, 
+        0x42, 0x61, 0x72, 0x6E, 0x65, 0x79, 0x00, 0x00, 
+        0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x07, 
+        0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x32, 0x00, 
+        0x42, 0x00, 0x0E, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x10, 0x06, 0x00, 0x00, 0x00, 0x08, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
+        0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[168] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct protocol_version pv = {0};
+    pv.major = 1;
+    pv.minor = 0;
+    
+    struct text_string username = {0};
+    username.value = "Barney";
+    username.size = 6;
+    struct text_string password = {0};
+    password.value = "secret2";
+    password.size = 7;
+    
+    struct username_password_credential upc = {0};
+    upc.username = &username;
+    upc.password = &password;
+    
+    struct credential c = {0};
+    c.credential_type = KMIP_CRED_USERNAME_AND_PASSWORD;
+    c.credential_value = &upc;
+    
+    struct authentication a = {0};
+    a.credential = &c;
+    
+    struct request_header rh = {0};
+    kmip_init_request_header(&rh);
+    
+    rh.protocol_version = &pv;
+    rh.authentication = &a;
+    rh.batch_error_continuation_option = KMIP_BATCH_CONTINUE;
+    rh.batch_order_option = KMIP_TRUE;
+    rh.batch_count = 2;
+    
+    int result = kmip_encode_request_header(&ctx, &rh);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_request_header(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[168] = {
+        0x42, 0x00, 0x77, 0x01, 0x00, 0x00, 0x00, 0xA0, 
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x40, 
+        0x42, 0x00, 0x23, 0x01, 0x00, 0x00, 0x00, 0x38, 
+        0x42, 0x00, 0x24, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x99, 0x07, 0x00, 0x00, 0x00, 0x06, 
+        0x42, 0x61, 0x72, 0x6E, 0x65, 0x79, 0x00, 0x00, 
+        0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x07, 
+        0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x32, 0x00, 
+        0x42, 0x00, 0x0E, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x10, 0x06, 0x00, 0x00, 0x00, 0x08, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
+        0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct protocol_version pv = {0};
+    pv.major = 1;
+    pv.minor = 0;
+    
+    struct text_string username = {0};
+    username.value = "Barney";
+    username.size = 6;
+    struct text_string password = {0};
+    password.value = "secret2";
+    password.size = 7;
+    
+    struct username_password_credential upc = {0};
+    upc.username = &username;
+    upc.password = &password;
+    
+    struct credential c = {0};
+    c.credential_type = KMIP_CRED_USERNAME_AND_PASSWORD;
+    c.credential_value = &upc;
+    
+    struct authentication a = {0};
+    a.credential = &c;
+    
+    struct request_header expected = {0};
+    kmip_init_request_header(&expected);
+    
+    expected.protocol_version = &pv;
+    expected.authentication = &a;
+    expected.batch_error_continuation_option = KMIP_BATCH_CONTINUE;
+    expected.batch_order_option = KMIP_TRUE;
+    expected.batch_count = 2;
+    
+    struct request_header observed = {0};
+    kmip_init_request_header(&observed);
+    
+    int result = kmip_decode_request_header(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_request_header(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_request_header(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_response_header(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[80] = {
+        0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, 
+        0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE5, 
+        0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[80] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct protocol_version pv = {0};
+    pv.major = 1;
+    pv.minor = 0;
+    
+    struct response_header rh = {0};
+    kmip_init_response_header(&rh);
+    
+    rh.protocol_version = &pv;
+    rh.time_stamp = 1335514341;
+    rh.batch_count = 1;
+    
+    int result = kmip_encode_response_header(&ctx, &rh);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_response_header(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[80] = {
+        0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, 
+        0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE5, 
+        0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct protocol_version pv = {0};
+    pv.major = 1;
+    pv.minor = 0;
+    
+    struct response_header expected = {0};
+    kmip_init_response_header(&expected);
+    
+    expected.protocol_version = &pv;
+    expected.time_stamp = 1335514341;
+    expected.batch_count = 1;
+    
+    struct response_header observed = {0};
+    kmip_init_response_header(&observed);
+    
+    int result = kmip_decode_response_header(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_response_header(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_response_header(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_request_batch_item_get_payload(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[80] = {
+        0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x34, 0x39, 0x61, 0x31, 0x63, 0x61, 0x38, 0x38, 
+        0x2D, 0x36, 0x62, 0x65, 0x61, 0x2D, 0x34, 0x66, 
+        0x62, 0x32, 0x2D, 0x62, 0x34, 0x35, 0x30, 0x2D, 
+        0x37, 0x65, 0x35, 0x38, 0x38, 0x30, 0x32, 0x63, 
+        0x33, 0x30, 0x33, 0x38, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[80] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038";
+    uuid.size = 36;
+    
+    struct get_request_payload grp = {0};
+    grp.unique_identifier = &uuid;
+    
+    struct request_batch_item rbi = {0};
+    kmip_init_request_batch_item(&rbi);
+    rbi.operation = KMIP_OP_GET;
+    rbi.request_payload = &grp;
+    
+    int result = kmip_encode_request_batch_item(&ctx, &rbi);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_request_batch_item_get_payload_kmip_2_0(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following set of values:
+    *  Batch Item
+    *      Operation - Get
+    *      Ephemeral - False
+    *      Request Payload
+    *          Unique Identifier - 49a1ca88-6bea-4fb2-b450-7e58802c3038
+    */
+    uint8 expected[96] = {
+        0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x58,
+        0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x01, 0x54, 0x06, 0x00, 0x00, 0x00, 0x08,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x30,
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24,
+        0x34, 0x39, 0x61, 0x31, 0x63, 0x61, 0x38, 0x38,
+        0x2D, 0x36, 0x62, 0x65, 0x61, 0x2D, 0x34, 0x66,
+        0x62, 0x32, 0x2D, 0x62, 0x34, 0x35, 0x30, 0x2D,
+        0x37, 0x65, 0x35, 0x38, 0x38, 0x30, 0x32, 0x63,
+        0x33, 0x30, 0x33, 0x38, 0x00, 0x00, 0x00, 0x00
+    };
+
+    uint8 observed[96] = {0};
+    KMIP ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0);
+
+    TextString uuid = {0};
+    uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038";
+    uuid.size = 36;
+
+    GetRequestPayload grp = {0};
+    grp.unique_identifier = &uuid;
+
+    RequestBatchItem rbi = {0};
+    kmip_init_request_batch_item(&rbi);
+    rbi.operation = KMIP_OP_GET;
+    rbi.ephemeral = KMIP_FALSE;
+    rbi.request_payload = &grp;
+
+    int result = kmip_encode_request_batch_item(&ctx, &rbi);
+    result = report_encoding_test_result(tracker, &ctx, expected, observed, result, __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_request_batch_item_get_payload(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[80] = {
+        0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x34, 0x39, 0x61, 0x31, 0x63, 0x61, 0x38, 0x38, 
+        0x2D, 0x36, 0x62, 0x65, 0x61, 0x2D, 0x34, 0x66, 
+        0x62, 0x32, 0x2D, 0x62, 0x34, 0x35, 0x30, 0x2D, 
+        0x37, 0x65, 0x35, 0x38, 0x38, 0x30, 0x32, 0x63, 
+        0x33, 0x30, 0x33, 0x38, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038";
+    uuid.size = 36;
+    
+    struct get_request_payload grp = {0};
+    grp.unique_identifier = &uuid;
+    
+    struct request_batch_item expected = {0};
+    kmip_init_request_batch_item(&expected);
+    expected.operation = KMIP_OP_GET;
+    expected.request_payload = &grp;
+    
+    struct request_batch_item observed = {0};
+    kmip_init_request_batch_item(&observed);
+    
+    int result = kmip_decode_request_batch_item(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_request_batch_item(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_request_batch_item(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_request_batch_item_get_payload_kmip_2_0(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following set of values:
+    *  Batch Item
+    *      Operation - Get
+    *      Ephemeral - False
+    *      Request Payload
+    *          Unique Identifier - 49a1ca88-6bea-4fb2-b450-7e58802c3038
+    */
+    uint8 encoding[96] = {
+        0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x58,
+        0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x01, 0x54, 0x06, 0x00, 0x00, 0x00, 0x08,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x30,
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24,
+        0x34, 0x39, 0x61, 0x31, 0x63, 0x61, 0x38, 0x38,
+        0x2D, 0x36, 0x62, 0x65, 0x61, 0x2D, 0x34, 0x66,
+        0x62, 0x32, 0x2D, 0x62, 0x34, 0x35, 0x30, 0x2D,
+        0x37, 0x65, 0x35, 0x38, 0x38, 0x30, 0x32, 0x63,
+        0x33, 0x30, 0x33, 0x38, 0x00, 0x00, 0x00, 0x00
+    };
+
+    KMIP ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0);
+
+    TextString uuid = {0};
+    uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038";
+    uuid.size = 36;
+
+    GetRequestPayload grp = {0};
+    grp.unique_identifier = &uuid;
+
+    RequestBatchItem expected = {0};
+    kmip_init_request_batch_item(&expected);
+    expected.operation = KMIP_OP_GET;
+    expected.ephemeral = KMIP_FALSE;
+    expected.request_payload = &grp;
+
+    RequestBatchItem observed = {0};
+    kmip_init_request_batch_item(&observed);
+
+    int result = kmip_decode_request_batch_item(&ctx, &observed);
+    int comparison = kmip_compare_request_batch_item(&expected, &observed);
+    if(!comparison)
+    {
+        kmip_print_request_batch_item(1, &expected);
+        kmip_print_request_batch_item(1, &observed);
+    }
+    result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__);
+
+    kmip_free_request_batch_item(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_response_batch_item_get_payload(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[216] = {
+        0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0xD0, 
+        0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x7F, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0xA8, 
+        0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x34, 0x39, 0x61, 0x31, 0x63, 0x61, 0x38, 0x38, 
+        0x2D, 0x36, 0x62, 0x65, 0x61, 0x2D, 0x34, 0x66, 
+        0x62, 0x32, 0x2D, 0x62, 0x34, 0x35, 0x30, 0x2D, 
+        0x37, 0x65, 0x35, 0x38, 0x38, 0x30, 0x32, 0x63, 
+        0x33, 0x30, 0x33, 0x38, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x60, 
+        0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x58, 
+        0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x18, 
+        0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, 
+        0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, 
+        0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8, 
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[216] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038";
+    uuid.size = 36;
+    
+    uint8 value[24] = {
+        0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, 
+        0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, 
+        0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8
+    };
+    
+    struct byte_string v = {0};
+    v.value = value;
+    v.size = ARRAY_LENGTH(value);
+    
+    struct key_value kv = {0};
+    kv.key_material = &v;
+    
+    struct key_block kb = {0};
+    kb.key_format_type = KMIP_KEYFORMAT_RAW;
+    kb.key_value = &kv;
+    kb.cryptographic_algorithm = KMIP_CRYPTOALG_TRIPLE_DES;
+    kb.cryptographic_length = 168;
+    
+    struct symmetric_key key = {0};
+    key.key_block = &kb;
+    
+    struct get_response_payload grp = {0};
+    grp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY;
+    grp.unique_identifier = &uuid;
+    grp.object = &key;
+    
+    struct response_batch_item rbi = {0};
+    rbi.operation = KMIP_OP_GET;
+    rbi.result_status = KMIP_STATUS_SUCCESS;
+    rbi.response_payload = &grp;
+    
+    int result = kmip_encode_response_batch_item(&ctx, &rbi);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_response_batch_item_get_payload(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[216] = {
+        0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0xD0, 
+        0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x7F, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0xA8, 
+        0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x34, 0x39, 0x61, 0x31, 0x63, 0x61, 0x38, 0x38, 
+        0x2D, 0x36, 0x62, 0x65, 0x61, 0x2D, 0x34, 0x66, 
+        0x62, 0x32, 0x2D, 0x62, 0x34, 0x35, 0x30, 0x2D, 
+        0x37, 0x65, 0x35, 0x38, 0x38, 0x30, 0x32, 0x63, 
+        0x33, 0x30, 0x33, 0x38, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x60, 
+        0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x58, 
+        0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x18, 
+        0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, 
+        0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, 
+        0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8, 
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct text_string uuid = {0};
+    uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038";
+    uuid.size = 36;
+    
+    uint8 value[24] = {
+        0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, 
+        0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, 
+        0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8
+    };
+    
+    struct byte_string v = {0};
+    v.value = value;
+    v.size = ARRAY_LENGTH(value);
+    
+    struct key_value kv = {0};
+    kv.key_material = &v;
+    
+    struct key_block kb = {0};
+    kb.key_format_type = KMIP_KEYFORMAT_RAW;
+    kb.key_value = &kv;
+    kb.key_value_type = KMIP_TYPE_STRUCTURE;
+    kb.cryptographic_algorithm = KMIP_CRYPTOALG_TRIPLE_DES;
+    kb.cryptographic_length = 168;
+    
+    struct symmetric_key key = {0};
+    key.key_block = &kb;
+    
+    struct get_response_payload grp = {0};
+    grp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY;
+    grp.unique_identifier = &uuid;
+    grp.object = &key;
+    
+    struct response_batch_item expected = {0};
+    expected.operation = KMIP_OP_GET;
+    expected.result_status = KMIP_STATUS_SUCCESS;
+    expected.response_payload = &grp;
+    
+    struct response_batch_item observed = {0};
+    
+    int result = kmip_decode_response_batch_item(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_response_batch_item(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_response_batch_item(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_request_message_get(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[152] = {
+        0x42, 0x00, 0x78, 0x01, 0x00, 0x00, 0x00, 0x90, 
+        0x42, 0x00, 0x77, 0x01, 0x00, 0x00, 0x00, 0x38, 
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x34, 0x39, 0x61, 0x31, 0x63, 0x61, 0x38, 0x38, 
+        0x2D, 0x36, 0x62, 0x65, 0x61, 0x2D, 0x34, 0x66, 
+        0x62, 0x32, 0x2D, 0x62, 0x34, 0x35, 0x30, 0x2D, 
+        0x37, 0x65, 0x35, 0x38, 0x38, 0x30, 0x32, 0x63, 
+        0x33, 0x30, 0x33, 0x38, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[152] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct protocol_version pv = {0};
+    pv.major = 1;
+    pv.minor = 0;
+    
+    struct request_header rh = {0};
+    kmip_init_request_header(&rh);
+    
+    rh.protocol_version = &pv;
+    rh.batch_count = 1;
+    
+    struct text_string uuid = {0};
+    uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038";
+    uuid.size = 36;
+    
+    struct get_request_payload grp = {0};
+    grp.unique_identifier = &uuid;
+    
+    struct request_batch_item rbi = {0};
+    kmip_init_request_batch_item(&rbi);
+    rbi.operation = KMIP_OP_GET;
+    rbi.request_payload = &grp;
+    
+    struct request_message rm = {0};
+    rm.request_header = &rh;
+    rm.batch_items = &rbi;
+    rm.batch_count = 1;
+    
+    int result = kmip_encode_request_message(&ctx, &rm);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_request_message_get(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[152] = {
+        0x42, 0x00, 0x78, 0x01, 0x00, 0x00, 0x00, 0x90, 
+        0x42, 0x00, 0x77, 0x01, 0x00, 0x00, 0x00, 0x38, 
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x34, 0x39, 0x61, 0x31, 0x63, 0x61, 0x38, 0x38, 
+        0x2D, 0x36, 0x62, 0x65, 0x61, 0x2D, 0x34, 0x66, 
+        0x62, 0x32, 0x2D, 0x62, 0x34, 0x35, 0x30, 0x2D, 
+        0x37, 0x65, 0x35, 0x38, 0x38, 0x30, 0x32, 0x63, 
+        0x33, 0x30, 0x33, 0x38, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct protocol_version pv = {0};
+    pv.major = 1;
+    pv.minor = 0;
+    
+    struct request_header rh = {0};
+    kmip_init_request_header(&rh);
+    
+    rh.protocol_version = &pv;
+    rh.batch_count = 1;
+    
+    struct text_string uuid = {0};
+    uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038";
+    uuid.size = 36;
+    
+    struct get_request_payload grp = {0};
+    grp.unique_identifier = &uuid;
+    
+    struct request_batch_item rbi = {0};
+    kmip_init_request_batch_item(&rbi);
+    rbi.operation = KMIP_OP_GET;
+    rbi.request_payload = &grp;
+    
+    struct request_message expected = {0};
+    expected.request_header = &rh;
+    expected.batch_items = &rbi;
+    expected.batch_count = 1;
+    
+    struct request_message observed = {0};
+    
+    int result = kmip_decode_request_message(&ctx, &observed);
+    int comparison = kmip_compare_request_message(&expected, &observed);
+    if(!comparison)
+    {
+        kmip_print_request_message(&expected);
+        kmip_print_request_message(&observed);
+    }
+    result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__);
+
+    kmip_free_request_message(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_response_message_get(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[304] = {
+        0x42, 0x00, 0x7B, 0x01, 0x00, 0x00, 0x01, 0x28, 
+        0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, 
+        0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE7, 
+        0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0xD0, 
+        0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x7F, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0xA8, 
+        0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x34, 0x39, 0x61, 0x31, 0x63, 0x61, 0x38, 0x38, 
+        0x2D, 0x36, 0x62, 0x65, 0x61, 0x2D, 0x34, 0x66, 
+        0x62, 0x32, 0x2D, 0x62, 0x34, 0x35, 0x30, 0x2D, 
+        0x37, 0x65, 0x35, 0x38, 0x38, 0x30, 0x32, 0x63, 
+        0x33, 0x30, 0x33, 0x38, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x60, 
+        0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x58, 
+        0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x18, 
+        0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, 
+        0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, 
+        0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8, 
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[304] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct protocol_version pv = {0};
+    pv.major = 1;
+    pv.minor = 0;
+    
+    struct response_header rh = {0};
+    kmip_init_response_header(&rh);
+    
+    rh.protocol_version = &pv;
+    rh.time_stamp = 1335514343;
+    rh.batch_count = 1;
+    
+    struct text_string uuid = {0};
+    uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038";
+    uuid.size = 36;
+    
+    uint8 value[24] = {
+        0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, 
+        0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, 
+        0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8
+    };
+    
+    struct byte_string v = {0};
+    v.value = value;
+    v.size = ARRAY_LENGTH(value);
+    
+    struct key_value kv = {0};
+    kv.key_material = &v;
+    
+    struct key_block kb = {0};
+    kb.key_format_type = KMIP_KEYFORMAT_RAW;
+    kb.key_value = &kv;
+    kb.cryptographic_algorithm = KMIP_CRYPTOALG_TRIPLE_DES;
+    kb.cryptographic_length = 168;
+    
+    struct symmetric_key key = {0};
+    key.key_block = &kb;
+    
+    struct get_response_payload grp = {0};
+    grp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY;
+    grp.unique_identifier = &uuid;
+    grp.object = &key;
+    
+    struct response_batch_item rbi = {0};
+    rbi.operation = KMIP_OP_GET;
+    rbi.result_status = KMIP_STATUS_SUCCESS;
+    rbi.response_payload = &grp;
+    
+    struct response_message rm = {0};
+    rm.response_header = &rh;
+    rm.batch_items = &rbi;
+    rm.batch_count = 1;
+    
+    int result = kmip_encode_response_message(&ctx, &rm);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_response_message_get(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[304] = {
+        0x42, 0x00, 0x7B, 0x01, 0x00, 0x00, 0x01, 0x28, 
+        0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, 
+        0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE7, 
+        0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0xD0, 
+        0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x7F, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0xA8, 
+        0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x34, 0x39, 0x61, 0x31, 0x63, 0x61, 0x38, 0x38, 
+        0x2D, 0x36, 0x62, 0x65, 0x61, 0x2D, 0x34, 0x66, 
+        0x62, 0x32, 0x2D, 0x62, 0x34, 0x35, 0x30, 0x2D, 
+        0x37, 0x65, 0x35, 0x38, 0x38, 0x30, 0x32, 0x63, 
+        0x33, 0x30, 0x33, 0x38, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x60, 
+        0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x58, 
+        0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x18, 
+        0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, 
+        0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, 
+        0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8, 
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct protocol_version pv = {0};
+    pv.major = 1;
+    pv.minor = 0;
+    
+    struct response_header rh = {0};
+    kmip_init_response_header(&rh);
+    
+    rh.protocol_version = &pv;
+    rh.time_stamp = 1335514343;
+    rh.batch_count = 1;
+    
+    struct text_string uuid = {0};
+    uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038";
+    uuid.size = 36;
+    
+    uint8 value[24] = {
+        0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, 
+        0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, 
+        0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8
+    };
+    
+    struct byte_string v = {0};
+    v.value = value;
+    v.size = ARRAY_LENGTH(value);
+    
+    struct key_value kv = {0};
+    kv.key_material = &v;
+    
+    struct key_block kb = {0};
+    kb.key_format_type = KMIP_KEYFORMAT_RAW;
+    kb.key_value = &kv;
+    kb.key_value_type = KMIP_TYPE_STRUCTURE;
+    kb.cryptographic_algorithm = KMIP_CRYPTOALG_TRIPLE_DES;
+    kb.cryptographic_length = 168;
+    
+    struct symmetric_key key = {0};
+    key.key_block = &kb;
+    
+    struct get_response_payload grp = {0};
+    grp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY;
+    grp.unique_identifier = &uuid;
+    grp.object = &key;
+    
+    struct response_batch_item rbi = {0};
+    rbi.operation = KMIP_OP_GET;
+    rbi.result_status = KMIP_STATUS_SUCCESS;
+    rbi.response_payload = &grp;
+    
+    struct response_message expected = {0};
+    expected.response_header = &rh;
+    expected.batch_items = &rbi;
+    expected.batch_count = 1;
+    
+    struct response_message observed = {0};
+    
+    int result = kmip_decode_response_message(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_response_message(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_response_message(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_attributes(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following set of values:
+    *  Attributes
+    *      Cryptographic Algorithm - AES
+    *      Cryptographic Length - 128
+    */
+    uint8 expected[40] = {
+        0x42, 0x01, 0x25, 0x01, 0x00, 0x00, 0x00, 0x20,
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[40] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0);
+
+    LinkedList attribute_list = {0};
+
+    LinkedListItem item_1 = {0};
+    Attribute attr_1 = {0};
+    kmip_init_attribute(&attr_1);
+    enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES;
+    attr_1.type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM;
+    attr_1.value = &algorithm;
+    item_1.data = &attr_1;
+
+    LinkedListItem item_2 = {0};
+    Attribute attr_2 = {0};
+    kmip_init_attribute(&attr_2);
+    int32 length = 128;
+    attr_2.type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH;
+    attr_2.value = &length;
+    item_2.data = &attr_2;
+
+    kmip_linked_list_enqueue(&attribute_list, &item_1);
+    kmip_linked_list_enqueue(&attribute_list, &item_2);
+
+    Attributes attributes = {0};
+    attributes.attribute_list = &attribute_list;
+
+    int result = kmip_encode_attributes(&ctx, &attributes);
+    result = report_encoding_test_result(tracker, &ctx, expected, observed, result, __func__);
+
+    kmip_destroy(&ctx);
+
+    return(result);
+}
+
+int
+test_encode_attributes_with_invalid_kmip_version(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 observed[40] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_4);
+
+    Attributes attributes = {0};
+
+    int result = kmip_encode_attributes(&ctx, &attributes);
+    kmip_destroy(&ctx);
+
+    result = report_result(tracker, result, KMIP_INVALID_FOR_VERSION, __func__);
+    return(result);
+}
+
+int
+test_encode_attribute_v2_unique_identifier(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following value:
+    *  Unique Identifier - fb4b5b9c-6188-4c63-8142-fe9c328129fc
+    */
+    uint8 expected[48] = {
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24,
+        0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63,
+        0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63,
+        0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D,
+        0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31,
+        0x32, 0x39, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00
+    };
+
+    uint8 observed[48] = {0};
+    KMIP ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0);
+
+    Attribute attribute = {0};
+    kmip_init_attribute(&attribute);
+    TextString unique_identifier = {0};
+    unique_identifier.value = "fb4b5b9c-6188-4c63-8142-fe9c328129fc";
+    unique_identifier.size = 36;
+    attribute.type = KMIP_ATTR_UNIQUE_IDENTIFIER;
+    attribute.value = &unique_identifier;
+
+    int result = kmip_encode_attribute_v2(&ctx, &attribute);
+    result = report_encoding_test_result(tracker, &ctx, expected, observed, result, __func__);
+
+    kmip_destroy(&ctx);
+
+    return(result);
+}
+
+int
+test_encode_attribute_v2_name(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following value:
+    *  Name
+    *      Value - Template1
+    *      Type - Uninterpreted Text String
+    */
+    uint8 expected[48] = {
+        0x42, 0x00, 0x53, 0x01, 0x00, 0x00, 0x00, 0x28,
+        0x42, 0x00, 0x55, 0x07, 0x00, 0x00, 0x00, 0x09,
+        0x54, 0x65, 0x6D, 0x70, 0x6C, 0x61, 0x74, 0x65,
+        0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+
+    uint8 observed[48] = {0};
+    KMIP ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0);
+
+    Attribute attribute = {0};
+    kmip_init_attribute(&attribute);
+    TextString name_value = {0};
+    name_value.value = "Template1";
+    name_value.size = 9;
+    Name name = {0};
+    name.value = &name_value;
+    name.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING;
+
+    attribute.type = KMIP_ATTR_NAME;
+    attribute.value = &name;
+
+    int result = kmip_encode_attribute_v2(&ctx, &attribute);
+    result = report_encoding_test_result(tracker, &ctx, expected, observed, result, __func__);
+
+    kmip_destroy(&ctx);
+
+    return(result);
+}
+
+int
+test_encode_attribute_v2_object_type(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following value:
+    *  Object Type - Symmetric Key
+    */
+    uint8 expected[16] = {
+        0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00
+    };
+
+    uint8 observed[16] = {0};
+    KMIP ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0);
+
+    Attribute attribute = {0};
+    kmip_init_attribute(&attribute);
+    enum object_type object_type = KMIP_OBJTYPE_SYMMETRIC_KEY;
+    attribute.type = KMIP_ATTR_OBJECT_TYPE;
+    attribute.value = &object_type;
+
+    int result = kmip_encode_attribute_v2(&ctx, &attribute);
+    result = report_encoding_test_result(tracker, &ctx, expected, observed, result, __func__);
+
+    kmip_destroy(&ctx);
+
+    return(result);
+}
+
+int
+test_encode_attribute_v2_cryptographic_algorithm(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following value:
+    *  Cryptographic Algorithm - AES
+    */
+    uint8 expected[16] = {
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00
+    };
+
+    uint8 observed[16] = {0};
+    KMIP ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0);
+
+    Attribute attribute = {0};
+    kmip_init_attribute(&attribute);
+    enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES;
+    attribute.type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM;
+    attribute.value = &algorithm;
+
+    int result = kmip_encode_attribute_v2(&ctx, &attribute);
+    result = report_encoding_test_result(tracker, &ctx, expected, observed, result, __func__);
+
+    kmip_destroy(&ctx);
+
+    return(result);
+}
+
+int
+test_encode_attribute_v2_cryptographic_length(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following value:
+    *  Cryptographic Length - 128
+    */
+    uint8 expected[16] = {
+        0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
+    };
+
+    uint8 observed[16] = {0};
+    KMIP ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0);
+
+    Attribute attribute = {0};
+    kmip_init_attribute(&attribute);
+    int32 length = 128;
+    attribute.type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH;
+    attribute.value = &length;
+
+    int result = kmip_encode_attribute_v2(&ctx, &attribute);
+    result = report_encoding_test_result(tracker, &ctx, expected, observed, result, __func__);
+
+    kmip_destroy(&ctx);
+
+    return(result);
+}
+
+int
+test_encode_attribute_v2_cryptographic_usage_mask(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following value:
+    *  Cryptographic Usage Mask - Encrypt | Decrypt
+    */
+    uint8 expected[16] = {
+        0x42, 0x00, 0x2C, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00
+    };
+
+    uint8 observed[16] = {0};
+    KMIP ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0);
+
+    Attribute attribute = {0};
+    kmip_init_attribute(&attribute);
+    int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT;
+    attribute.type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK;
+    attribute.value = &mask;
+
+    int result = kmip_encode_attribute_v2(&ctx, &attribute);
+    result = report_encoding_test_result(tracker, &ctx, expected, observed, result, __func__);
+
+    kmip_destroy(&ctx);
+
+    return(result);
+}
+
+int
+test_encode_attribute_v2_state(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following value:
+    *  State - Active
+    */
+    uint8 expected[16] = {
+        0x42, 0x00, 0x8D, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00
+    };
+
+    uint8 observed[16] = {0};
+    KMIP ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0);
+
+    Attribute attribute = {0};
+    kmip_init_attribute(&attribute);
+    enum state state = KMIP_STATE_ACTIVE;
+    attribute.type = KMIP_ATTR_STATE;
+    attribute.value = &state;
+
+    int result = kmip_encode_attribute_v2(&ctx, &attribute);
+    result = report_encoding_test_result(tracker, &ctx, expected, observed, result, __func__);
+
+    kmip_destroy(&ctx);
+
+    return(result);
+}
+
+int
+test_encode_attribute_v2_unsupported_attribute(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[16] = {0};
+
+    KMIP ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0);
+
+    Attribute attribute = {0};
+    attribute.type = -1;
+    int result = kmip_encode_attribute_v2(&ctx, &attribute);
+    if(result != KMIP_ERROR_ATTR_UNSUPPORTED)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_destroy(&ctx);
+
+    TEST_PASSED(tracker, __func__);
+}
+
+int
+test_decode_attributes(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following set of values:
+    *  Attributes
+    *      Cryptographic Algorithm - AES
+    *      Cryptographic Length - 128
+    */
+    uint8 encoding[40] = {
+        0x42, 0x01, 0x25, 0x01, 0x00, 0x00, 0x00, 0x20,
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
+    };
+
+    KMIP ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0);
+
+    LinkedList attribute_list = {0};
+
+    LinkedListItem item_1 = {0};
+    Attribute attr_1 = {0};
+    kmip_init_attribute(&attr_1);
+    enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES;
+    attr_1.type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM;
+    attr_1.value = &algorithm;
+    item_1.data = &attr_1;
+
+    LinkedListItem item_2 = {0};
+    Attribute attr_2 = {0};
+    kmip_init_attribute(&attr_2);
+    int32 length = 128;
+    attr_2.type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH;
+    attr_2.value = &length;
+    item_2.data = &attr_2;
+
+    kmip_linked_list_enqueue(&attribute_list, &item_1);
+    kmip_linked_list_enqueue(&attribute_list, &item_2);
+
+    Attributes expected = {0};
+    expected.attribute_list = &attribute_list;
+
+    Attributes observed = {0};
+    int result = kmip_decode_attributes(&ctx, &observed);
+    int comparison = kmip_compare_attributes(&expected, &observed);
+    if(!comparison)
+    {
+        kmip_print_attributes(1, &expected);
+        kmip_print_attributes(1, &observed);
+    }
+    result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__);
+
+    kmip_free_attributes(&ctx, &observed);
+    kmip_destroy(&ctx);
+
+    return(result);
+}
+
+int
+test_decode_attributes_with_invalid_kmip_version(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[] = {0};
+
+    KMIP ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_4);
+
+    Attributes observed = {0};
+    int result = kmip_decode_attributes(&ctx, &observed);
+
+    kmip_free_attributes(&ctx, &observed);
+    kmip_destroy(&ctx);
+
+    result = report_result(tracker, result, KMIP_INVALID_FOR_VERSION, __func__);
+    return(result);
+}
+
+int
+test_decode_attribute_v2_unique_identifier(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following value:
+    *  Unique Identifier - fb4b5b9c-6188-4c63-8142-fe9c328129fc
+    */
+    uint8 encoding[48] = {
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24,
+        0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63,
+        0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63,
+        0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D,
+        0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31,
+        0x32, 0x39, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00
+    };
+
+    KMIP ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0);
+
+    Attribute expected = {0};
+    kmip_init_attribute(&expected);
+    TextString unique_identifier = {0};
+    unique_identifier.value = "fb4b5b9c-6188-4c63-8142-fe9c328129fc";
+    unique_identifier.size = 36;
+    expected.type = KMIP_ATTR_UNIQUE_IDENTIFIER;
+    expected.value = &unique_identifier;
+
+    Attribute observed = {0};
+    int result = kmip_decode_attribute_v2(&ctx, &observed);
+    int comparison = kmip_compare_attribute(&expected, &observed);
+    if(!comparison)
+    {
+        kmip_print_attribute(1, &expected);
+        kmip_print_attribute(1, &observed);
+    }
+    result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__);
+
+    kmip_free_attribute(&ctx, &observed);
+    kmip_destroy(&ctx);
+
+    return(result);
+}
+
+int
+test_decode_attribute_v2_name(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following value:
+    *  Name
+    *      Value - Template1
+    *      Type - Uninterpreted Text String
+    */
+    uint8 encoding[48] = {
+        0x42, 0x00, 0x53, 0x01, 0x00, 0x00, 0x00, 0x28,
+        0x42, 0x00, 0x55, 0x07, 0x00, 0x00, 0x00, 0x09,
+        0x54, 0x65, 0x6D, 0x70, 0x6C, 0x61, 0x74, 0x65,
+        0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+
+    KMIP ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0);
+
+    Attribute expected = {0};
+    kmip_init_attribute(&expected);
+    TextString name_value = {0};
+    name_value.value = "Template1";
+    name_value.size = 9;
+    Name name = {0};
+    name.value = &name_value;
+    name.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING;
+
+    expected.type = KMIP_ATTR_NAME;
+    expected.value = &name;
+
+    Attribute observed = {0};
+    int result = kmip_decode_attribute_v2(&ctx, &observed);
+    int comparison = kmip_compare_attribute(&expected, &observed);
+    if(!comparison)
+    {
+        kmip_print_attribute(1, &expected);
+        kmip_print_attribute(1, &observed);
+    }
+    result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__);
+
+    kmip_free_attribute(&ctx, &observed);
+    kmip_destroy(&ctx);
+
+    return(result);
+}
+
+int
+test_decode_attribute_v2_object_type(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following value:
+    *  Object Type - Symmetric Key
+    */
+    uint8 encoding[16] = {
+        0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00
+    };
+
+    KMIP ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0);
+
+    Attribute expected = {0};
+    kmip_init_attribute(&expected);
+    enum object_type object_type = KMIP_OBJTYPE_SYMMETRIC_KEY;
+    expected.type = KMIP_ATTR_OBJECT_TYPE;
+    expected.value = &object_type;
+
+    Attribute observed = {0};
+    int result = kmip_decode_attribute_v2(&ctx, &observed);
+    int comparison = kmip_compare_attribute(&expected, &observed);
+    if(!comparison)
+    {
+        kmip_print_attribute(1, &expected);
+        kmip_print_attribute(1, &observed);
+    }
+    result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__);
+
+    kmip_free_attribute(&ctx, &observed);
+    kmip_destroy(&ctx);
+
+    return(result);
+}
+
+int
+test_decode_attribute_v2_cryptographic_algorithm(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following value:
+    *  Cryptographic Algorithm - AES
+    */
+    uint8 encoding[16] = {
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00
+    };
+
+    KMIP ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0);
+
+    Attribute expected = {0};
+    kmip_init_attribute(&expected);
+    enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES;
+    expected.type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM;
+    expected.value = &algorithm;
+
+    Attribute observed = {0};
+    int result = kmip_decode_attribute_v2(&ctx, &observed);
+    int comparison = kmip_compare_attribute(&expected, &observed);
+    if(!comparison)
+    {
+        kmip_print_attribute(1, &expected);
+        kmip_print_attribute(1, &observed);
+    }
+    result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__);
+
+    kmip_free_attribute(&ctx, &observed);
+    kmip_destroy(&ctx);
+
+    return(result);
+}
+
+int
+test_decode_attribute_v2_cryptographic_length(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following value:
+    *  Cryptographic Length - 128
+    */
+    uint8 encoding[16] = {
+        0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
+    };
+
+    KMIP ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0);
+
+    Attribute expected = {0};
+    kmip_init_attribute(&expected);
+    int32 length = 128;
+    expected.type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH;
+    expected.value = &length;
+
+    Attribute observed = {0};
+    int result = kmip_decode_attribute_v2(&ctx, &observed);
+    int comparison = kmip_compare_attribute(&expected, &observed);
+    if(!comparison)
+    {
+        kmip_print_attribute(1, &expected);
+        kmip_print_attribute(1, &observed);
+    }
+    result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__);
+
+    kmip_free_attribute(&ctx, &observed);
+    kmip_destroy(&ctx);
+
+    return(result);
+}
+
+int
+test_decode_attribute_v2_cryptographic_usage_mask(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following value:
+    *  Cryptographic Usage Mask - Encrypt | Decrypt
+    */
+    uint8 encoding[16] = {
+        0x42, 0x00, 0x2C, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00
+    };
+
+    KMIP ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0);
+
+    Attribute expected = {0};
+    kmip_init_attribute(&expected);
+    int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT;
+    expected.type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK;
+    expected.value = &mask;
+
+    Attribute observed = {0};
+    int result = kmip_decode_attribute_v2(&ctx, &observed);
+    int comparison = kmip_compare_attribute(&expected, &observed);
+    if(!comparison)
+    {
+        kmip_print_attribute(1, &expected);
+        kmip_print_attribute(1, &observed);
+    }
+    result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__);
+
+    kmip_free_attribute(&ctx, &observed);
+    kmip_destroy(&ctx);
+
+    return(result);
+}
+
+int
+test_decode_attribute_v2_state(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following value:
+    *  State - Active
+    */
+    uint8 encoding[16] = {
+        0x42, 0x00, 0x8D, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00
+    };
+
+    KMIP ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0);
+
+    Attribute expected = {0};
+    kmip_init_attribute(&expected);
+    enum state state = KMIP_STATE_ACTIVE;
+    expected.type = KMIP_ATTR_STATE;
+    expected.value = &state;
+
+    Attribute observed = {0};
+    int result = kmip_decode_attribute_v2(&ctx, &observed);
+    int comparison = kmip_compare_attribute(&expected, &observed);
+    if(!comparison)
+    {
+        kmip_print_attribute(1, &expected);
+        kmip_print_attribute(1, &observed);
+    }
+    result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__);
+
+    kmip_free_attribute(&ctx, &observed);
+    kmip_destroy(&ctx);
+
+    return(result);
+}
+
+int
+test_decode_attribute_v2_unsupported_attribute(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[3] = {0x42, 0x00, 0x00};
+
+    KMIP ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0);
+
+    Attribute observed = {0};
+    int result = kmip_decode_attribute_v2(&ctx, &observed);
+    if(result != KMIP_ERROR_ATTR_UNSUPPORTED)
+    {
+        TEST_FAILED(tracker, __func__, __LINE__);
+    }
+
+    kmip_free_attribute(&ctx, &observed);
+    kmip_destroy(&ctx);
+
+    TEST_PASSED(tracker, __func__);
+}
+
+int
+test_encode_template_attribute(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[288] = {
+        0x42, 0x00, 0x91, 0x01, 0x00, 0x00, 0x01, 0x18, 
+        0x42, 0x00, 0x53, 0x01, 0x00, 0x00, 0x00, 0x28, 
+        0x42, 0x00, 0x55, 0x07, 0x00, 0x00, 0x00, 0x09, 
+        0x54, 0x65, 0x6D, 0x70, 0x6C, 0x61, 0x74, 0x65, 
+        0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x17, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C, 
+        0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, 
+        0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x14, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x4C, 0x65, 
+        0x6E, 0x67, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, 
+        0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B, 
+        0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x38, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x04, 
+        0x4E, 0x61, 0x6D, 0x65, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0B, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x55, 0x07, 0x00, 0x00, 0x00, 0x04, 
+        0x4B, 0x65, 0x79, 0x31, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[288] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct text_string v = {0};
+    v.value = "Template1";
+    v.size = 9;
+    
+    struct name n = {0};
+    n.value = &v;
+    n.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING;
+    
+    struct attribute a[4] = {0};
+    for(int i = 0; i < 4; i++)
+    {
+        kmip_init_attribute(&a[i]);
+    }
+    
+    enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES;
+    a[0].type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM;
+    a[0].value = &algorithm;
+    
+    int32 length = 128;
+    a[1].type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH;
+    a[1].value = &length;
+    
+    int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT;
+    a[2].type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK;
+    a[2].value = &mask;
+    
+    struct text_string value = {0};
+    value.value = "Key1";
+    value.size = 4;
+    
+    struct name name = {0};
+    name.value = &value;
+    name.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING;
+    a[3].type = KMIP_ATTR_NAME;
+    a[3].value = &name;
+    
+    struct template_attribute ta = {0};
+    ta.names = &n;
+    ta.name_count = 1;
+    ta.attributes = a;
+    ta.attribute_count = ARRAY_LENGTH(a);
+    
+    int result = kmip_encode_template_attribute(&ctx, &ta);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_template_attribute(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[288] = {
+        0x42, 0x00, 0x91, 0x01, 0x00, 0x00, 0x01, 0x18, 
+        0x42, 0x00, 0x53, 0x01, 0x00, 0x00, 0x00, 0x28, 
+        0x42, 0x00, 0x55, 0x07, 0x00, 0x00, 0x00, 0x09, 
+        0x54, 0x65, 0x6D, 0x70, 0x6C, 0x61, 0x74, 0x65, 
+        0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x17, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C, 
+        0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, 
+        0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x14, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x4C, 0x65, 
+        0x6E, 0x67, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, 
+        0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B, 
+        0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x38, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x04, 
+        0x4E, 0x61, 0x6D, 0x65, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0B, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x55, 0x07, 0x00, 0x00, 0x00, 0x04, 
+        0x4B, 0x65, 0x79, 0x31, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_0);
+    
+    struct text_string v = {0};
+    v.value = "Template1";
+    v.size = 9;
+    
+    struct name n = {0};
+    n.value = &v;
+    n.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING;
+    
+    struct attribute a[4] = {0};
+    for(int i = 0; i < 4; i++)
+    {
+        kmip_init_attribute(&a[i]);
+    }
+    
+    enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES;
+    a[0].type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM;
+    a[0].value = &algorithm;
+    
+    int32 length = 128;
+    a[1].type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH;
+    a[1].value = &length;
+    
+    int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT;
+    a[2].type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK;
+    a[2].value = &mask;
+    
+    struct text_string value = {0};
+    value.value = "Key1";
+    value.size = 4;
+    
+    struct name name = {0};
+    name.value = &value;
+    name.type = KMIP_NAME_UNINTERPRETED_TEXT_STRING;
+    a[3].type = KMIP_ATTR_NAME;
+    a[3].value = &name;
+    
+    struct template_attribute expected = {0};
+    expected.names = &n;
+    expected.name_count = 1;
+    expected.attributes = a;
+    expected.attribute_count = ARRAY_LENGTH(a);
+    struct template_attribute observed = {0};
+    
+    int result = kmip_decode_template_attribute(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_template_attribute(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_template_attribute(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+/*
+The following tests cover features added in KMIP 1.1.
+*/
+
+int
+test_encode_device_credential(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[144] = {
+        0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x88, 
+        0x42, 0x00, 0xB0, 0x07, 0x00, 0x00, 0x00, 0x0C, 
+        0x73, 0x65, 0x72, 0x4E, 0x75, 0x6D, 0x31, 0x32, 
+        0x33, 0x34, 0x35, 0x36, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x06, 
+        0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x00, 0x00, 
+        0x42, 0x00, 0xA2, 0x07, 0x00, 0x00, 0x00, 0x09, 
+        0x64, 0x65, 0x76, 0x49, 0x44, 0x32, 0x32, 0x33, 
+        0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0xAB, 0x07, 0x00, 0x00, 0x00, 0x09, 
+        0x6E, 0x65, 0x74, 0x49, 0x44, 0x39, 0x30, 0x30, 
+        0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0xA9, 0x07, 0x00, 0x00, 0x00, 0x0A, 
+        0x6D, 0x61, 0x63, 0x68, 0x69, 0x6E, 0x65, 0x49, 
+        0x44, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0xAA, 0x07, 0x00, 0x00, 0x00, 0x0A, 
+        0x6D, 0x65, 0x64, 0x69, 0x61, 0x49, 0x44, 0x33, 
+        0x31, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[144] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_1);
+    
+    struct text_string dsn = {0};
+    dsn.value = "serNum123456";
+    dsn.size = 12;
+    
+    struct text_string p = {0};
+    p.value = "secret";
+    p.size = 6;
+    
+    struct text_string di = {0};
+    di.value = "devID2233";
+    di.size = 9;
+    
+    struct text_string ni = {0};
+    ni.value = "netID9000";
+    ni.size = 9;
+    
+    struct text_string mac = {0};
+    mac.value = "machineID1";
+    mac.size = 10;
+    
+    struct text_string med = {0};
+    med.value = "mediaID313";
+    med.size = 10;
+    
+    struct device_credential dc = {0};
+    dc.device_serial_number = &dsn;
+    dc.password = &p;
+    dc.device_identifier = &di;
+    dc.network_identifier = &ni;
+    dc.machine_identifier = &mac;
+    dc.media_identifier = &med;
+    
+    int result = kmip_encode_device_credential(&ctx, &dc);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_device_credential(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[144] = {
+        0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x88, 
+        0x42, 0x00, 0xB0, 0x07, 0x00, 0x00, 0x00, 0x0C, 
+        0x73, 0x65, 0x72, 0x4E, 0x75, 0x6D, 0x31, 0x32, 
+        0x33, 0x34, 0x35, 0x36, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x06, 
+        0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x00, 0x00, 
+        0x42, 0x00, 0xA2, 0x07, 0x00, 0x00, 0x00, 0x09, 
+        0x64, 0x65, 0x76, 0x49, 0x44, 0x32, 0x32, 0x33, 
+        0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0xAB, 0x07, 0x00, 0x00, 0x00, 0x09, 
+        0x6E, 0x65, 0x74, 0x49, 0x44, 0x39, 0x30, 0x30, 
+        0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0xA9, 0x07, 0x00, 0x00, 0x00, 0x0A, 
+        0x6D, 0x61, 0x63, 0x68, 0x69, 0x6E, 0x65, 0x49, 
+        0x44, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0xAA, 0x07, 0x00, 0x00, 0x00, 0x0A, 
+        0x6D, 0x65, 0x64, 0x69, 0x61, 0x49, 0x44, 0x33, 
+        0x31, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_1);
+    
+    struct text_string dsn = {0};
+    dsn.value = "serNum123456";
+    dsn.size = 12;
+    
+    struct text_string p = {0};
+    p.value = "secret";
+    p.size = 6;
+    
+    struct text_string di = {0};
+    di.value = "devID2233";
+    di.size = 9;
+    
+    struct text_string ni = {0};
+    ni.value = "netID9000";
+    ni.size = 9;
+    
+    struct text_string mac = {0};
+    mac.value = "machineID1";
+    mac.size = 10;
+    
+    struct text_string med = {0};
+    med.value = "mediaID313";
+    med.size = 10;
+    
+    struct device_credential expected = {0};
+    expected.device_serial_number = &dsn;
+    expected.password = &p;
+    expected.device_identifier = &di;
+    expected.network_identifier = &ni;
+    expected.machine_identifier = &mac;
+    expected.media_identifier = &med;
+    
+    struct device_credential observed = {0};
+    
+    int result = kmip_decode_device_credential(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_device_credential(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_device_credential(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_key_wrapping_data_with_encoding_option(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[120] = {
+        0x42, 0x00, 0x46, 0x01, 0x00, 0x00, 0x00, 0x70, 
+        0x42, 0x00, 0x9E, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35,
+        0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, 
+        0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, 
+        0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, 
+        0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10,
+        0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xA3, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[120] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_1);
+    
+    struct text_string uuid = {0};
+    uuid.value = "100182d5-72b8-47aa-8383-4d97d512e98a";
+    uuid.size = 36;
+    
+    struct cryptographic_parameters cp = {0};
+    cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP;
+    
+    struct encryption_key_information eki = {0};
+    eki.unique_identifier = &uuid;
+    eki.cryptographic_parameters = &cp;
+    
+    struct key_wrapping_data kwd = {0};
+    kwd.wrapping_method = KMIP_WRAP_ENCRYPT;
+    kwd.encryption_key_info = &eki;
+    kwd.encoding_option = KMIP_ENCODE_NO_ENCODING;
+    
+    int result = kmip_encode_key_wrapping_data(&ctx, &kwd);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_key_wrapping_data_with_encoding_option(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[120] = {
+        0x42, 0x00, 0x46, 0x01, 0x00, 0x00, 0x00, 0x70, 
+        0x42, 0x00, 0x9E, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35,
+        0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, 
+        0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, 
+        0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, 
+        0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10,
+        0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xA3, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_1);
+    
+    struct text_string uuid = {0};
+    uuid.value = "100182d5-72b8-47aa-8383-4d97d512e98a";
+    uuid.size = 36;
+    
+    struct cryptographic_parameters cp = {0};
+    kmip_init_cryptographic_parameters(&cp);
+    cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP;
+    
+    struct encryption_key_information eki = {0};
+    eki.unique_identifier = &uuid;
+    eki.cryptographic_parameters = &cp;
+    
+    struct key_wrapping_data expected = {0};
+    expected.wrapping_method = KMIP_WRAP_ENCRYPT;
+    expected.encryption_key_info = &eki;
+    expected.encoding_option = KMIP_ENCODE_NO_ENCODING;
+    
+    struct key_wrapping_data observed = {0};
+    
+    int result = kmip_decode_key_wrapping_data(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_key_wrapping_data(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_key_wrapping_data(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_key_wrapping_specification_with_encoding_option(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[120] = {
+        0x42, 0x00, 0x47, 0x01, 0x00, 0x00, 0x00, 0x70, 
+        0x42, 0x00, 0x9E, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x31, 0x30, 0x30, 0x31, 0x38, 0x32, 0x64, 0x35, 
+        0x2D, 0x37, 0x32, 0x62, 0x38, 0x2D, 0x34, 0x37, 
+        0x61, 0x61, 0x2D, 0x38, 0x33, 0x38, 0x33, 0x2D, 
+        0x34, 0x64, 0x39, 0x37, 0x64, 0x35, 0x31, 0x32, 
+        0x65, 0x39, 0x38, 0x61, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, 
+        0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0xA3, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[120] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_1);
+    
+    struct text_string uuid = {0};
+    uuid.value = "100182d5-72b8-47aa-8383-4d97d512e98a";
+    uuid.size = 36;
+    
+    struct cryptographic_parameters cp = {0};
+    cp.block_cipher_mode = KMIP_BLOCK_NIST_KEY_WRAP;
+    
+    struct encryption_key_information eki = {0};
+    eki.unique_identifier = &uuid;
+    eki.cryptographic_parameters = &cp;
+    
+    struct key_wrapping_specification kws = {0};
+    kws.wrapping_method = KMIP_WRAP_ENCRYPT;
+    kws.encryption_key_info = &eki;
+    kws.encoding_option = KMIP_ENCODE_NO_ENCODING;
+    
+    int result = kmip_encode_key_wrapping_specification(&ctx, &kws);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+/*
+The following tests cover features added in KMIP 1.2.
+*/
+
+int
+test_encode_nonce(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[40] = {
+        0x42, 0x00, 0xC8, 0x01, 0x00, 0x00, 0x00, 0x20,
+        0x42, 0x00, 0xC9, 0x08, 0x00, 0x00, 0x00, 0x04,
+        0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x06,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00
+    };
+    
+    uint8 observed[40] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_2);
+    
+    uint8 id[4] = {0x01, 0x02, 0x03, 0x04};
+    struct byte_string ni = {0};
+    ni.value = id;
+    ni.size = ARRAY_LENGTH(id);
+    
+    uint8 value[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+    struct byte_string nv = {0};
+    nv.value = value;
+    nv.size = ARRAY_LENGTH(value);
+    
+    struct nonce n = {0};
+    n.nonce_id = &ni;
+    n.nonce_value = &nv;
+    
+    int result = kmip_encode_nonce(&ctx, &n);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_nonce(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[40] = {
+        0x42, 0x00, 0xC8, 0x01, 0x00, 0x00, 0x00, 0x20,
+        0x42, 0x00, 0xC9, 0x08, 0x00, 0x00, 0x00, 0x04,
+        0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x06,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_2);
+    
+    uint8 id[4] = {0x01, 0x02, 0x03, 0x04};
+    struct byte_string ni = {0};
+    ni.value = id;
+    ni.size = ARRAY_LENGTH(id);
+    
+    uint8 value[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+    struct byte_string nv = {0};
+    nv.value = value;
+    nv.size = ARRAY_LENGTH(value);
+    
+    struct nonce expected = {0};
+    expected.nonce_id = &ni;
+    expected.nonce_value = &nv;
+    
+    struct nonce observed = {0};
+    
+    int result = kmip_decode_nonce(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_nonce(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_nonce(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_attestation_credential(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[128] = {
+        0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x70,
+        0x42, 0x00, 0xC8, 0x01, 0x00, 0x00, 0x00, 0x20,
+        0x42, 0x00, 0xC9, 0x08, 0x00, 0x00, 0x00, 0x04,
+        0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x06,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+        0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xCB, 0x08, 0x00, 0x00, 0x00, 0x10,
+        0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44,
+        0x66, 0x66, 0x66, 0x66, 0x88, 0x88, 0x88, 0x88,
+        0x42, 0x00, 0xCC, 0x08, 0x00, 0x00, 0x00, 0x14,
+        0x11, 0x11, 0x11, 0x11, 0x33, 0x33, 0x33, 0x33,
+        0x55, 0x55, 0x55, 0x55, 0x77, 0x77, 0x77, 0x77,
+        0x99, 0x99, 0x99, 0x99, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[128] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_2);
+    
+    uint8 nonce_id[4] = {0x01, 0x02, 0x03, 0x04};
+    struct byte_string ni = {0};
+    ni.value = nonce_id;
+    ni.size = ARRAY_LENGTH(nonce_id);
+    
+    uint8 nonce_value[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+    struct byte_string nv = {0};
+    nv.value = nonce_value;
+    nv.size = ARRAY_LENGTH(nonce_value);
+    
+    struct nonce n = {0};
+    n.nonce_id = &ni;
+    n.nonce_value = &nv;
+    
+    uint8 measurement[16] = {
+        0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44,
+        0x66, 0x66, 0x66, 0x66, 0x88, 0x88, 0x88, 0x88
+    };
+    struct byte_string am = {0};
+    am.value = measurement;
+    am.size = ARRAY_LENGTH(measurement);
+    
+    uint8 assertion[20] = {
+        0x11, 0x11, 0x11, 0x11, 0x33, 0x33, 0x33, 0x33,
+        0x55, 0x55, 0x55, 0x55, 0x77, 0x77, 0x77, 0x77,
+        0x99, 0x99, 0x99, 0x99
+    };
+    struct byte_string aa = {0};
+    aa.value = assertion;
+    aa.size = ARRAY_LENGTH(assertion);
+    
+    struct attestation_credential ac = {0};
+    ac.nonce = &n;
+    ac.attestation_type = KMIP_ATTEST_TPM_QUOTE;
+    ac.attestation_measurement = &am;
+    ac.attestation_assertion = &aa;
+    
+    int result = kmip_encode_attestation_credential(&ctx, &ac);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_attestation_credential(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[128] = {
+        0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x70,
+        0x42, 0x00, 0xC8, 0x01, 0x00, 0x00, 0x00, 0x20,
+        0x42, 0x00, 0xC9, 0x08, 0x00, 0x00, 0x00, 0x04,
+        0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x06,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+        0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xCB, 0x08, 0x00, 0x00, 0x00, 0x10,
+        0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44,
+        0x66, 0x66, 0x66, 0x66, 0x88, 0x88, 0x88, 0x88,
+        0x42, 0x00, 0xCC, 0x08, 0x00, 0x00, 0x00, 0x14,
+        0x11, 0x11, 0x11, 0x11, 0x33, 0x33, 0x33, 0x33,
+        0x55, 0x55, 0x55, 0x55, 0x77, 0x77, 0x77, 0x77,
+        0x99, 0x99, 0x99, 0x99, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_2);
+    
+    uint8 nonce_id[4] = {0x01, 0x02, 0x03, 0x04};
+    struct byte_string ni = {0};
+    ni.value = nonce_id;
+    ni.size = ARRAY_LENGTH(nonce_id);
+    
+    uint8 nonce_value[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+    struct byte_string nv = {0};
+    nv.value = nonce_value;
+    nv.size = ARRAY_LENGTH(nonce_value);
+    
+    struct nonce n = {0};
+    n.nonce_id = &ni;
+    n.nonce_value = &nv;
+    
+    uint8 measurement[16] = {
+        0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44,
+        0x66, 0x66, 0x66, 0x66, 0x88, 0x88, 0x88, 0x88
+    };
+    struct byte_string am = {0};
+    am.value = measurement;
+    am.size = ARRAY_LENGTH(measurement);
+    
+    uint8 assertion[20] = {
+        0x11, 0x11, 0x11, 0x11, 0x33, 0x33, 0x33, 0x33,
+        0x55, 0x55, 0x55, 0x55, 0x77, 0x77, 0x77, 0x77,
+        0x99, 0x99, 0x99, 0x99
+    };
+    struct byte_string aa = {0};
+    aa.value = assertion;
+    aa.size = ARRAY_LENGTH(assertion);
+    
+    struct attestation_credential expected = {0};
+    expected.nonce = &n;
+    expected.attestation_type = KMIP_ATTEST_TPM_QUOTE;
+    expected.attestation_measurement = &am;
+    expected.attestation_assertion = &aa;
+    
+    struct attestation_credential observed = {0};
+    
+    int result = kmip_decode_attestation_credential(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_attestation_credential(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_attestation_credential(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_request_header_with_attestation_details(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[216] = {
+        0x42, 0x00, 0x77, 0x01, 0x00, 0x00, 0x00, 0xD0, 
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0xD3, 0x06, 0x00, 0x00, 0x00, 0x08,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x40, 
+        0x42, 0x00, 0x23, 0x01, 0x00, 0x00, 0x00, 0x38, 
+        0x42, 0x00, 0x24, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x99, 0x07, 0x00, 0x00, 0x00, 0x06, 
+        0x42, 0x61, 0x72, 0x6E, 0x65, 0x79, 0x00, 0x00, 
+        0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x07, 
+        0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x32, 0x00, 
+        0x42, 0x00, 0x0E, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x10, 0x06, 0x00, 0x00, 0x00, 0x08, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
+        0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[216] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_2);
+    
+    struct protocol_version pv = {0};
+    pv.major = 1;
+    pv.minor = 0;
+    
+    struct text_string username = {0};
+    username.value = "Barney";
+    username.size = 6;
+    struct text_string password = {0};
+    password.value = "secret2";
+    password.size = 7;
+    
+    struct username_password_credential upc = {0};
+    upc.username = &username;
+    upc.password = &password;
+    
+    struct credential c = {0};
+    c.credential_type = KMIP_CRED_USERNAME_AND_PASSWORD;
+    c.credential_value = &upc;
+    
+    struct authentication a = {0};
+    a.credential = &c;
+    
+    enum attestation_type types[2] = {
+        KMIP_ATTEST_TPM_QUOTE, 
+        KMIP_ATTEST_SAML_ASSERTION
+    };
+    
+    struct request_header rh = {0};
+    kmip_init_request_header(&rh);
+    
+    rh.protocol_version = &pv;
+    rh.attestation_capable_indicator = KMIP_TRUE;
+    rh.attestation_types = types;
+    rh.attestation_type_count = ARRAY_LENGTH(types);
+    rh.authentication = &a;
+    rh.batch_error_continuation_option = KMIP_BATCH_CONTINUE;
+    rh.batch_order_option = KMIP_TRUE;
+    rh.batch_count = 2;
+    
+    int result = kmip_encode_request_header(&ctx, &rh);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_response_header_with_attestation_details(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[152] = {
+        0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0x90, 
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, 
+        0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE5,
+        0x42, 0x00, 0xC8, 0x01, 0x00, 0x00, 0x00, 0x20,
+        0x42, 0x00, 0xC9, 0x08, 0x00, 0x00, 0x00, 0x04,
+        0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x06,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+        0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[152] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_2);
+    
+    struct protocol_version pv = {0};
+    pv.major = 1;
+    pv.minor = 0;
+    
+    uint8 id[4] = {0x01, 0x02, 0x03, 0x04};
+    struct byte_string ni = {0};
+    ni.value = id;
+    ni.size = ARRAY_LENGTH(id);
+    
+    uint8 value[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+    struct byte_string nv = {0};
+    nv.value = value;
+    nv.size = ARRAY_LENGTH(value);
+    
+    struct nonce n = {0};
+    n.nonce_id = &ni;
+    n.nonce_value = &nv;
+    
+    enum attestation_type types[2] = {
+        KMIP_ATTEST_TPM_QUOTE,
+        KMIP_ATTEST_SAML_ASSERTION
+    };
+    
+    struct response_header rh = {0};
+    kmip_init_response_header(&rh);
+    
+    rh.protocol_version = &pv;
+    rh.time_stamp = 1335514341;
+    rh.nonce = &n;
+    rh.attestation_types = types;
+    rh.attestation_type_count = ARRAY_LENGTH(types);
+    rh.batch_count = 1;
+    
+    int result = kmip_encode_response_header(&ctx, &rh);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_response_header_with_attestation_details(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[152] = {
+        0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0x90, 
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, 
+        0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE5,
+        0x42, 0x00, 0xC8, 0x01, 0x00, 0x00, 0x00, 0x20,
+        0x42, 0x00, 0xC9, 0x08, 0x00, 0x00, 0x00, 0x04,
+        0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x06,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+        0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_2);
+    
+    struct protocol_version pv = {0};
+    pv.major = 1;
+    pv.minor = 0;
+    
+    uint8 id[4] = {0x01, 0x02, 0x03, 0x04};
+    struct byte_string ni = {0};
+    ni.value = id;
+    ni.size = ARRAY_LENGTH(id);
+    
+    uint8 value[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+    struct byte_string nv = {0};
+    nv.value = value;
+    nv.size = ARRAY_LENGTH(value);
+    
+    struct nonce n = {0};
+    n.nonce_id = &ni;
+    n.nonce_value = &nv;
+    
+    enum attestation_type types[2] = {
+        KMIP_ATTEST_TPM_QUOTE,
+        KMIP_ATTEST_SAML_ASSERTION
+    };
+    
+    struct response_header expected = {0};
+    kmip_init_response_header(&expected);
+    
+    expected.protocol_version = &pv;
+    expected.time_stamp = 1335514341;
+    expected.nonce = &n;
+    expected.attestation_types = types;
+    expected.attestation_type_count = ARRAY_LENGTH(types);
+    expected.batch_count = 1;
+    
+    struct response_header observed = {0};
+    kmip_init_response_header(&observed);
+    
+    int result = kmip_decode_response_header(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_response_header(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_response_header(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_cryptographic_parameters_with_digital_signature_fields(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[216] = {
+        0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0xD0,
+        0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x5F, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x38, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x83, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xAE, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xC5, 0x06, 0x00, 0x00, 0x00, 0x08,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        0x42, 0x00, 0xCD, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xCE, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xCF, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xD2, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xD0, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xD1, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[216] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_2);
+    
+    struct cryptographic_parameters cp = {0};
+    cp.block_cipher_mode = KMIP_BLOCK_CBC;
+    cp.padding_method = KMIP_PAD_PKCS5;
+    cp.hashing_algorithm = KMIP_HASH_SHA1;
+    cp.key_role_type = KMIP_ROLE_KEK;
+    
+    cp.digital_signature_algorithm = KMIP_DIGITAL_SHA256_WITH_RSA;
+    cp.cryptographic_algorithm = KMIP_CRYPTOALG_RSA;
+    cp.random_iv = KMIP_TRUE;
+    cp.iv_length = 128;
+    cp.tag_length = 64;
+    cp.fixed_field_length = 64;
+    cp.invocation_field_length = 64;
+    cp.counter_length = 256;
+    cp.initial_counter_value = 0;
+    
+    int result = kmip_encode_cryptographic_parameters(&ctx, &cp);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_cryptographic_parameters_with_digital_signature_fields(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[216] = {
+        0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0xD0,
+        0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x5F, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x38, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x83, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xAE, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00 ,0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xC5, 0x06, 0x00, 0x00, 0x00, 0x08,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        0x42, 0x00, 0xCD, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xCE, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xCF, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xD2, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xD0, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xD1, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_2);
+    
+    struct cryptographic_parameters expected = {0};
+    kmip_init_cryptographic_parameters(&expected);
+    expected.block_cipher_mode = KMIP_BLOCK_CBC;
+    expected.padding_method = KMIP_PAD_PKCS5;
+    expected.hashing_algorithm = KMIP_HASH_SHA1;
+    expected.key_role_type = KMIP_ROLE_KEK;
+    
+    expected.digital_signature_algorithm = KMIP_DIGITAL_SHA256_WITH_RSA;
+    expected.cryptographic_algorithm = KMIP_CRYPTOALG_RSA;
+    expected.random_iv = KMIP_TRUE;
+    expected.iv_length = 128;
+    expected.tag_length = 64;
+    expected.fixed_field_length = 64;
+    expected.invocation_field_length = 64;
+    expected.counter_length = 256;
+    expected.initial_counter_value = 0;
+    
+    struct cryptographic_parameters observed = {0};
+    kmip_init_cryptographic_parameters(&observed);
+    
+    int result = kmip_decode_cryptographic_parameters(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_cryptographic_parameters(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_cryptographic_parameters(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+/*
+The following tests cover features added in KMIP 1.4.
+*/
+
+int
+test_encode_cryptographic_parameters_with_mask_fields(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[312] = {
+        0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x01, 0x30,
+        0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x5F, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x38, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x83, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xAE, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xC5, 0x06, 0x00, 0x00, 0x00, 0x08,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        0x42, 0x00, 0xCD, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xCE, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xCF, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xD2, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xD0, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xD1, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x01, 0x01, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x01, 0x02, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x01, 0x03, 0x08, 0x00, 0x00, 0x00, 0x18, 
+        0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, 
+        0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, 
+        0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8,
+        0x42, 0x01, 0x04, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[312] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_4);
+    
+    uint8 value[24] = {
+        0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, 
+        0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, 
+        0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8
+    };
+    struct byte_string ps = {0};
+    ps.value = value;
+    ps.size = ARRAY_LENGTH(value);
+    
+    struct cryptographic_parameters cp = {0};
+    cp.block_cipher_mode = KMIP_BLOCK_CBC;
+    cp.padding_method = KMIP_PAD_PKCS5;
+    cp.hashing_algorithm = KMIP_HASH_SHA1;
+    cp.key_role_type = KMIP_ROLE_KEK;
+    
+    cp.digital_signature_algorithm = KMIP_DIGITAL_SHA256_WITH_RSA;
+    cp.cryptographic_algorithm = KMIP_CRYPTOALG_RSA;
+    cp.random_iv = KMIP_TRUE;
+    cp.iv_length = 128;
+    cp.tag_length = 64;
+    cp.fixed_field_length = 64;
+    cp.invocation_field_length = 64;
+    cp.counter_length = 256;
+    cp.initial_counter_value = 0;
+    
+    cp.salt_length = 32;
+    cp.mask_generator = KMIP_MASKGEN_MGF1;
+    cp.mask_generator_hashing_algorithm = KMIP_HASH_SHA256;
+    cp.p_source = &ps;
+    cp.trailer_field = 1;
+    
+    int result = kmip_encode_cryptographic_parameters(&ctx, &cp);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_cryptographic_parameters_with_mask_fields(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[312] = {
+        0x42, 0x00, 0x2B, 0x01, 0x00, 0x00, 0x01, 0x30,
+        0x42, 0x00, 0x11, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x5F, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x38, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x83, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xAE, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xC5, 0x06, 0x00, 0x00, 0x00, 0x08,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        0x42, 0x00, 0xCD, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xCE, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xCF, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xD2, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xD0, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xD1, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x01, 0x01, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x01, 0x02, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x01, 0x03, 0x08, 0x00, 0x00, 0x00, 0x18, 
+        0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, 
+        0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, 
+        0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8,
+        0x42, 0x01, 0x04, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_4);
+    
+    uint8 value[24] = {
+        0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, 
+        0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, 
+        0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8
+    };
+    struct byte_string ps = {0};
+    ps.value = value;
+    ps.size = ARRAY_LENGTH(value);
+    
+    struct cryptographic_parameters expected = {0};
+    kmip_init_cryptographic_parameters(&expected);
+    
+    expected.block_cipher_mode = KMIP_BLOCK_CBC;
+    expected.padding_method = KMIP_PAD_PKCS5;
+    expected.hashing_algorithm = KMIP_HASH_SHA1;
+    expected.key_role_type = KMIP_ROLE_KEK;
+    
+    expected.digital_signature_algorithm = KMIP_DIGITAL_SHA256_WITH_RSA;
+    expected.cryptographic_algorithm = KMIP_CRYPTOALG_RSA;
+    expected.random_iv = KMIP_TRUE;
+    expected.iv_length = 128;
+    expected.tag_length = 64;
+    expected.fixed_field_length = 64;
+    expected.invocation_field_length = 64;
+    expected.counter_length = 256;
+    expected.initial_counter_value = 0;
+    
+    expected.salt_length = 32;
+    expected.mask_generator = KMIP_MASKGEN_MGF1;
+    expected.mask_generator_hashing_algorithm = KMIP_HASH_SHA256;
+    expected.p_source = &ps;
+    expected.trailer_field = 1;
+    
+    struct cryptographic_parameters observed = {0};
+    kmip_init_cryptographic_parameters(&observed);
+    
+    int result = kmip_decode_cryptographic_parameters(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_cryptographic_parameters(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_cryptographic_parameters(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_get_request_payload_with_wrap_type(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[104] = {
+        0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x60, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x37, 0x63, 0x66, 0x35, 0x32, 0x30, 0x39, 0x62, 
+        0x2D, 0x36, 0x66, 0x66, 0x36, 0x2D, 0x34, 0x34, 
+        0x32, 0x36, 0x2D, 0x38, 0x39, 0x39, 0x65, 0x2D, 
+        0x32, 0x32, 0x62, 0x30, 0x36, 0x37, 0x38, 0x35, 
+        0x39, 0x33, 0x37, 0x32, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xF8, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x41, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[104] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_4);
+    
+    struct text_string uuid = {0};
+    uuid.value = "7cf5209b-6ff6-4426-899e-22b067859372";
+    uuid.size = 36;
+    
+    struct get_request_payload grp = {0};
+    grp.unique_identifier = &uuid;
+    grp.key_format_type = KMIP_KEYFORMAT_PKCS1;
+    grp.key_compression_type = KMIP_KEYCOMP_EC_PUB_UNCOMPRESSED;
+    
+    grp.key_wrap_type = KMIP_WRAPTYPE_NOT_WRAPPED;
+    
+    int result = kmip_encode_get_request_payload(&ctx, &grp);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_request_header_with_correlation_values(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[280] = {
+        0x42, 0x00, 0x77, 0x01, 0x00, 0x00, 0x01, 0x10, 
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x50, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x01, 0x05, 0x07, 0x00, 0x00, 0x00, 0x08,
+        0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x31,
+        0x42, 0x01, 0x06, 0x07, 0x00, 0x00, 0x00, 0x08,
+        0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x31,
+        0x42, 0x00, 0x07, 0x06, 0x00, 0x00, 0x00, 0x08,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        0x42, 0x00, 0xD3, 0x06, 0x00, 0x00, 0x00, 0x08,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x40, 
+        0x42, 0x00, 0x23, 0x01, 0x00, 0x00, 0x00, 0x38, 
+        0x42, 0x00, 0x24, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x99, 0x07, 0x00, 0x00, 0x00, 0x06, 
+        0x42, 0x61, 0x72, 0x6E, 0x65, 0x79, 0x00, 0x00, 
+        0x42, 0x00, 0xA1, 0x07, 0x00, 0x00, 0x00, 0x07, 
+        0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x32, 0x00, 
+        0x42, 0x00, 0x0E, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x10, 0x06, 0x00, 0x00, 0x00, 0x08, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
+        0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[280] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_4);
+    
+    struct protocol_version pv = {0};
+    pv.major = 1;
+    pv.minor = 0;
+    
+    struct text_string username = {0};
+    username.value = "Barney";
+    username.size = 6;
+    struct text_string password = {0};
+    password.value = "secret2";
+    password.size = 7;
+    
+    struct username_password_credential upc = {0};
+    upc.username = &username;
+    upc.password = &password;
+    
+    struct credential c = {0};
+    c.credential_type = KMIP_CRED_USERNAME_AND_PASSWORD;
+    c.credential_value = &upc;
+    
+    struct authentication a = {0};
+    a.credential = &c;
+    
+    enum attestation_type types[2] = {
+        KMIP_ATTEST_TPM_QUOTE, 
+        KMIP_ATTEST_SAML_ASSERTION
+    };
+    
+    struct text_string ccv = {0};
+    ccv.value = "client 1";
+    ccv.size = 8;
+    
+    struct text_string scv = {0};
+    scv.value = "server 1";
+    scv.size = 8;
+    
+    struct request_header rh = {0};
+    kmip_init_request_header(&rh);
+    
+    rh.protocol_version = &pv;
+    rh.maximum_response_size = 4096;
+    rh.asynchronous_indicator = KMIP_TRUE;
+    rh.attestation_capable_indicator = KMIP_TRUE;
+    rh.attestation_types = types;
+    rh.attestation_type_count = ARRAY_LENGTH(types);
+    rh.authentication = &a;
+    rh.batch_error_continuation_option = KMIP_BATCH_CONTINUE;
+    rh.batch_order_option = KMIP_TRUE;
+    rh.batch_count = 2;
+    
+    rh.client_correlation_value = &ccv;
+    rh.server_correlation_value = &scv;
+    
+    int result = kmip_encode_request_header(&ctx, &rh);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_response_header_with_correlation_values(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[184] = {
+        0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0xB0, 
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, 
+        0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE5,
+        0x42, 0x00, 0xC8, 0x01, 0x00, 0x00, 0x00, 0x20,
+        0x42, 0x00, 0xC9, 0x08, 0x00, 0x00, 0x00, 0x04,
+        0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x06,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+        0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x01, 0x05, 0x07, 0x00, 0x00, 0x00, 0x08,
+        0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x31,
+        0x42, 0x01, 0x06, 0x07, 0x00, 0x00, 0x00, 0x08,
+        0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x31, 
+        0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[184] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_4);
+    
+    struct protocol_version pv = {0};
+    pv.major = 1;
+    pv.minor = 0;
+    
+    uint8 id[4] = {0x01, 0x02, 0x03, 0x04};
+    struct byte_string ni = {0};
+    ni.value = id;
+    ni.size = ARRAY_LENGTH(id);
+    
+    uint8 value[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+    struct byte_string nv = {0};
+    nv.value = value;
+    nv.size = ARRAY_LENGTH(value);
+    
+    struct nonce n = {0};
+    n.nonce_id = &ni;
+    n.nonce_value = &nv;
+    
+    enum attestation_type types[2] = {
+        KMIP_ATTEST_TPM_QUOTE,
+        KMIP_ATTEST_SAML_ASSERTION
+    };
+    
+    struct text_string ccv = {0};
+    ccv.value = "client 1";
+    ccv.size = 8;
+    
+    struct text_string scv = {0};
+    scv.value = "server 1";
+    scv.size = 8;
+    
+    struct response_header rh = {0};
+    kmip_init_response_header(&rh);
+    
+    rh.protocol_version = &pv;
+    rh.time_stamp = 1335514341;
+    rh.nonce = &n;
+    rh.attestation_types = types;
+    rh.attestation_type_count = ARRAY_LENGTH(types);
+    rh.batch_count = 1;
+    
+    rh.client_correlation_value = &ccv;
+    rh.server_correlation_value = &scv;
+    
+    int result = kmip_encode_response_header(&ctx, &rh);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_response_header_with_correlation_values(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 encoding[184] = {
+        0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0xB0, 
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, 
+        0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE5,
+        0x42, 0x00, 0xC8, 0x01, 0x00, 0x00, 0x00, 0x20,
+        0x42, 0x00, 0xC9, 0x08, 0x00, 0x00, 0x00, 0x04,
+        0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x06,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+        0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x01, 0x05, 0x07, 0x00, 0x00, 0x00, 0x08,
+        0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x31,
+        0x42, 0x01, 0x06, 0x07, 0x00, 0x00, 0x00, 0x08,
+        0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x31, 
+        0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    struct kmip ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_1_4);
+    
+    struct protocol_version pv = {0};
+    pv.major = 1;
+    pv.minor = 0;
+    
+    uint8 id[4] = {0x01, 0x02, 0x03, 0x04};
+    struct byte_string ni = {0};
+    ni.value = id;
+    ni.size = ARRAY_LENGTH(id);
+    
+    uint8 value[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+    struct byte_string nv = {0};
+    nv.value = value;
+    nv.size = ARRAY_LENGTH(value);
+    
+    struct nonce n = {0};
+    n.nonce_id = &ni;
+    n.nonce_value = &nv;
+    
+    enum attestation_type types[2] = {
+        KMIP_ATTEST_TPM_QUOTE,
+        KMIP_ATTEST_SAML_ASSERTION
+    };
+    
+    struct text_string ccv = {0};
+    ccv.value = "client 1";
+    ccv.size = 8;
+    
+    struct text_string scv = {0};
+    scv.value = "server 1";
+    scv.size = 8;
+    
+    struct response_header expected = {0};
+    kmip_init_response_header(&expected);
+    
+    expected.protocol_version = &pv;
+    expected.time_stamp = 1335514341;
+    expected.nonce = &n;
+    expected.attestation_types = types;
+    expected.attestation_type_count = ARRAY_LENGTH(types);
+    expected.batch_count = 1;
+    
+    expected.client_correlation_value = &ccv;
+    expected.server_correlation_value = &scv;
+    
+    struct response_header observed = {0};
+    kmip_init_response_header(&observed);
+    
+    int result = kmip_decode_response_header(&ctx, &observed);
+    result = report_decoding_test_result(
+        tracker,
+        &ctx,
+        kmip_compare_response_header(&expected, &observed),
+        result,
+        __func__);
+    kmip_free_response_header(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_encode_response_header_kmip_2_0(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following set of values:
+    *  Response Header
+    *      Protocol Version
+    *          Protocol Version Major - 2
+    *          Protocol Version Minor - 0
+    *      Time Stamp - 1335514341
+    *      Nonce
+    *          Nonce ID - 0x01020304
+    *          Nonce Value - 0xFFFFFFFFFFFF
+    *      Server Hashed Password - 301EC144E9C6C4F64C29C01C3E11839C97D6E7D2BC0C5DBC68377B679AE51D4D
+    *      Attestation Type - TPM Quote
+    *      Attestation Type - SAML Assertion
+    *      Client Correlation Value - client 1
+    *      Server Correlation Value - server 1
+    *      Batch Count - 1
+    */
+    uint8 expected[224] = {
+        0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0xD8,
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20,
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08,
+        0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE5,
+        0x42, 0x00, 0xC8, 0x01, 0x00, 0x00, 0x00, 0x20,
+        0x42, 0x00, 0xC9, 0x08, 0x00, 0x00, 0x00, 0x04,
+        0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x06,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+        0x42, 0x01, 0x55, 0x08, 0x00, 0x00, 0x00, 0x20,
+        0x30, 0x1E, 0xC1, 0x44, 0xE9, 0xC6, 0xC4, 0xF6,
+        0x4C, 0x29, 0xC0, 0x1C, 0x3E, 0x11, 0x83, 0x9C,
+        0x97, 0xD6, 0xE7, 0xD2, 0xBC, 0x0C, 0x5D, 0xBC,
+        0x68, 0x37, 0x7B, 0x67, 0x9A, 0xE5, 0x1D, 0x4D,
+        0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x01, 0x05, 0x07, 0x00, 0x00, 0x00, 0x08,
+        0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x31,
+        0x42, 0x01, 0x06, 0x07, 0x00, 0x00, 0x00, 0x08,
+        0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x31,
+        0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+
+    uint8 observed[224] = {0};
+    KMIP ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_2_0);
+
+    ProtocolVersion pv = {0};
+    pv.major = 2;
+    pv.minor = 0;
+
+    uint8 id[4] = {0x01, 0x02, 0x03, 0x04};
+    ByteString ni = {0};
+    ni.value = id;
+    ni.size = ARRAY_LENGTH(id);
+
+    uint8 value[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+    ByteString nv = {0};
+    nv.value = value;
+    nv.size = ARRAY_LENGTH(value);
+
+    Nonce n = {0};
+    n.nonce_id = &ni;
+    n.nonce_value = &nv;
+
+    uint8 hash[32] = {
+        0x30, 0x1E, 0xC1, 0x44, 0xE9, 0xC6, 0xC4, 0xF6,
+        0x4C, 0x29, 0xC0, 0x1C, 0x3E, 0x11, 0x83, 0x9C,
+        0x97, 0xD6, 0xE7, 0xD2, 0xBC, 0x0C, 0x5D, 0xBC,
+        0x68, 0x37, 0x7B, 0x67, 0x9A, 0xE5, 0x1D, 0x4D
+    };
+    ByteString shp = {0};
+    shp.value = hash;
+    shp.size = ARRAY_LENGTH(hash);
+
+    enum attestation_type types[2] = {
+        KMIP_ATTEST_TPM_QUOTE,
+        KMIP_ATTEST_SAML_ASSERTION
+    };
+
+    TextString ccv = {0};
+    ccv.value = "client 1";
+    ccv.size = 8;
+
+    TextString scv = {0};
+    scv.value = "server 1";
+    scv.size = 8;
+
+    ResponseHeader rh = {0};
+    kmip_init_response_header(&rh);
+
+    rh.protocol_version = &pv;
+    rh.time_stamp = 1335514341;
+    rh.nonce = &n;
+    rh.server_hashed_password = &shp;
+    rh.attestation_types = types;
+    rh.attestation_type_count = ARRAY_LENGTH(types);
+    rh.batch_count = 1;
+
+    rh.client_correlation_value = &ccv;
+    rh.server_correlation_value = &scv;
+
+    int result = kmip_encode_response_header(&ctx, &rh);
+    result = report_encoding_test_result(tracker, &ctx, expected, observed, result, __func__);
+
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_decode_response_header_kmip_2_0(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* This encoding matches the following set of values:
+    *  Response Header
+    *      Protocol Version
+    *          Protocol Version Major - 2
+    *          Protocol Version Minor - 0
+    *      Time Stamp - 1335514341
+    *      Nonce
+    *          Nonce ID - 0x01020304
+    *          Nonce Value - 0xFFFFFFFFFFFF
+    *      Server Hashed Password - 301EC144E9C6C4F64C29C01C3E11839C97D6E7D2BC0C5DBC68377B679AE51D4D
+    *      Attestation Type - TPM Quote
+    *      Attestation Type - SAML Assertion
+    *      Client Correlation Value - client 1
+    *      Server Correlation Value - server 1
+    *      Batch Count - 1
+    */
+    uint8 encoding[224] = {
+        0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0xD8,
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20,
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08,
+        0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE5,
+        0x42, 0x00, 0xC8, 0x01, 0x00, 0x00, 0x00, 0x20,
+        0x42, 0x00, 0xC9, 0x08, 0x00, 0x00, 0x00, 0x04,
+        0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x06,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+        0x42, 0x01, 0x55, 0x08, 0x00, 0x00, 0x00, 0x20,
+        0x30, 0x1E, 0xC1, 0x44, 0xE9, 0xC6, 0xC4, 0xF6,
+        0x4C, 0x29, 0xC0, 0x1C, 0x3E, 0x11, 0x83, 0x9C,
+        0x97, 0xD6, 0xE7, 0xD2, 0xBC, 0x0C, 0x5D, 0xBC,
+        0x68, 0x37, 0x7B, 0x67, 0x9A, 0xE5, 0x1D, 0x4D,
+        0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x01, 0x05, 0x07, 0x00, 0x00, 0x00, 0x08,
+        0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x31,
+        0x42, 0x01, 0x06, 0x07, 0x00, 0x00, 0x00, 0x08,
+        0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x31,
+        0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+    };
+
+    KMIP ctx = {0};
+    kmip_init(&ctx, encoding, ARRAY_LENGTH(encoding), KMIP_2_0);
+
+    ProtocolVersion pv = {0};
+    pv.major = 2;
+    pv.minor = 0;
+
+    uint8 id[4] = {0x01, 0x02, 0x03, 0x04};
+    ByteString ni = {0};
+    ni.value = id;
+    ni.size = ARRAY_LENGTH(id);
+
+    uint8 value[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+    ByteString nv = {0};
+    nv.value = value;
+    nv.size = ARRAY_LENGTH(value);
+
+    Nonce n = {0};
+    n.nonce_id = &ni;
+    n.nonce_value = &nv;
+
+    uint8 hash[32] = {
+        0x30, 0x1E, 0xC1, 0x44, 0xE9, 0xC6, 0xC4, 0xF6,
+        0x4C, 0x29, 0xC0, 0x1C, 0x3E, 0x11, 0x83, 0x9C,
+        0x97, 0xD6, 0xE7, 0xD2, 0xBC, 0x0C, 0x5D, 0xBC,
+        0x68, 0x37, 0x7B, 0x67, 0x9A, 0xE5, 0x1D, 0x4D
+    };
+    ByteString shp = {0};
+    shp.value = hash;
+    shp.size = ARRAY_LENGTH(hash);
+
+    enum attestation_type types[2] = {
+        KMIP_ATTEST_TPM_QUOTE,
+        KMIP_ATTEST_SAML_ASSERTION
+    };
+
+    TextString ccv = {0};
+    ccv.value = "client 1";
+    ccv.size = 8;
+
+    TextString scv = {0};
+    scv.value = "server 1";
+    scv.size = 8;
+
+    ResponseHeader expected = {0};
+    kmip_init_response_header(&expected);
+
+    expected.protocol_version = &pv;
+    expected.time_stamp = 1335514341;
+    expected.nonce = &n;
+    expected.server_hashed_password = &shp;
+    expected.attestation_types = types;
+    expected.attestation_type_count = ARRAY_LENGTH(types);
+    expected.batch_count = 1;
+
+    expected.client_correlation_value = &ccv;
+    expected.server_correlation_value = &scv;
+
+    ResponseHeader observed = {0};
+    kmip_init_response_header(&observed);
+
+    int result = kmip_decode_response_header(&ctx, &observed);
+    int comparison = kmip_compare_response_header(&expected, &observed);
+    if(!comparison)
+    {
+        /* TODO (ph) Reorder these with printing result so that objects are
+                     below function name.
+        */
+        kmip_print_response_header(1, &expected);
+        kmip_print_response_header(1, &observed);
+    }
+    result = report_decoding_test_result(tracker, &ctx, comparison, result, __func__);
+
+    kmip_free_response_header(&ctx, &observed);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+/*
+The following tests are taken verbatim from the KMIP 1.1 Test Cases
+documentation, available here:
+
+http://docs.oasis-open.org/kmip/testcases/v1.1/kmip-testcases-v1.1.html
+*/
+
+int
+test_kmip_1_1_test_suite_3_1_1_0_a(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* KMIP 1.1 Test Suite - Test 3.1.1.0a */
+    uint8 expected[296] = {
+        0x42, 0x00, 0x78, 0x01, 0x00, 0x00, 0x01, 0x20, 
+        0x42, 0x00, 0x77, 0x01, 0x00, 0x00, 0x00, 0x38, 
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0xD8, 
+        0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0xC0, 
+        0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x91, 0x01, 0x00, 0x00, 0x00, 0xA8, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x17, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x41, 0x6C, 
+        0x67, 0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x00, 
+        0x42, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x14, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x4C, 0x65, 
+        0x6E, 0x67, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x0A, 0x07, 0x00, 0x00, 0x00, 0x18, 
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6F, 0x67, 0x72, 
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x55, 0x73, 
+        0x61, 0x67, 0x65, 0x20, 0x4D, 0x61, 0x73, 0x6B, 
+        0x42, 0x00, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[296] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_1);
+    
+    /* TODO (ph) If protocol version omitted, pull from context? */
+    struct protocol_version pv = {0};
+    pv.major = 1;
+    pv.minor = 1;
+    
+    struct request_header rh = {0};
+    kmip_init_request_header(&rh);
+    
+    rh.protocol_version = &pv;
+    rh.batch_count = 1;
+    
+    struct attribute a[3] = {0};
+    for(int i = 0; i < 3; i++)
+    {
+        kmip_init_attribute(&a[i]);
+    }
+    
+    enum cryptographic_algorithm algorithm = KMIP_CRYPTOALG_AES;
+    a[0].type = KMIP_ATTR_CRYPTOGRAPHIC_ALGORITHM;
+    a[0].value = &algorithm;
+    
+    int32 length = 128;
+    a[1].type = KMIP_ATTR_CRYPTOGRAPHIC_LENGTH;
+    a[1].value = &length;
+    
+    int32 mask = KMIP_CRYPTOMASK_ENCRYPT | KMIP_CRYPTOMASK_DECRYPT;
+    a[2].type = KMIP_ATTR_CRYPTOGRAPHIC_USAGE_MASK;
+    a[2].value = &mask;
+    
+    struct template_attribute ta = {0};
+    ta.attributes = a;
+    ta.attribute_count = ARRAY_LENGTH(a);
+    
+    struct create_request_payload crp = {0};
+    crp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY;
+    crp.template_attribute = &ta;
+    
+    struct request_batch_item rbi = {0};
+    kmip_init_request_batch_item(&rbi);
+    rbi.operation = KMIP_OP_CREATE;
+    rbi.request_payload = &crp;
+    
+    struct request_message rm = {0};
+    rm.request_header = &rh;
+    rm.batch_items = &rbi;
+    rm.batch_count = 1;
+    
+    int result = kmip_encode_request_message(&ctx, &rm);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_kmip_1_1_test_suite_3_1_1_0_b(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* KMIP 1.1 Test Suite - Test 3.1.1.0b */
+    uint8 expected[200] = {
+        0x42, 0x00, 0x7B, 0x01, 0x00, 0x00, 0x00, 0xC0, 
+        0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, 
+        0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE5, 
+        0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x68, 
+        0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x7F, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x40, 
+        0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, 
+        0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, 
+        0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, 
+        0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, 
+        0x32, 0x39, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[200] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_0);
+    
+    struct protocol_version pv = {0};
+    pv.major = 1;
+    pv.minor = 1;
+    
+    struct response_header rh = {0};
+    kmip_init_response_header(&rh);
+    
+    rh.protocol_version = &pv;
+    rh.time_stamp = 1335514341;
+    rh.batch_count = 1;
+    
+    struct text_string uuid = {0};
+    uuid.value = "fb4b5b9c-6188-4c63-8142-fe9c328129fc";
+    uuid.size = 36;
+    
+    struct create_response_payload crp = {0};
+    crp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY;
+    crp.unique_identifier = &uuid;
+    
+    struct response_batch_item rbi = {0};
+    rbi.operation = KMIP_OP_CREATE;
+    rbi.result_status = KMIP_STATUS_SUCCESS;
+    rbi.response_payload = &crp;
+    
+    struct response_message rm = {0};
+    rm.response_header = &rh;
+    rm.batch_items = &rbi;
+    rm.batch_count = 1;
+    
+    int result = kmip_encode_response_message(&ctx, &rm);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_kmip_1_1_test_suite_3_1_1_1_a(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* KMIP 1.1 Test Suite - Test 3.1.1.1a */
+    uint8 expected[152] = {
+        0x42, 0x00, 0x78, 0x01, 0x00, 0x00, 0x00, 0x90, 
+        0x42, 0x00, 0x77, 0x01, 0x00, 0x00, 0x00, 0x38, 
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, 
+        0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, 
+        0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, 
+        0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, 
+        0x32, 0x39, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[152] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_1);
+    
+    struct protocol_version pv = {0};
+    pv.major = 1;
+    pv.minor = 1;
+    
+    struct request_header rh = {0};
+    kmip_init_request_header(&rh);
+    
+    rh.protocol_version = &pv;
+    rh.batch_count = 1;
+    
+    struct text_string uuid = {0};
+    uuid.value = "fb4b5b9c-6188-4c63-8142-fe9c328129fc";
+    uuid.size = 36;
+    
+    struct destroy_request_payload drp = {0};
+    drp.unique_identifier = &uuid;
+    
+    struct request_batch_item rbi = {0};
+    kmip_init_request_batch_item(&rbi);
+    rbi.operation = KMIP_OP_DESTROY;
+    rbi.request_payload = &drp;
+    
+    struct request_message rm = {0};
+    rm.request_header = &rh;
+    rm.batch_items = &rbi;
+    rm.batch_count = 1;
+    
+    int result = kmip_encode_request_message(&ctx, &rm);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_kmip_1_1_test_suite_3_1_1_1_b(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* KMIP 1.1 Test Suite - Test 3.1.1.1b */
+    uint8 expected[184] = {
+        0x42, 0x00, 0x7B, 0x01, 0x00, 0x00, 0x00, 0xB0, 
+        0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, 
+        0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE5, 
+        0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x58, 
+        0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x7F, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x66, 0x62, 0x34, 0x62, 0x35, 0x62, 0x39, 0x63, 
+        0x2D, 0x36, 0x31, 0x38, 0x38, 0x2D, 0x34, 0x63, 
+        0x36, 0x33, 0x2D, 0x38, 0x31, 0x34, 0x32, 0x2D, 
+        0x66, 0x65, 0x39, 0x63, 0x33, 0x32, 0x38, 0x31, 
+        0x32, 0x39, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[184] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_1);
+    
+    struct protocol_version pv = {0};
+    pv.major = 1;
+    pv.minor = 1;
+    
+    struct response_header rh = {0};
+    kmip_init_response_header(&rh);
+    
+    rh.protocol_version = &pv;
+    rh.time_stamp = 1335514341;
+    rh.batch_count = 1;
+    
+    struct text_string uuid = {0};
+    uuid.value = "fb4b5b9c-6188-4c63-8142-fe9c328129fc";
+    uuid.size = 36;
+    
+    struct destroy_response_payload drp = {0};
+    drp.unique_identifier = &uuid;
+    
+    struct response_batch_item rbi = {0};
+    rbi.operation = KMIP_OP_DESTROY;
+    rbi.result_status = KMIP_STATUS_SUCCESS;
+    rbi.response_payload = &drp;
+    
+    struct response_message rm = {0};
+    rm.response_header = &rh;
+    rm.batch_items = &rbi;
+    rm.batch_count = 1;
+    
+    int result = kmip_encode_response_message(&ctx, &rm);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_kmip_1_1_test_suite_3_1_3_2_a(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    /* KMIP 1.1 Test Suite - Test 3.1.3.2a */
+    uint8 expected[152] = {
+        0x42, 0x00, 0x78, 0x01, 0x00, 0x00, 0x00, 0x90, 
+        0x42, 0x00, 0x77, 0x01, 0x00, 0x00, 0x00, 0x38, 
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x79, 0x01, 0x00, 0x00, 0x00, 0x30, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x34, 0x39, 0x61, 0x31, 0x63, 0x61, 0x38, 0x38, 
+        0x2D, 0x36, 0x62, 0x65, 0x61, 0x2D, 0x34, 0x66, 
+        0x62, 0x32, 0x2D, 0x62, 0x34, 0x35, 0x30, 0x2D, 
+        0x37, 0x65, 0x35, 0x38, 0x38, 0x30, 0x32, 0x63, 
+        0x33, 0x30, 0x33, 0x38, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[152] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_1);
+    
+    struct protocol_version pv = {0};
+    pv.major = 1;
+    pv.minor = 1;
+    
+    struct request_header rh = {0};
+    kmip_init_request_header(&rh);
+    
+    rh.protocol_version = &pv;
+    rh.batch_count = 1;
+    
+    struct text_string uuid = {0};
+    uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038";
+    uuid.size = 36;
+    
+    struct get_request_payload grp = {0};
+    grp.unique_identifier = &uuid;
+    
+    struct request_batch_item rbi = {0};
+    kmip_init_request_batch_item(&rbi);
+    rbi.operation = KMIP_OP_GET;
+    rbi.request_payload = &grp;
+    
+    struct request_message rm = {0};
+    rm.request_header = &rh;
+    rm.batch_items = &rbi;
+    rm.batch_count = 1;
+    
+    int result = kmip_encode_request_message(&ctx, &rm);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+int
+test_kmip_1_1_test_suite_3_1_3_2_b(TestTracker *tracker)
+{
+    TRACK_TEST(tracker);
+
+    uint8 expected[304] = {
+        0x42, 0x00, 0x7B, 0x01, 0x00, 0x00, 0x01, 0x28, 
+        0x42, 0x00, 0x7A, 0x01, 0x00, 0x00, 0x00, 0x48, 
+        0x42, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x6B, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, 
+        0x00, 0x00, 0x00, 0x00, 0x4F, 0x9A, 0x54, 0xE7, 
+        0x42, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x42, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0xD0, 
+        0x42, 0x00, 0x5C, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x7F, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0xA8, 
+        0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x24, 
+        0x34, 0x39, 0x61, 0x31, 0x63, 0x61, 0x38, 0x38, 
+        0x2D, 0x36, 0x62, 0x65, 0x61, 0x2D, 0x34, 0x66, 
+        0x62, 0x32, 0x2D, 0x62, 0x34, 0x35, 0x30, 0x2D, 
+        0x37, 0x65, 0x35, 0x38, 0x38, 0x30, 0x32, 0x63, 
+        0x33, 0x30, 0x33, 0x38, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x60, 
+        0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x58, 
+        0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x20, 
+        0x42, 0x00, 0x43, 0x08, 0x00, 0x00, 0x00, 0x18, 
+        0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, 
+        0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, 
+        0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8, 
+        0x42, 0x00, 0x28, 0x05, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
+        0x42, 0x00, 0x2A, 0x02, 0x00, 0x00, 0x00, 0x04, 
+        0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x00
+    };
+    
+    uint8 observed[304] = {0};
+    struct kmip ctx = {0};
+    kmip_init(&ctx, observed, ARRAY_LENGTH(observed), KMIP_1_1);
+    
+    struct protocol_version pv = {0};
+    pv.major = 1;
+    pv.minor = 1;
+    
+    struct response_header rh = {0};
+    kmip_init_response_header(&rh);
+    
+    rh.protocol_version = &pv;
+    rh.time_stamp = 1335514343;
+    rh.batch_count = 1;
+    
+    struct text_string uuid = {0};
+    uuid.value = "49a1ca88-6bea-4fb2-b450-7e58802c3038";
+    uuid.size = 36;
+    
+    uint8 value[24] = {
+        0x73, 0x67, 0x57, 0x80, 0x51, 0x01, 0x2A, 0x6D, 
+        0x13, 0x4A, 0x85, 0x5E, 0x25, 0xC8, 0xCD, 0x5E, 
+        0x4C, 0xA1, 0x31, 0x45, 0x57, 0x29, 0xD3, 0xC8
+    };
+
+    struct byte_string v = {0};
+    v.value = value;
+    v.size = ARRAY_LENGTH(value);
+    
+    struct key_value kv = {0};
+    kv.key_material = &v;
+    
+    struct key_block kb = {0};
+    kb.key_format_type = KMIP_KEYFORMAT_RAW;
+    kb.key_value = &kv;
+    kb.cryptographic_algorithm = KMIP_CRYPTOALG_TRIPLE_DES;
+    kb.cryptographic_length = 168;
+    
+    struct symmetric_key key = {0};
+    key.key_block = &kb;
+    
+    struct get_response_payload grp = {0};
+    grp.object_type = KMIP_OBJTYPE_SYMMETRIC_KEY;
+    grp.unique_identifier = &uuid;
+    grp.object = &key;
+    
+    struct response_batch_item rbi = {0};
+    rbi.operation = KMIP_OP_GET;
+    rbi.result_status = KMIP_STATUS_SUCCESS;
+    rbi.response_payload = &grp;
+    
+    struct response_message rm = {0};
+    rm.response_header = &rh;
+    rm.batch_items = &rbi;
+    rm.batch_count = 1;
+    
+    int result = kmip_encode_response_message(&ctx, &rm);
+    result = report_encoding_test_result(
+        tracker,
+        &ctx,
+        expected,
+        observed,
+        result,
+        __func__);
+    kmip_destroy(&ctx);
+    return(result);
+}
+
+/* Test Harness */
+
+int
+run_tests(void)
+{
+    TestTracker tracker = {0};
+    
+    printf("Tests\n");
+    printf("=====\n");
+    
+    printf("\nUtility Tests\n");
+    printf("-------------\n");
+    test_linked_list_pop(&tracker);
+    test_linked_list_push(&tracker);
+    test_linked_list_enqueue(&tracker);
+    test_buffer_bytes_left(&tracker);
+    test_peek_tag(&tracker);
+    test_is_attribute_tag(&tracker);
+    test_get_enum_string_index(&tracker);
+    test_check_enum_value_protection_storage_masks(&tracker);
+    test_init_protocol_version(&tracker);
+    test_init_request_batch_item(&tracker);
+    test_deep_copy_int32(&tracker);
+    test_deep_copy_text_string(&tracker);
+    test_deep_copy_name(&tracker);
+    test_deep_copy_attribute(&tracker);
+
+    printf("\nKMIP 1.0 Feature Tests\n");
+    printf("----------------------\n");
+    test_buffer_full_and_resize(&tracker);
+    test_is_tag_next(&tracker);
+    test_get_num_items_next(&tracker);
+    test_get_num_items_next_with_partial_item(&tracker);
+    test_get_num_items_next_with_mismatch_item(&tracker);
+    test_get_num_items_next_with_no_matches(&tracker);
+    test_get_num_items_next_with_non_structures(&tracker);
+    
+    printf("\n");
+    test_decode_int8_be(&tracker);
+    test_decode_int32_be(&tracker);
+    test_decode_int64_be(&tracker);
+    test_decode_integer(&tracker);
+    test_decode_long(&tracker);
+    test_decode_enum(&tracker);
+    test_decode_bool(&tracker);
+    test_decode_text_string(&tracker);
+    test_decode_byte_string(&tracker);
+    test_decode_date_time(&tracker);
+    test_decode_interval(&tracker);
+    test_decode_name(&tracker);
+    test_decode_attribute_unique_identifier(&tracker);
+    test_decode_attribute_name(&tracker);
+    test_decode_attribute_object_type(&tracker);
+    test_decode_attribute_cryptographic_algorithm(&tracker);
+    test_decode_attribute_cryptographic_length(&tracker);
+    test_decode_attribute_operation_policy_name(&tracker);
+    test_decode_attribute_cryptographic_usage_mask(&tracker);
+    test_decode_attribute_state(&tracker);
+    test_decode_template_attribute(&tracker);
+    test_decode_protocol_version(&tracker);
+    test_decode_key_material_byte_string(&tracker);
+    test_decode_key_material_transparent_symmetric_key(&tracker);
+    test_decode_key_value(&tracker);
+    test_decode_key_value_with_attributes(&tracker);
+    test_decode_cryptographic_parameters(&tracker);
+    test_decode_encryption_key_information(&tracker);
+    test_decode_mac_signature_key_information(&tracker);
+    test_decode_key_wrapping_data(&tracker);
+    test_decode_key_block_key_value_byte_string(&tracker);
+    test_decode_key_block_key_value_structure(&tracker);
+    test_decode_symmetric_key(&tracker);
+    test_decode_public_key(&tracker);
+    test_decode_private_key(&tracker);
+    test_decode_key_wrapping_specification(&tracker);
+    test_decode_create_request_payload(&tracker);
+    test_decode_create_response_payload(&tracker);
+    test_decode_create_response_payload_with_template_attribute(&tracker);
+    test_decode_get_request_payload(&tracker);
+    test_decode_get_response_payload(&tracker);
+    test_decode_destroy_request_payload(&tracker);
+    test_decode_destroy_response_payload(&tracker);
+    test_decode_response_batch_item_get_payload(&tracker);
+    test_decode_username_password_credential(&tracker);
+    test_decode_credential_username_password_credential(&tracker);
+    test_decode_authentication_username_password_credential(&tracker);
+    test_decode_request_header(&tracker);
+    test_decode_response_header(&tracker);
+    test_decode_request_batch_item_get_payload(&tracker);
+    test_decode_request_message_get(&tracker);
+    test_decode_response_message_get(&tracker);
+    
+    printf("\n");
+    test_encode_integer(&tracker);
+    test_encode_long(&tracker);
+    test_encode_enum(&tracker);
+    test_encode_bool(&tracker);
+    test_encode_text_string(&tracker);
+    test_encode_byte_string(&tracker);
+    test_encode_date_time(&tracker);
+    test_encode_interval(&tracker);
+    test_encode_name(&tracker);
+    test_encode_attribute_unique_identifier(&tracker);
+    test_encode_attribute_name(&tracker);
+    test_encode_attribute_object_type(&tracker);
+    test_encode_attribute_cryptographic_algorithm(&tracker);
+    test_encode_attribute_cryptographic_length(&tracker);
+    test_encode_attribute_operation_policy_name(&tracker);
+    test_encode_attribute_cryptographic_usage_mask(&tracker);
+    test_encode_attribute_state(&tracker);
+    test_encode_protocol_version(&tracker);
+    test_encode_cryptographic_parameters(&tracker);
+    test_encode_encryption_key_information(&tracker);
+    test_encode_mac_signature_key_information(&tracker);
+    test_encode_key_wrapping_data(&tracker);
+    test_encode_key_material_byte_string(&tracker);
+    test_encode_key_material_transparent_symmetric_key(&tracker);
+    test_encode_key_value(&tracker);
+    test_encode_key_value_with_attributes(&tracker);
+    test_encode_key_block_key_value_byte_string(&tracker);
+    test_encode_key_block_key_value_structure(&tracker);
+    test_encode_symmetric_key(&tracker);
+    test_encode_public_key(&tracker);
+    test_encode_private_key(&tracker);
+    test_encode_key_wrapping_specification(&tracker);
+    test_encode_create_request_payload(&tracker);
+    test_encode_create_response_payload(&tracker);
+    test_encode_create_response_payload_with_template_attribute(&tracker);
+    test_encode_get_request_payload(&tracker);
+    test_encode_get_request_payload_with_format_compression(&tracker);
+    test_encode_get_request_payload_with_wrapping_spec(&tracker);
+    test_encode_get_response_payload(&tracker);
+    test_encode_destroy_request_payload(&tracker);
+    test_encode_destroy_response_payload(&tracker);
+    test_encode_username_password_credential(&tracker);
+    test_encode_credential_username_password_credential(&tracker);
+    test_encode_authentication_username_password_credential(&tracker);
+    test_encode_request_header(&tracker);
+    test_encode_response_header(&tracker);
+    test_encode_request_batch_item_get_payload(&tracker);
+    test_encode_response_batch_item_get_payload(&tracker);
+    test_encode_request_message_get(&tracker);
+    test_encode_response_message_get(&tracker);
+    test_encode_template_attribute(&tracker);
+    
+    printf("\nKMIP 1.1 Feature Tests\n");
+    printf("----------------------\n");
+    test_decode_device_credential(&tracker);
+    test_decode_key_wrapping_data_with_encoding_option(&tracker);
+    
+    printf("\n");
+    test_encode_device_credential(&tracker);
+    test_encode_key_wrapping_data_with_encoding_option(&tracker);
+    test_encode_key_wrapping_specification_with_encoding_option(&tracker);
+    
+    printf("\nKMIP 1.1 Test Suite Test Cases\n");
+    printf("------------------------------\n");
+    test_kmip_1_1_test_suite_3_1_1_0_a(&tracker);
+    test_kmip_1_1_test_suite_3_1_1_0_b(&tracker);
+    test_kmip_1_1_test_suite_3_1_1_1_a(&tracker);
+    test_kmip_1_1_test_suite_3_1_1_1_b(&tracker);
+    test_kmip_1_1_test_suite_3_1_3_2_a(&tracker);
+    test_kmip_1_1_test_suite_3_1_3_2_b(&tracker);
+    
+    printf("\nKMIP 1.2 Feature Tests\n");
+    printf("----------------------\n");
+    test_decode_nonce(&tracker);
+    test_decode_attestation_credential(&tracker);
+    test_decode_response_header_with_attestation_details(&tracker);
+    test_decode_cryptographic_parameters_with_digital_signature_fields(&tracker);
+    
+    printf("\n");
+    test_encode_nonce(&tracker);
+    test_encode_attestation_credential(&tracker);
+    test_encode_request_header_with_attestation_details(&tracker);
+    test_encode_response_header_with_attestation_details(&tracker);
+    test_encode_cryptographic_parameters_with_digital_signature_fields(&tracker);
+    
+    printf("\nKMIP 1.4 Feature Tests\n");
+    printf("----------------------\n");
+    test_decode_cryptographic_parameters_with_mask_fields(&tracker);
+    test_decode_response_header_with_correlation_values(&tracker);
+    
+    printf("\n");
+    test_encode_cryptographic_parameters_with_mask_fields(&tracker);
+    test_encode_get_request_payload_with_wrap_type(&tracker);
+    test_encode_request_header_with_correlation_values(&tracker);
+    test_encode_response_header_with_correlation_values(&tracker);
+    
+    printf("\nKMIP 2.0 Feature Tests\n");
+    printf("----------------------\n");
+    test_decode_protection_storage_masks(&tracker);
+    test_decode_attributes(&tracker);
+    test_decode_attributes_with_invalid_kmip_version(&tracker);
+    test_decode_attribute_v2_unique_identifier(&tracker);
+    test_decode_attribute_v2_name(&tracker);
+    test_decode_attribute_v2_object_type(&tracker);
+    test_decode_attribute_v2_cryptographic_algorithm(&tracker);
+    test_decode_attribute_v2_cryptographic_length(&tracker);
+    test_decode_attribute_v2_cryptographic_usage_mask(&tracker);
+    test_decode_attribute_v2_state(&tracker);
+    test_decode_attribute_v2_unsupported_attribute(&tracker);
+    test_decode_create_request_payload_kmip_2_0(&tracker);
+    test_decode_request_batch_item_get_payload_kmip_2_0(&tracker);
+    test_decode_response_header_kmip_2_0(&tracker);
+
+    printf("\n");
+    test_encode_protection_storage_masks(&tracker);
+    test_encode_attributes(&tracker);
+    test_encode_attributes_with_invalid_kmip_version(&tracker);
+    test_encode_attribute_v2_unique_identifier(&tracker);
+    test_encode_attribute_v2_name(&tracker);
+    test_encode_attribute_v2_object_type(&tracker);
+    test_encode_attribute_v2_cryptographic_algorithm(&tracker);
+    test_encode_attribute_v2_cryptographic_length(&tracker);
+    test_encode_attribute_v2_cryptographic_usage_mask(&tracker);
+    test_encode_attribute_v2_state(&tracker);
+    test_encode_attribute_v2_unsupported_attribute(&tracker);
+    test_encode_create_request_payload_kmip_2_0(&tracker);
+    test_encode_request_batch_item_get_payload_kmip_2_0(&tracker);
+    test_encode_response_header_kmip_2_0(&tracker);
+
+    printf("\nSummary\n");
+    printf("================\n");
+    printf("Total tests: %u\n", tracker.test_count);
+    printf("       PASS: %u\n", tracker.tests_passed);
+    printf("    FAILURE: %u\n", tracker.tests_failed);
+
+    return(tracker.tests_failed);
+}
+
+void
+print_help(const char *app)
+{
+    printf("Usage: %s [flag] ...\n\n", app);
+    printf("Flags:\n");
+    printf("-h : print this help info\n");
+    printf("-i : run the test suite forever\n");
+}
+
+int
+parse_arguments(int argc,
+                char **argv,
+                int *print_usage,
+                int *run_forever)
+{
+    for(int i = 1; i < argc; i++)
+    {
+        if(strncmp(argv[i], "-h", 2) == 0)
+        {
+            *print_usage = 1;
+        }
+        else if(strncmp(argv[i], "-i", 2) == 0)
+        {
+            *run_forever = 1;
+        }
+        else
+        {
+            printf("Invalid option: '%s'\n", argv[i]);
+            print_help(argv[0]);
+            return(-1);
+        }
+    }
+    
+    return(0);
+}
+
+int
+main(int argc, char **argv)
+{
+    int print_usage = 0;
+    int run_forever = 0;
+    
+    int error = parse_arguments(argc, argv, &print_usage, &run_forever);
+    if(error)
+    {
+        return(error);
+    }
+    if(print_usage)
+    {
+        print_help(argv[0]);
+        return(0);
+    }
+    
+    int results = 0;
+    if(run_forever)
+    {
+        while(1)
+        {
+            run_tests();
+        }
+    }
+    else
+    {
+        results = run_tests();
+    }
+
+    return(results);
+}