/* * Demo on how to use /dev/crypto device for HMAC. * * Placed under public domain. * */ #include #include #include #include #include #include #include #include #include #include #include #include "../ncr.h" #include #define DATA_SIZE 4096 #define ALIGN_NL __attribute__((aligned(NLA_ALIGNTO))) #define ALG_AES_CBC "cbc(aes)" #define ALG_AES_ECB "ecb(aes)" static void randomize_data(uint8_t * data, size_t data_size) { int i; srand(time(0)*getpid()); for (i=0;inla_type = NCR_ATTR_WANTED_ATTRS; attr_p = (uint16_t *)((char *)nla + NLA_HDRLEN); *attr_p++ = NCR_ATTR_ALGORITHM; *attr_p++ = NCR_ATTR_KEY_FLAGS; *attr_p++ = NCR_ATTR_KEY_TYPE; nla->nla_len = (char *)attr_p - (char *)nla; kinfo.f.input_size = (char *)attr_p - (char *)&kinfo; if (ioctl(cfd, NCRIO_KEY_GET_INFO, &kinfo)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_GET_INFO)"); return 1; } got_algo = got_flags = got_type = 0; if (kinfo.f.output_size < (char *)&kinfo.u.first_header - (char *)&kinfo) { fprintf(stderr, "No nlattr returned\n"); return 1; } nla = &kinfo.u.first_header; for (;;) { void *data; if (nla->nla_len > kinfo.f.output_size - ((char *)nla - (char *)&kinfo)) { fprintf(stderr, "Attributes overflow\n"); return 1; } data = (char *)nla + NLA_HDRLEN; switch (nla->nla_type) { case NCR_ATTR_ALGORITHM: if (nla->nla_len < NLA_HDRLEN + 1) { fprintf(stderr, "Attribute too small\n"); return 1; } if (((char *)data)[nla->nla_len - NLA_HDRLEN - 1] != 0) { fprintf(stderr, "NUL missing\n"); return 1; } if (strcmp(data, ALG_AES_CBC) != 0) { fprintf(stderr, "Unexpected algorithm\n"); return 1; } got_algo++; break; case NCR_ATTR_KEY_FLAGS: if (nla->nla_len < NLA_HDRLEN + sizeof(uint32_t)) { fprintf(stderr, "Attribute too small\n"); return 1; } if (*(uint32_t *)data != NCR_KEY_FLAG_EXPORTABLE) { fprintf(stderr, "Unexpected key flags\n"); return 1; } got_flags++; break; case NCR_ATTR_KEY_TYPE: if (nla->nla_len < NLA_HDRLEN + sizeof(uint32_t)) { fprintf(stderr, "Attribute too small\n"); return 1; } if (*(uint32_t *)data != NCR_KEY_TYPE_SECRET) { fprintf(stderr, "Unexpected key type\n"); return 1; } got_type++; break; } if (NLA_ALIGN(nla->nla_len) + NLA_HDRLEN > kinfo.f.output_size - ((char *)nla - (char *)&kinfo)) break; nla = (struct nlattr *)((char *)nla + NLA_ALIGN(nla->nla_len)); } if (got_algo != 1 || got_flags != 1 || got_type != 1) { fprintf(stderr, "Unexpected attrs - %d, %d, %d\n", got_algo, got_flags, got_type); return 1; } if (ioctl(cfd, NCRIO_KEY_DEINIT, &key)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_DEINIT)"); return 1; } /* test 3: generate an unexportable key in kernel space and * try to export it. */ fprintf(stdout, "\tKey protection of non-exportable keys...\n"); key = ioctl(cfd, NCRIO_KEY_INIT); if (key == -1) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_INIT)"); return 1; } memset(&kgen.f, 0, sizeof(kgen.f)); kgen.f.input_size = sizeof(kgen); kgen.f.key = key; kgen.algo_head.nla_len = NLA_HDRLEN + sizeof(kgen.algo); kgen.algo_head.nla_type = NCR_ATTR_ALGORITHM; strcpy(kgen.algo, ALG_AES_CBC); kgen.flags_head.nla_len = NLA_HDRLEN + sizeof(kgen.flags); kgen.flags_head.nla_type = NCR_ATTR_KEY_FLAGS; kgen.flags = 0; kgen.bits_head.nla_len = NLA_HDRLEN + sizeof(kgen.flags); kgen.bits_head.nla_type = NCR_ATTR_SECRET_KEY_BITS; kgen.bits = 128; /* 16 bytes */ if (ioctl(cfd, NCRIO_KEY_GENERATE, &kgen)) { perror("ioctl(NCRIO_KEY_GENERATE)"); return 1; } memset(data, 0, sizeof(data)); memset(&kexport, 0, sizeof(kexport)); kexport.key = key; kexport.buffer = data; kexport.buffer_size = sizeof(data); /* try to get the output data - should fail */ if (ioctl(cfd, NCRIO_KEY_EXPORT, &kexport) >= 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); fprintf(stderr, "Data were exported, but shouldn't be!\n"); return 1; } if (ioctl(cfd, NCRIO_KEY_DEINIT, &key)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_DEINIT)"); return 1; } return 0; } /* Key wrapping */ static int test_ncr_wrap_key(int cfd) { int i, ret; ncr_key_t key, key2; struct __attribute__((packed)) { struct ncr_key_import f; struct nlattr id_head ALIGN_NL; uint8_t id[2] ALIGN_NL; struct nlattr type_head ALIGN_NL; uint32_t type ALIGN_NL; struct nlattr algo_head ALIGN_NL; char algo[sizeof(ALG_AES_CBC)] ALIGN_NL; struct nlattr flags_head ALIGN_NL; uint32_t flags ALIGN_NL; } kimport; struct __attribute__((packed)) { struct ncr_key_wrap f; struct nlattr algo_head ALIGN_NL; char algo[sizeof(NCR_WALG_AES_RFC3394)] ALIGN_NL; } kwrap; struct __attribute__((packed)) { struct ncr_key_unwrap f; struct nlattr wrap_algo_head ALIGN_NL; char wrap_algo[sizeof(NCR_WALG_AES_RFC3394)] ALIGN_NL; struct nlattr flags_head ALIGN_NL; uint32_t flags ALIGN_NL; } kunwrap; uint8_t data[WRAPPED_KEY_DATA_SIZE]; int data_size; fprintf(stdout, "Tests on Keys:\n"); /* test 1: generate a key in userspace import it * to kernel via data and export it. */ fprintf(stdout, "\tKey Wrap test...\n"); /* convert it to key */ key = ioctl(cfd, NCRIO_KEY_INIT); if (key == -1) { perror("ioctl(NCRIO_KEY_INIT)"); return 1; } memset(&kimport.f, 0, sizeof(kimport.f)); kimport.f.input_size = sizeof(kimport); kimport.f.key = key; kimport.f.data = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; kimport.f.data_size = 16; kimport.id_head.nla_len = NLA_HDRLEN + sizeof(kimport.id); kimport.id_head.nla_type = NCR_ATTR_KEY_ID; kimport.id[0] = 'a'; kimport.id[1] = 'b'; kimport.type_head.nla_len = NLA_HDRLEN + sizeof(kimport.type); kimport.type_head.nla_type = NCR_ATTR_KEY_TYPE; kimport.type = NCR_KEY_TYPE_SECRET; kimport.algo_head.nla_len = NLA_HDRLEN + sizeof(kimport.algo); kimport.algo_head.nla_type = NCR_ATTR_ALGORITHM; strcpy(kimport.algo, ALG_AES_CBC); kimport.flags_head.nla_len = NLA_HDRLEN + sizeof(kimport.flags); kimport.flags_head.nla_type = NCR_ATTR_KEY_FLAGS; kimport.flags = NCR_KEY_FLAG_EXPORTABLE|NCR_KEY_FLAG_WRAPPING|NCR_KEY_FLAG_UNWRAPPING; ret = ioctl(cfd, NCRIO_KEY_IMPORT, &kimport); if (geteuid() == 0 && ret) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_IMPORT)"); return 1; } if (geteuid() != 0) { /* cannot test further */ fprintf(stdout, "\t(Wrapping test not completed. Run as root)\n"); return 0; } /* convert it to key */ key2 = ioctl(cfd, NCRIO_KEY_INIT); if (key2 == -1) { perror("ioctl(NCRIO_KEY_INIT)"); return 1; } memset(&kimport.f, 0, sizeof(kimport.f)); kimport.f.input_size = sizeof(kimport); kimport.f.key = key2; #define DKEY "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF" kimport.f.data = DKEY; kimport.f.data_size = 16; kimport.id_head.nla_len = NLA_HDRLEN + sizeof(kimport.id); kimport.id_head.nla_type = NCR_ATTR_KEY_ID; kimport.id[0] = 'b'; kimport.id[1] = 'a'; kimport.type_head.nla_len = NLA_HDRLEN + sizeof(kimport.type); kimport.type_head.nla_type = NCR_ATTR_KEY_TYPE; kimport.type = NCR_KEY_TYPE_SECRET; kimport.algo_head.nla_len = NLA_HDRLEN + sizeof(kimport.algo); kimport.algo_head.nla_type = NCR_ATTR_ALGORITHM; strcpy(kimport.algo, ALG_AES_CBC); kimport.flags_head.nla_len = NLA_HDRLEN + sizeof(kimport.flags); kimport.flags_head.nla_type = NCR_ATTR_KEY_FLAGS; kimport.flags = NCR_KEY_FLAG_EXPORTABLE|NCR_KEY_FLAG_WRAPPABLE; if (ioctl(cfd, NCRIO_KEY_IMPORT, &kimport)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_IMPORT)"); return 1; } /* now try wrapping key2 using key */ memset(&kwrap.f, 0, sizeof(kwrap.f)); kwrap.f.input_size = sizeof(kwrap); kwrap.f.wrapping_key = key; kwrap.f.source_key = key2; kwrap.f.buffer = data; kwrap.f.buffer_size = sizeof(data); kwrap.algo_head.nla_len = NLA_HDRLEN + sizeof(kwrap.algo); kwrap.algo_head.nla_type = NCR_ATTR_WRAPPING_ALGORITHM; strcpy(kwrap.algo, NCR_WALG_AES_RFC3394); data_size = ioctl(cfd, NCRIO_KEY_WRAP, &kwrap); if (data_size < 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_WRAP)"); return 1; } if (data_size != 24 || memcmp(data, "\x1F\xA6\x8B\x0A\x81\x12\xB4\x47\xAE\xF3\x4B\xD8\xFB\x5A\x7B\x82\x9D\x3E\x86\x23\x71\xD2\xCF\xE5", 24) != 0) { fprintf(stderr, "Wrapped data do not match.\n"); fprintf(stderr, "Data[%d]: ",(int) data_size); for(i=0;i= 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); /* wrapping shouldn't have been allowed */ return 1; } return 0; } static int test_ncr_store_wrap_key(int cfd) { int i; ncr_key_t key2; struct __attribute__((packed)) { struct ncr_key_import f; struct nlattr id_head ALIGN_NL; uint8_t id[2] ALIGN_NL; struct nlattr type_head ALIGN_NL; uint32_t type ALIGN_NL; struct nlattr algo_head ALIGN_NL; char algo[sizeof(ALG_AES_CBC)] ALIGN_NL; struct nlattr flags_head ALIGN_NL; uint32_t flags ALIGN_NL; } kimport; struct ncr_key_export kexport; struct ncr_key_storage_wrap kwrap; struct ncr_key_storage_unwrap kunwrap; uint8_t data[DATA_SIZE]; int data_size; fprintf(stdout, "Tests on Key storage:\n"); /* test 1: generate a key in userspace import it * to kernel via data and export it. */ fprintf(stdout, "\tKey Storage wrap test...\n"); /* convert it to key */ key2 = ioctl(cfd, NCRIO_KEY_INIT); if (key2 == -1) { perror("ioctl(NCRIO_KEY_INIT)"); return 1; } memset(&kimport.f, 0, sizeof(kimport.f)); kimport.f.input_size = sizeof(kimport); kimport.f.key = key2; #define DKEY "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF" kimport.f.data = DKEY; kimport.f.data_size = 16; kimport.id_head.nla_len = NLA_HDRLEN + sizeof(kimport.id); kimport.id_head.nla_type = NCR_ATTR_KEY_ID; kimport.id[0] = 'b'; kimport.id[1] = 'a'; kimport.type_head.nla_len = NLA_HDRLEN + sizeof(kimport.type); kimport.type_head.nla_type = NCR_ATTR_KEY_TYPE; kimport.type = NCR_KEY_TYPE_SECRET; kimport.algo_head.nla_len = NLA_HDRLEN + sizeof(kimport.algo); kimport.algo_head.nla_type = NCR_ATTR_ALGORITHM; strcpy(kimport.algo, ALG_AES_CBC); kimport.flags_head.nla_len = NLA_HDRLEN + sizeof(kimport.flags); kimport.flags_head.nla_type = NCR_ATTR_KEY_FLAGS; kimport.flags = NCR_KEY_FLAG_EXPORTABLE|NCR_KEY_FLAG_WRAPPABLE; if (ioctl(cfd, NCRIO_KEY_IMPORT, &kimport)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_IMPORT)"); return 1; } /* now try wrapping key2 using key */ memset(&kwrap, 0, sizeof(kwrap)); kwrap.key = key2; kwrap.buffer = data; kwrap.buffer_size = sizeof(data); data_size = ioctl(cfd, NCRIO_KEY_STORAGE_WRAP, &kwrap); if (data_size < 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_STORAGE_WRAP)"); return 1; } /* test unwrapping */ fprintf(stdout, "\tKey Storage Unwrap test...\n"); /* reset key2 */ if (ioctl(cfd, NCRIO_KEY_DEINIT, &key2)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_DEINIT)"); return 1; } key2 = ioctl(cfd, NCRIO_KEY_INIT); if (key2 == -1) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_INIT)"); return 1; } memset(&kunwrap, 0, sizeof(kunwrap)); kunwrap.key = key2; kunwrap.data = data; kunwrap.data_size = data_size; if (ioctl(cfd, NCRIO_KEY_STORAGE_UNWRAP, &kunwrap)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_STORAGE_UNWRAP)"); return 1; } /* now export the unwrapped */ memset(&kexport, 0, sizeof(kexport)); kexport.key = key2; kexport.buffer = data; kexport.buffer_size = sizeof(data); data_size = ioctl(cfd, NCRIO_KEY_EXPORT, &kexport); if (data_size != 16) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_EXPORT)"); return 1; } if (memcmp(data, DKEY, 16) != 0) { fprintf(stderr, "Unwrapped data do not match.\n"); fprintf(stderr, "Data[%d]: ", (int) data_size); for(i=0;ialgorithm) + 1; fprintf(stdout, "\t%s:\n", hv->algorithm); /* import key */ if (hv->key != NULL) { memset(&kimport.f, 0, sizeof(kimport.f)); kimport.f.key = key; kimport.f.data = hv->key; kimport.f.data_size = hv->key_size; kimport.id_head.nla_len = NLA_HDRLEN + sizeof(kimport.id); kimport.id_head.nla_type = NCR_ATTR_KEY_ID; kimport.id[0] = 'a'; kimport.id[1] = 'b'; kimport.type_head.nla_len = NLA_HDRLEN + sizeof(kimport.type); kimport.type_head.nla_type = NCR_ATTR_KEY_TYPE; kimport.type = NCR_KEY_TYPE_SECRET; kimport.flags_head.nla_len = NLA_HDRLEN + sizeof(kimport.flags); kimport.flags_head.nla_type = NCR_ATTR_KEY_FLAGS; kimport.flags = NCR_KEY_FLAG_EXPORTABLE; kimport.algo_head.nla_len = NLA_HDRLEN + algo_size; kimport.algo_head.nla_type = NCR_ATTR_ALGORITHM; memcpy(kimport.algo, hv->algorithm, algo_size); kimport.f.input_size = kimport.algo + algo_size - (char *)&kimport; if (ioctl(cfd, NCRIO_KEY_IMPORT, &kimport)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_IMPORT)"); return 1; } } /* Initialize a session */ memset(&kinit.f, 0, sizeof(kinit.f)); kinit.f.op = hv->op; kinit.key_head.nla_len = NLA_HDRLEN + sizeof(kinit.key); kinit.key_head.nla_type = NCR_ATTR_KEY; kinit.key = hv->key != NULL ? key : NCR_KEY_INVALID; kinit.algo_head.nla_len = NLA_HDRLEN + algo_size; kinit.algo_head.nla_type = NCR_ATTR_ALGORITHM; memcpy(kinit.algo, hv->algorithm, algo_size); kinit.f.input_size = kinit.algo + algo_size - (char *)&kinit; ses = ioctl(cfd, NCRIO_SESSION_INIT, &kinit); if (ses < 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_SESSION_INIT)"); return 1; } /* Submit half of the data */ memset(&kupdate.f, 0, sizeof(kupdate.f)); kupdate.f.input_size = sizeof(kupdate); kupdate.f.ses = ses; kupdate.input_head.nla_len = NLA_HDRLEN + sizeof(kupdate.input); kupdate.input_head.nla_type = NCR_ATTR_UPDATE_INPUT_DATA; kupdate.input.data = hv->plaintext; kupdate.input.data_size = hv->plaintext_size / 2; if (ioctl(cfd, NCRIO_SESSION_UPDATE, &kupdate)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_SESSION_UPDATE)"); return 1; } /* Clone a session, submit the other half, verify. */ memset(&kclone.f, 0, sizeof(kclone.f)); kclone.f.input_size = sizeof(kclone); kclone.f.op = hv->op; kclone.clone_head.nla_len = NLA_HDRLEN + sizeof(kclone.clone); kclone.clone_head.nla_type = NCR_ATTR_SESSION_CLONE_FROM; kclone.clone = ses; kclone.input_head.nla_len = NLA_HDRLEN + sizeof(kclone.input); kclone.input_head.nla_type = NCR_ATTR_UPDATE_INPUT_DATA; kclone.input.data = hv->plaintext + hv->plaintext_size / 2; kclone.input.data_size = hv->plaintext_size - hv->plaintext_size / 2; kclone.output_head.nla_len = NLA_HDRLEN + sizeof(kclone.output); kclone.output_head.nla_type = NCR_ATTR_FINAL_OUTPUT_BUFFER; kclone.output.buffer = data; kclone.output.buffer_size = sizeof(data); kclone.output.result_size_ptr = &data_size; if (ioctl(cfd, NCRIO_SESSION_ONCE, &kclone)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_SESSION_ONCE)"); return 1; } if (data_size != hv->output_size || memcmp(data, hv->output, hv->output_size) != 0) { fprintf(stderr, "HASH test vector %td failed!\n", hv - hash_vectors); fprintf(stderr, "Output[%zu]: ", data_size); for(j = 0; j < data_size; j++) fprintf(stderr, "%.2x:", (int)data[j]); fprintf(stderr, "\n"); fprintf(stderr, "Expected[%d]: ", hv->output_size); for (j = 0; j < hv->output_size; j++) fprintf(stderr, "%.2x:", (int)hv->output[j]); fprintf(stderr, "\n"); return 1; } /* Submit the other half to the original session, verify. */ memset(&kfinal.f, 0, sizeof(kfinal.f)); kfinal.f.input_size = sizeof(kfinal); kfinal.f.ses = ses; kfinal.input_head.nla_len = NLA_HDRLEN + sizeof(kfinal.input); kfinal.input_head.nla_type = NCR_ATTR_UPDATE_INPUT_DATA; kfinal.input.data = hv->plaintext + hv->plaintext_size / 2; kfinal.input.data_size = hv->plaintext_size - hv->plaintext_size / 2; kfinal.output_head.nla_len = NLA_HDRLEN + sizeof(kfinal.output); kfinal.output_head.nla_type = NCR_ATTR_FINAL_OUTPUT_BUFFER; kfinal.output.buffer = data; kfinal.output.buffer_size = sizeof(data); kfinal.output.result_size_ptr = &data_size; if (ioctl(cfd, NCRIO_SESSION_FINAL, &kfinal)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_SESSION_FINAL)"); return 1; } if (data_size != hv->output_size || memcmp(data, hv->output, hv->output_size) != 0) { fprintf(stderr, "HASH test vector %td failed!\n", hv - hash_vectors); fprintf(stderr, "Output[%zu]: ", data_size); for(j = 0; j < data_size; j++) fprintf(stderr, "%.2x:", (int)data[j]); fprintf(stderr, "\n"); fprintf(stderr, "Expected[%d]: ", hv->output_size); for (j = 0; j < hv->output_size; j++) fprintf(stderr, "%.2x:", (int)hv->output[j]); fprintf(stderr, "\n"); return 1; } } fprintf(stdout, "\n"); return 0; } static int test_ncr_hash_key(int cfd) { ncr_key_t key; ncr_session_t ses; struct __attribute__((packed)) { struct ncr_key_import f; struct nlattr id_head ALIGN_NL; uint8_t id[2] ALIGN_NL; struct nlattr type_head ALIGN_NL; uint32_t type ALIGN_NL; struct nlattr flags_head ALIGN_NL; uint32_t flags ALIGN_NL; struct nlattr algo_head ALIGN_NL; char algo[128] ALIGN_NL; } kimport; uint8_t data[HASH_DATA_SIZE]; int j; size_t data_size, algo_size; struct __attribute__((packed)) { struct ncr_session_init f; struct nlattr algo_head ALIGN_NL; char algo[128] ALIGN_NL; } op_init; struct __attribute__((packed)) { struct ncr_session_update f; struct nlattr data_head ALIGN_NL; struct ncr_session_input_data data ALIGN_NL; } op_up_data; struct __attribute__((packed)) { struct ncr_session_update f; struct nlattr key_head ALIGN_NL; uint32_t key; } op_up_key; struct __attribute__((packed)) { struct ncr_session_final f; struct nlattr output_head ALIGN_NL; struct ncr_session_output_buffer output ALIGN_NL; } op_final; const uint8_t *output = (void*)"\xe2\xd7\x2c\x2e\x14\xad\x97\xc8\xd2\xdb\xce\xd8\xb3\x52\x9f\x1c\xb3\x2c\x5c\xec"; /* convert it to key */ key = ioctl(cfd, NCRIO_KEY_INIT); if (key == -1) { perror("ioctl(NCRIO_KEY_INIT)"); return 1; } fprintf(stdout, "Tests on Hashes of Keys\n"); fprintf(stdout, "\t%s:\n", hash_vectors[0].algorithm); algo_size = strlen(hash_vectors[0].algorithm) + 1; /* import key */ memset(&kimport.f, 0, sizeof(kimport.f)); kimport.f.key = key; kimport.f.data = hash_vectors[0].plaintext; kimport.f.data_size = hash_vectors[0].plaintext_size; kimport.id_head.nla_len = NLA_HDRLEN + sizeof(kimport.id); kimport.id_head.nla_type = NCR_ATTR_KEY_ID; kimport.id[0] = 'a'; kimport.id[1] = 'b'; kimport.type_head.nla_len = NLA_HDRLEN + sizeof(kimport.type); kimport.type_head.nla_type = NCR_ATTR_KEY_TYPE; kimport.type = NCR_KEY_TYPE_SECRET; kimport.flags_head.nla_len = NLA_HDRLEN + sizeof(kimport.flags); kimport.flags_head.nla_type = NCR_ATTR_KEY_FLAGS; kimport.flags = NCR_KEY_FLAG_EXPORTABLE|NCR_KEY_FLAG_HASHABLE; kimport.algo_head.nla_len = NLA_HDRLEN + algo_size; kimport.algo_head.nla_type = NCR_ATTR_ALGORITHM; memcpy(kimport.algo, hash_vectors[0].algorithm, algo_size); kimport.f.input_size = kimport.algo + algo_size - (char *)&kimport; if (ioctl(cfd, NCRIO_KEY_IMPORT, &kimport)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_KEY_IMPORT)"); return 1; } memset(&op_init.f, 0, sizeof(op_init.f)); op_init.f.op = hash_vectors[0].op; op_init.algo_head.nla_len = NLA_HDRLEN + algo_size; op_init.algo_head.nla_type = NCR_ATTR_ALGORITHM; memcpy(op_init.algo, hash_vectors[0].algorithm, algo_size); op_init.f.input_size = op_init.algo + algo_size - (char *)&op_init; ses = ioctl(cfd, NCRIO_SESSION_INIT, &op_init); if (ses < 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_SESSION_INIT)"); return 1; } memset(&op_up_data.f, 0, sizeof(op_up_data.f)); op_up_data.f.input_size = sizeof(op_up_data); op_up_data.f.ses = ses; op_up_data.data_head.nla_len = NLA_HDRLEN + sizeof(op_up_data.data); op_up_data.data_head.nla_type = NCR_ATTR_UPDATE_INPUT_DATA; op_up_data.data.data = hash_vectors[0].plaintext; op_up_data.data.data_size = hash_vectors[0].plaintext_size; if (ioctl(cfd, NCRIO_SESSION_UPDATE, &op_up_data)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_SESSION_UPDATE)"); return 1; } memset(&op_up_key.f, 0, sizeof(op_up_key.f)); op_up_key.f.input_size = sizeof(op_up_key); op_up_key.f.ses = ses; op_up_key.key_head.nla_len = NLA_HDRLEN + sizeof(op_up_key.key); op_up_key.key_head.nla_type = NCR_ATTR_UPDATE_INPUT_KEY_AS_DATA; op_up_key.key = key; if (ioctl(cfd, NCRIO_SESSION_UPDATE, &op_up_key)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_SESSION_UPDATE)"); return 1; } memset(&op_final.f, 0, sizeof(op_final.f)); op_final.f.input_size = sizeof(op_final); op_final.f.ses = ses; op_final.output_head.nla_len = NLA_HDRLEN + sizeof(op_final.output); op_final.output_head.nla_type = NCR_ATTR_FINAL_OUTPUT_BUFFER; op_final.output.buffer = data; op_final.output.buffer_size = sizeof(data); op_final.output.result_size_ptr = &data_size; if (ioctl(cfd, NCRIO_SESSION_FINAL, &op_final)) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); perror("ioctl(NCRIO_SESSION_FINAL)"); return 1; } if (data_size != hash_vectors[0].output_size || memcmp(data, output, hash_vectors[0].output_size) != 0) { fprintf(stderr, "HASH test vector %d failed!\n", 0); fprintf(stderr, "Output[%d]: ", (int)data_size); for(j=0;j