1 /*
2 * COPYRIGHT (c) International Business Machines Corp. 2010-2017
3 *
4 * This program is provided under the terms of the Common Public License,
5 * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
6 * software constitutes recipient's acceptance of CPL-1.0 terms which can be
7 * found in the file LICENSE file or at
8 * https://opensource.org/licenses/cpl1.0.php
9 */
10
11 /* File: sess_perf.c */
12
13 #include <windows.h>
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <memory.h>
19
20 #include "pkcs11types.h"
21 #include "regress.h"
22 #include "defs.h"
23
24 #define DATALEN 1024
25 CK_BYTE DATA[DATALEN];
26 CK_BYTE DUMP[DATALEN];
27
28 typedef struct _context_table {
29 CK_SESSION_HANDLE hsess;
30 CK_OBJECT_HANDLE hkey;
31 } context_table_t;
32
dump_session_info(CK_SESSION_INFO * info)33 void dump_session_info(CK_SESSION_INFO * info)
34 {
35 printf(" CK_SESSION_INFO:\n");
36 printf(" slotID: %ld\n", info->slotID);
37 printf(" state: ");
38 switch (info->state) {
39 case CKS_RO_PUBLIC_SESSION:
40 printf("CKS_RO_PUBLIC_SESSION\n");
41 break;
42 case CKS_RW_PUBLIC_SESSION:
43 printf("CKS_RW_PUBLIC_SESSION\n");
44 break;
45 case CKS_RO_USER_FUNCTIONS:
46 printf("CKS_RO_USER_FUNCTIONS\n");
47 break;
48 case CKS_RW_USER_FUNCTIONS:
49 printf("CKS_RW_USER_FUNCTIONS\n");
50 break;
51 case CKS_RW_SO_FUNCTIONS:
52 printf("CKS_RW_SO_FUNCTIONS\n");
53 break;
54 }
55 printf(" flags: %p\n", (void *) info->flags);
56 printf(" ulDeviceError: %ld\n", info->ulDeviceError);
57 }
58
create_des_encrypt_context(CK_SESSION_HANDLE_PTR hsess,CK_OBJECT_HANDLE_PTR hkey)59 int create_des_encrypt_context(CK_SESSION_HANDLE_PTR hsess,
60 CK_OBJECT_HANDLE_PTR hkey)
61 {
62 CK_SLOT_ID slot_id;
63 CK_FLAGS flags;
64 CK_RV rc;
65 CK_MECHANISM mech;
66 CK_ULONG key_len = 16;
67 CK_ATTRIBUTE tkey = { CKA_VALUE_LEN, &key_len, sizeof(CK_ULONG) };
68
69 /* create session */
70 slot_id = SLOT_ID;
71 flags = CKF_SERIAL_SESSION; // read-only session
72
73 rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, hsess);
74 if (rc != CKR_OK) {
75 show_error(" C_OpenSession #1", rc);
76 return FALSE;
77 }
78
79 /* generate key in this specific session */
80 mech.mechanism = CKM_AES_KEY_GEN;
81 mech.ulParameterLen = 0;
82 mech.pParameter = NULL;
83
84 rc = funcs->C_GenerateKey(*hsess, &mech, &tkey, 1, hkey);
85 if (rc != CKR_OK) {
86 show_error(" C_GenerateKey #1", rc);
87 return FALSE;
88 }
89
90 /* Get Random for Initialization Vector */
91 mech.mechanism = CKM_AES_CBC;
92 mech.ulParameterLen = 16;
93 mech.pParameter = "1234567890123456";
94
95 /* Create encryption context using this session and key */
96 rc = funcs->C_EncryptInit(*hsess, &mech, *hkey);
97 if (rc != CKR_OK) {
98 show_error(" C_EncryptInit #1", rc);
99 return FALSE;
100 }
101
102 return TRUE;
103 }
104
encrypt_DATA(CK_SESSION_HANDLE hsess,CK_OBJECT_HANDLE hkey,CK_ULONG blocklen)105 int encrypt_DATA(CK_SESSION_HANDLE hsess, CK_OBJECT_HANDLE hkey,
106 CK_ULONG blocklen)
107 {
108 CK_RV rc;
109 CK_ULONG outlen = 16;
110 unsigned long int i;
111
112 UNUSED(hkey);
113
114 for (i = 0; i < DATALEN; i += outlen) {
115 rc = funcs->C_EncryptUpdate(hsess, (CK_BYTE_PTR) (DATA + i), blocklen,
116 (CK_BYTE_PTR) (DUMP + i), &outlen);
117 if (rc != CKR_OK) {
118 show_error("C_Encrypt #1", rc);
119 return FALSE;
120 }
121 }
122
123 return TRUE;
124 }
125
126
finalize_des_encrypt_context(CK_SESSION_HANDLE hsess)127 int finalize_des_encrypt_context(CK_SESSION_HANDLE hsess)
128 {
129 CK_RV rc;
130 CK_ULONG outlen = DATALEN;
131
132 rc = funcs->C_EncryptFinal(hsess, DUMP, &outlen);
133 if (rc != CKR_OK) {
134 show_error("C_EncryptFinal#1", rc);
135 return FALSE;
136 }
137
138 rc = funcs->C_CloseSession(hsess);
139 if (rc != CKR_OK) {
140 show_error("C_CloseSession #1", rc);
141 return FALSE;
142 }
143
144 return TRUE;
145 }
146
close_all_sess(void)147 int close_all_sess(void)
148 {
149 CK_SLOT_ID slot_id;
150 CK_RV rc;
151
152 slot_id = SLOT_ID;
153
154 rc = funcs->C_CloseAllSessions(slot_id);
155 if (rc != CKR_OK) {
156 show_error("C_CloseAllSessions #1", rc);
157 return FALSE;
158 }
159
160 return TRUE;
161 }
162
do_SessionPerformance(unsigned int count)163 int do_SessionPerformance(unsigned int count)
164 {
165 SYSTEMTIME t1, t2;
166 int rc;
167 unsigned int i;
168 context_table_t *t = NULL;
169
170 if (count == 0) {
171 show_error("do_SessionPerformance: zero session count", (CK_RV) 0);
172 return FALSE;
173 }
174
175 t = (context_table_t *) calloc(count, sizeof(context_table_t));
176 if (t == NULL) {
177 show_error("do_SessionPerformance: insuficient memory", (CK_RV) 0);
178 return FALSE;
179 }
180
181 /* create encryption contexts */
182 for (i = 0; i < count; i++) {
183 rc = create_des_encrypt_context(&(t[i].hsess), &(t[i].hkey));
184 if (rc == FALSE) {
185 show_error("create_aes_encrypt_context", (CK_RV) 0);
186 goto ret;
187 }
188 }
189
190 /* Time encrypt operation in the first and last session */
191 GetSystemTime(&t1);
192 rc = encrypt_DATA(t[0].hsess, t[0].hkey, 16);
193 if (rc == FALSE) {
194 show_error("encrypt_DATA #1", (CK_RV) 0);
195 goto ret;
196 }
197
198 rc = encrypt_DATA(t[count - 1].hsess, t[count - 1].hkey, 16);
199 if (rc == FALSE) {
200 show_error("encrypt_DATA #2", (CK_RV) 0);
201 goto ret;
202 }
203 GetSystemTime(&t2);
204 process_time(t1, t2);
205
206 for (i = 0; i < count; i++) {
207 rc = finalize_des_encrypt_context(t[i].hsess);
208 if (rc == FALSE) {
209 show_error("finalize_aes_encrypt_context", (CK_RV) 0);
210 goto ret;
211 }
212 }
213
214 rc = TRUE;
215 ret:
216 if (t != NULL)
217 free(t);
218 return rc;
219 }
220
main(int argc,char ** argv)221 int main(int argc, char **argv)
222 {
223 CK_C_INITIALIZE_ARGS cinit_args;
224 int rc, i;
225
226
227 rc = do_ParseArgs(argc, argv);
228 if (rc != 1)
229 return rc;
230
231 printf("Using slot #%lu...\n\n", SLOT_ID);
232 printf("With option: no_init: %d\n", no_init);
233
234 rc = do_GetFunctionList();
235 if (!rc) {
236 PRINT_ERR("ERROR do_GetFunctionList() Failed , rc = 0x%0x\n", rc);
237 return rc;
238 }
239
240 memset(&cinit_args, 0x0, sizeof(cinit_args));
241 cinit_args.flags = CKF_OS_LOCKING_OK;
242
243 // SAB Add calls to ALL functions before the C_Initialize gets hit
244
245 funcs->C_Initialize(&cinit_args);
246
247 {
248 CK_SESSION_HANDLE hsess = 0;
249
250 rc = funcs->C_GetFunctionStatus(hsess);
251 if (rc != CKR_FUNCTION_NOT_PARALLEL)
252 return rc;
253
254 rc = funcs->C_CancelFunction(hsess);
255 if (rc != CKR_FUNCTION_NOT_PARALLEL)
256 return rc;
257
258 }
259
260 for (i = 100; i < 50000; i = 1.2 * i) {
261 printf("timing do_SessionPerformance(%d)\n", i);
262 do_SessionPerformance(i);
263 }
264
265 return 0;
266 }
267