1 /*
2 * COPYRIGHT (c) International Business Machines Corp. 2005-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 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <memory.h>
15
16 #include "pkcs11types.h"
17 #include "regress.h"
18 #include "common.c"
19
20 // these values are required when generating a PKCS DSA value. they were
21 // obtained by generating a DSA key pair on the 4758 with the default (random)
22 // values. these values are in big-endian format
23 //
24 CK_BYTE DSA_PUBL_PRIME[128] = {
25 0xba, 0xa2, 0x5b, 0xd9, 0x77, 0xb3, 0xf0, 0x2d, 0xa1, 0x65,
26 0xf1, 0x83, 0xa7, 0xc9, 0xf0, 0x8a, 0x51, 0x3f, 0x74, 0xe8,
27 0xeb, 0x1f, 0xd7, 0x0a, 0xd5, 0x41, 0xfa, 0x52, 0x3c, 0x1f,
28 0x79, 0x15, 0x55, 0x18, 0x45, 0x41, 0x29, 0x27, 0x12, 0x4a,
29 0xb4, 0x32, 0xa6, 0xd2, 0xec, 0xe2, 0x82, 0x73, 0xf4, 0x30,
30 0x66, 0x1a, 0x31, 0x06, 0x37, 0xd2, 0xb0, 0xe4, 0x26, 0x39,
31 0x2a, 0x0e, 0x48, 0xf6, 0x77, 0x94, 0x47, 0xea, 0x7d, 0x99,
32 0x22, 0xce, 0x65, 0x61, 0x82, 0xd5, 0xe3, 0xfc, 0x15, 0x3f,
33 0xff, 0xff, 0xc8, 0xb9, 0x4f, 0x37, 0xbf, 0x7a, 0xa6, 0x6a,
34 0xbe, 0xff, 0xa9, 0xdf, 0xfd, 0xed, 0x4a, 0xb6, 0x83, 0xd6,
35 0x0f, 0xea, 0xf6, 0x90, 0x4f, 0x12, 0x8e, 0x09, 0x6e, 0x3c,
36 0x0a, 0x6d, 0x2e, 0xfb, 0xb3, 0x79, 0x90, 0x8e, 0x39, 0xc0,
37 0x86, 0x0e, 0x5d, 0xf0, 0x56, 0xcd, 0x26, 0x45
38 };
39
40 CK_BYTE DSA_PUBL_SUBPRIME[20] = {
41 0x9f, 0x3d, 0x47, 0x13, 0xa3, 0xff, 0x93, 0xbb, 0x4a, 0xa6,
42 0xb0, 0xf1, 0x7e, 0x54, 0x1e, 0xba, 0xf0, 0x66, 0x03, 0x61
43 };
44
45
46 CK_BYTE DSA_PUBL_BASE[128] = {
47 0x1a, 0x5b, 0xfe, 0x12, 0xba, 0x85, 0x8e, 0x9b, 0x08, 0x86,
48 0xd1, 0x43, 0x9b, 0x4a, 0xaf, 0x44, 0x31, 0xdf, 0xa1, 0x57,
49 0xd8, 0xe0, 0xec, 0x34, 0x07, 0x4b, 0x78, 0x8e, 0x3c, 0x62,
50 0x47, 0x4c, 0x2f, 0x5d, 0xd3, 0x31, 0x2c, 0xe9, 0xdd, 0x59,
51 0xc5, 0xe7, 0x2e, 0x06, 0x40, 0x6c, 0x72, 0x9c, 0x95, 0xc6,
52 0xa4, 0x2a, 0x1c, 0x1c, 0x45, 0xb9, 0xf3, 0xdc, 0x83, 0xb6,
53 0xc6, 0xdd, 0x94, 0x45, 0x4f, 0x74, 0xc6, 0x55, 0x36, 0x54,
54 0xba, 0x20, 0xad, 0x9a, 0xb6, 0xe3, 0x20, 0xf2, 0xdd, 0xd3,
55 0x66, 0x19, 0xeb, 0x53, 0xf5, 0x88, 0x35, 0xe1, 0xea, 0xe8,
56 0xd4, 0x57, 0xe1, 0x3d, 0xea, 0xd5, 0x00, 0xc2, 0xa4, 0xf5,
57 0xff, 0xfb, 0x0b, 0xfb, 0xa2, 0xb9, 0xf1, 0x49, 0x46, 0x9d,
58 0x11, 0xa5, 0xb1, 0x94, 0x52, 0x47, 0x6e, 0x2e, 0x79, 0x4b,
59 0xc5, 0x18, 0xe9, 0xbc, 0xff, 0xae, 0x34, 0x7f
60 };
61
62 //
63 //
do_GenerateDSAKeyPair(void)64 CK_RV do_GenerateDSAKeyPair(void)
65 {
66 CK_SLOT_ID slot_id = SLOT_ID;
67 CK_SESSION_HANDLE session;
68 CK_MECHANISM mech;
69 CK_OBJECT_HANDLE publ_key, priv_key;
70 CK_FLAGS flags;
71 CK_BYTE user_pin[PKCS11_MAX_PIN_LEN];
72 CK_ULONG user_pin_len;
73 CK_RV rc;
74
75 CK_ATTRIBUTE publ_tmpl[] = {
76 {CKA_PRIME, DSA_PUBL_PRIME, sizeof(DSA_PUBL_PRIME)},
77 {CKA_SUBPRIME, DSA_PUBL_SUBPRIME, sizeof(DSA_PUBL_SUBPRIME)},
78 {CKA_BASE, DSA_PUBL_BASE, sizeof(DSA_PUBL_BASE)}
79 };
80
81 mech.mechanism = CKM_DSA_KEY_PAIR_GEN;
82 mech.ulParameterLen = 0;
83 mech.pParameter = NULL;
84
85 testcase_begin("GenerateDSAKeyPair");
86 testcase_rw_session();
87 testcase_user_login();
88
89 testcase_new_assertion();
90
91 rc = funcs->C_GenerateKeyPair(session, &mech, publ_tmpl, 3, NULL, 0,
92 &publ_key, &priv_key);
93 if (rc != CKR_OK)
94 testcase_fail("C_GenerateKeyPair rc=%s", p11_get_ckr(rc));
95 else
96 testcase_pass("GenerateDSAKeyPair passed");
97
98 testcase_cleanup:
99 testcase_user_logout();
100 if (funcs->C_CloseAllSessions(slot_id) != CKR_OK)
101 testcase_error("C_CloseAllSession failed.");
102
103 return rc;
104 }
105
106
107 // the generic DSA mechanism assumes that the data to be signed has already
108 // been hashed by SHA-1. so the input data length must be 20 bytes
109 //
do_SignDSA(void)110 CK_RV do_SignDSA(void)
111 {
112 CK_BYTE data1[20];
113 CK_BYTE signature[256];
114 CK_SLOT_ID slot_id = SLOT_ID;
115 CK_SESSION_HANDLE session;
116 CK_MECHANISM mech;
117 CK_OBJECT_HANDLE publ_key, priv_key;
118 CK_FLAGS flags;
119 CK_BYTE user_pin[PKCS11_MAX_PIN_LEN];
120 CK_ULONG user_pin_len;
121 CK_ULONG i;
122 CK_ULONG len1, sig_len;
123 CK_RV rc;
124
125 CK_ATTRIBUTE publ_tmpl[] = {
126 {CKA_PRIME, DSA_PUBL_PRIME, sizeof(DSA_PUBL_PRIME)},
127 {CKA_SUBPRIME, DSA_PUBL_SUBPRIME, sizeof(DSA_PUBL_SUBPRIME)},
128 {CKA_BASE, DSA_PUBL_BASE, sizeof(DSA_PUBL_BASE)}
129 };
130
131 mech.mechanism = CKM_DSA_KEY_PAIR_GEN;
132 mech.ulParameterLen = 0;
133 mech.pParameter = NULL;
134
135 testcase_begin("DSA Sign/Verify");
136 testcase_rw_session();
137 testcase_user_login();
138
139 testcase_new_assertion();
140
141 rc = funcs->C_GenerateKeyPair(session, &mech, publ_tmpl, 3, NULL, 0,
142 &publ_key, &priv_key);
143 if (rc != CKR_OK) {
144 testcase_error("C_GenerateKeyPair rc=%s", p11_get_ckr(rc));
145 goto testcase_cleanup;
146 }
147 // now, sign some data
148 //
149 len1 = sizeof(data1);
150 sig_len = sizeof(signature);
151
152 for (i = 0; i < len1; i++)
153 data1[i] = i % 255;
154
155 mech.mechanism = CKM_DSA;
156 mech.ulParameterLen = 0;
157 mech.pParameter = NULL;
158
159 rc = funcs->C_SignInit(session, &mech, priv_key);
160 if (rc != CKR_OK) {
161 testcase_error("C_SignInit rc=%s", p11_get_ckr(rc));
162 goto testcase_cleanup;
163 }
164
165 rc = funcs->C_Sign(session, data1, len1, signature, &sig_len);
166 if (rc != CKR_OK) {
167 testcase_error("C_Sign rc=%s", p11_get_ckr(rc));
168 goto testcase_cleanup;
169 }
170 // now, verify the signature
171 //
172 rc = funcs->C_VerifyInit(session, &mech, publ_key);
173 if (rc != CKR_OK) {
174 testcase_error("C_VerifyInit rc=%s", p11_get_ckr(rc));
175 goto testcase_cleanup;
176 }
177
178 rc = funcs->C_Verify(session, data1, len1, signature, sig_len);
179 if (rc != CKR_OK) {
180 testcase_error("C_Verify rc=%s", p11_get_ckr(rc));
181 goto testcase_cleanup;
182 }
183 // now, corrupt the signature and try to re-verify.
184 //
185 memcpy(signature, "ABCDEFGHIJKLMNOPQRSTUV",
186 strlen("ABCDEFGHIJKLMNOPQRSTUV"));
187
188 rc = funcs->C_VerifyInit(session, &mech, publ_key);
189 if (rc != CKR_OK) {
190 testcase_error("C_VerifyInit rc=%s", p11_get_ckr(rc));
191 goto testcase_cleanup;
192 }
193
194 rc = funcs->C_Verify(session, data1, len1, signature, sig_len);
195 if (rc != CKR_SIGNATURE_INVALID) {
196 testcase_fail("Verify expected CKR_SIGNATURE_INVALID, got %s",
197 p11_get_ckr(rc));
198 goto testcase_cleanup;
199 } else {
200 testcase_pass("DSA Sign/Verify passed");
201 }
202
203 testcase_cleanup:
204 testcase_user_logout();
205 if (funcs->C_CloseAllSessions(slot_id) != CKR_OK)
206 testcase_error("C_CloseAllSessions failed.");
207
208 return rc;
209 }
210
211 CK_BYTE DSA1024_BASE[128] = {
212 0xf7, 0xe1, 0xa0, 0x85, 0xd6, 0x9b, 0x3d, 0xde, 0xcb, 0xbc,
213 0xab, 0x5c, 0x36, 0xb8, 0x57, 0xb9, 0x79, 0x94, 0xaf, 0xbb,
214 0xfa, 0x3a, 0xea, 0x82, 0xf9, 0x57, 0x4c, 0x0b, 0x3d, 0x07,
215 0x82, 0x67, 0x51, 0x59, 0x57, 0x8e, 0xba, 0xd4, 0x59, 0x4f,
216 0xe6, 0x71, 0x07, 0x10, 0x81, 0x80, 0xb4, 0x49, 0x16, 0x71,
217 0x23, 0xe8, 0x4c, 0x28, 0x16, 0x13, 0xb7, 0xcf, 0x09, 0x32,
218 0x8c, 0xc8, 0xa6, 0xe1, 0x3c, 0x16, 0x7a, 0x8b, 0x54, 0x7c,
219 0x8d, 0x28, 0xe0, 0xa3, 0xae, 0x1e, 0x2b, 0xb3, 0xa6, 0x75,
220 0x91, 0x6e, 0xa3, 0x7f, 0x0b, 0xfa, 0x21, 0x35, 0x62, 0xf1,
221 0xfb, 0x62, 0x7a, 0x01, 0x24, 0x3b, 0xcc, 0xa4, 0xf1, 0xbe,
222 0xa8, 0x51, 0x90, 0x89, 0xa8, 0x83, 0xdf, 0xe1, 0x5a, 0xe5,
223 0x9f, 0x06, 0x92, 0x8b, 0x66, 0x5e, 0x80, 0x7b, 0x55, 0x25,
224 0x64, 0x01, 0x4c, 0x3b, 0xfe, 0xcf, 0x49, 0x2a
225 };
226
227 CK_BYTE DSA1024_PRIME[128] = {
228 0xfd, 0x7f, 0x53, 0x81, 0x1d, 0x75, 0x12, 0x29, 0x52, 0xdf,
229 0x4a, 0x9c, 0x2e, 0xec, 0xe4, 0xe7, 0xf6, 0x11, 0xb7, 0x52,
230 0x3c, 0xef, 0x44, 0x00, 0xc3, 0x1e, 0x3f, 0x80, 0xb6, 0x51,
231 0x26, 0x69, 0x45, 0x5d, 0x40, 0x22, 0x51, 0xfb, 0x59, 0x3d,
232 0x8d, 0x58, 0xfa, 0xbf, 0xc5, 0xf5, 0xba, 0x30, 0xf6, 0xcb,
233 0x9b, 0x55, 0x6c, 0xd7, 0x81, 0x3b, 0x80, 0x1d, 0x34, 0x6f,
234 0xf2, 0x66, 0x60, 0xb7, 0x6b, 0x99, 0x50, 0xa5, 0xa4, 0x9f,
235 0x9f, 0xe8, 0x04, 0x7b, 0x10, 0x22, 0xc2, 0x4f, 0xbb, 0xa9,
236 0xd7, 0xfe, 0xb7, 0xc6, 0x1b, 0xf8, 0x3b, 0x57, 0xe7, 0xc6,
237 0xa8, 0xa6, 0x15, 0x0f, 0x04, 0xfb, 0x83, 0xf6, 0xd3, 0xc5,
238 0x1e, 0xc3, 0x02, 0x35, 0x54, 0x13, 0x5a, 0x16, 0x91, 0x32,
239 0xf6, 0x75, 0xf3, 0xae, 0x2b, 0x61, 0xd7, 0x2a, 0xef, 0xf2,
240 0x22, 0x03, 0x19, 0x9d, 0xd1, 0x48, 0x01, 0xc7
241 };
242
243 CK_BYTE DSA1024_SUBPRIME[20] = {
244 0x97, 0x60, 0x50, 0x8f, 0x15, 0x23, 0x0b, 0xcc, 0xb2, 0x92,
245 0xb9, 0x82, 0xa2, 0xeb, 0x84, 0x0b, 0xf0, 0x58, 0x1c, 0xf5
246 };
247
248 CK_BYTE DSA1024_PRIVATE[20] = {
249 0x87, 0xa0, 0x68, 0x97, 0x5e, 0xf2, 0x51, 0xb4, 0x50, 0x51,
250 0x0d, 0xee, 0x08, 0x73, 0x41, 0x19, 0x5c, 0xa6, 0x8c, 0x16
251 };
252
253 CK_BYTE DSA1024_PUBLIC[128] = {
254 0xa2, 0x8a, 0x43, 0xb9, 0x5d, 0x73, 0x6b, 0x5a, 0x5a, 0xfe,
255 0xb5, 0xa0, 0x7d, 0x2c, 0x89, 0x65, 0xeb, 0xf3, 0x52, 0xa3,
256 0xe2, 0x9b, 0xa7, 0xe3, 0x65, 0x11, 0x12, 0x0c, 0xcc, 0xa2,
257 0xb7, 0x60, 0x51, 0xcd, 0xfb, 0x87, 0xfd, 0x9e, 0xe7, 0x58,
258 0xe5, 0xb1, 0x15, 0x98, 0x66, 0x63, 0x18, 0x6f, 0x46, 0x83,
259 0x27, 0xbf, 0x5a, 0xc5, 0x00, 0xf1, 0x89, 0xcb, 0x70, 0x6f,
260 0x62, 0x16, 0xab, 0xbc, 0x4b, 0xb7, 0x25, 0x8f, 0x92, 0x15,
261 0x06, 0x06, 0x5d, 0xb3, 0x36, 0x98, 0x3c, 0x31, 0x26, 0x7c,
262 0xe7, 0x8c, 0x94, 0x27, 0xfa, 0xb8, 0xda, 0xd0, 0xc6, 0x4b,
263 0x54, 0xf1, 0xef, 0xf6, 0x0e, 0xc6, 0x01, 0xdd, 0x1a, 0xbc,
264 0x25, 0xd9, 0x56, 0x93, 0x80, 0x37, 0x94, 0xd9, 0x67, 0x33,
265 0xd5, 0x65, 0x69, 0x93, 0x1f, 0x07, 0xc7, 0x72, 0xa5, 0x13,
266 0x23, 0x83, 0xac, 0x6e, 0xab, 0xda, 0xfb, 0xc4
267 };
268
269
270 // import a DSA public key
271 //
do_ImportDSAKeyPairSignVerify(void)272 CK_RV do_ImportDSAKeyPairSignVerify(void)
273 {
274 CK_SLOT_ID slot_id = SLOT_ID;
275 CK_SESSION_HANDLE session;
276 CK_FLAGS flags;
277 CK_OBJECT_HANDLE publ_key, priv_key;
278 CK_BYTE user_pin[PKCS11_MAX_PIN_LEN];
279 CK_ULONG user_pin_len;
280 CK_MECHANISM mech;
281 CK_BYTE data1[20];
282 CK_BYTE signature[256];
283 CK_ULONG len1, sig_len;
284 CK_ULONG i;
285 CK_RV rc;
286
287 testcase_begin("DSA Import KeyPair Sign/Verify");
288 testcase_rw_session();
289 testcase_user_login();
290
291 testcase_new_assertion();
292
293 // import the private key
294 rc = create_DSAPrivateKey(session,
295 DSA1024_PRIME, sizeof(DSA1024_PRIME),
296 DSA1024_SUBPRIME, sizeof(DSA1024_SUBPRIME),
297 DSA1024_BASE, sizeof(DSA1024_BASE),
298 DSA1024_PRIVATE, sizeof(DSA1024_PRIVATE),
299 &priv_key);
300 if (rc != CKR_OK) {
301 testcase_fail("C_CreateObject (DSA Private Key) failed rc=%s",
302 p11_get_ckr(rc));
303 goto testcase_cleanup;
304 }
305 // import the public key
306 rc = create_DSAPublicKey(session,
307 DSA1024_PRIME, sizeof(DSA1024_PRIME),
308 DSA1024_SUBPRIME, sizeof(DSA1024_SUBPRIME),
309 DSA1024_BASE, sizeof(DSA1024_BASE),
310 DSA1024_PUBLIC, sizeof(DSA1024_PUBLIC), &publ_key);
311 if (rc != CKR_OK) {
312 testcase_fail("C_CreateObject (DSA Public Key) failed rc=%s",
313 p11_get_ckr(rc));
314 goto testcase_cleanup;
315 }
316 // now, sign some data
317 //
318 len1 = sizeof(data1);
319 sig_len = sizeof(signature);
320
321 for (i = 0; i < len1; i++)
322 data1[i] = i % 255;
323
324 mech.mechanism = CKM_DSA;
325 mech.ulParameterLen = 0;
326 mech.pParameter = NULL;
327
328 rc = funcs->C_SignInit(session, &mech, priv_key);
329 if (rc != CKR_OK) {
330 testcase_error("C_SignInit rc=%s", p11_get_ckr(rc));
331 goto testcase_cleanup;
332 }
333
334 rc = funcs->C_Sign(session, data1, len1, signature, &sig_len);
335 if (rc != CKR_OK) {
336 testcase_error("C_Sign rc=%s", p11_get_ckr(rc));
337 goto testcase_cleanup;
338 }
339 // now, verify the signature
340 //
341 rc = funcs->C_VerifyInit(session, &mech, publ_key);
342 if (rc != CKR_OK) {
343 testcase_error("C_VerifyInit rc=%s", p11_get_ckr(rc));
344 goto testcase_cleanup;
345 }
346
347 rc = funcs->C_Verify(session, data1, len1, signature, sig_len);
348 if (rc != CKR_OK) {
349 testcase_error("C_Verify rc=%s", p11_get_ckr(rc));
350 goto testcase_cleanup;
351 }
352
353 testcase_pass("DSA Import KeyPair Sign/Verify");
354
355 testcase_cleanup:
356 testcase_user_logout();
357 if (funcs->C_CloseAllSessions(slot_id) != CKR_OK)
358 testcase_error("C_CloseAllSessions failed.");
359
360 return rc;
361 }
362
dsa_functions()363 CK_RV dsa_functions()
364 {
365 SYSTEMTIME t1, t2;
366 CK_RV rc = CKR_OK;
367 CK_SLOT_ID slot_id;
368
369 /** skip tests if the slot doesn't support this mechanism **/
370 slot_id = SLOT_ID;
371 if (!(mech_supported(slot_id, CKM_DSA))) {
372 printf("Slot %u doesn't support DSA\n", (unsigned int) slot_id);
373 return rc;
374 }
375
376 GetSystemTime(&t1);
377 rc = do_GenerateDSAKeyPair();
378 if (rc) {
379 PRINT_ERR("ERROR do_GenerateDSAKeyPair failed, rc = 0x%lx\n", rc);
380 if (!no_stop)
381 return rc;
382 }
383 GetSystemTime(&t2);
384 process_time(t1, t2);
385
386 GetSystemTime(&t1);
387 rc = do_SignDSA();
388 if (rc) {
389 PRINT_ERR("ERROR do_SignDSA failed, rc = 0x%lx\n", rc);
390 if (!no_stop)
391 return rc;
392 }
393 GetSystemTime(&t2);
394 process_time(t1, t2);
395
396 GetSystemTime(&t1);
397 rc = do_ImportDSAKeyPairSignVerify();
398 if (rc) {
399 PRINT_ERR("ERROR do_ImportDSAKeyPairSignVerify failed, rc = 0x%lx\n",
400 rc);
401 if (!no_stop)
402 return rc;
403 }
404 GetSystemTime(&t2);
405 process_time(t1, t2);
406
407 return rc;
408 }
409
main(int argc,char ** argv)410 int main(int argc, char **argv)
411 {
412 CK_C_INITIALIZE_ARGS cinit_args;
413 int rc;
414 CK_RV rv;
415
416 rc = do_ParseArgs(argc, argv);
417 if (rc != 1)
418 return rc;
419
420 printf("Using slot #%lu...\n\n", SLOT_ID);
421 printf("With option: no_init: %d\n", no_init);
422
423 rc = do_GetFunctionList();
424 if (!rc) {
425 PRINT_ERR("ERROR do_GetFunctionList() Failed , rc = 0x%0x\n", rc);
426 return rc;
427 }
428
429 memset(&cinit_args, 0x0, sizeof(cinit_args));
430 cinit_args.flags = CKF_OS_LOCKING_OK;
431
432 // SAB Add calls to ALL functions before the C_Initialize gets hit
433
434 funcs->C_Initialize(&cinit_args);
435
436 {
437 CK_SESSION_HANDLE hsess = 0;
438
439 rc = funcs->C_GetFunctionStatus(hsess);
440 if (rc != CKR_FUNCTION_NOT_PARALLEL)
441 return rc;
442
443 rc = funcs->C_CancelFunction(hsess);
444 if (rc != CKR_FUNCTION_NOT_PARALLEL)
445 return rc;
446
447 }
448
449 testcase_setup(0);
450
451 rv = dsa_functions();
452
453 testcase_print_result();
454
455 funcs->C_Finalize(NULL);
456
457 /* make sure we return non-zero if rv is non-zero */
458 return ((rv == 0) || (rv % 256) ? (int)rv : -1);
459 }
460