1 /*
2 * COPYRIGHT (c) International Business Machines Corp. 2001-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: key.c
12 //
13 // Functions contained within:
14 //
15 // key_object_check_required_attributes
16 // key_object_set_default_attributes
17 // key_object_validate_attribute
18 //
19 // publ_key_check_required_attributes
20 // publ_key_set_default_attributes
21 // publ_key_validate_attribute
22 //
23 // priv_key_check_required_attributes
24 // priv_key_set_default_attributes
25 // priv_key_validate_attribute
26 //
27 // secret_key_check_required_attributes
28 // secret_key_set_default_attributes
29 // secret_key_validate_attribute
30 //
31 // rsa_publ_check_required_attributes
32 // rsa_publ_validate_attribute
33 // rsa_priv_check_required_attributes
34 // rsa_priv_validate_attribute
35 // rsa_priv_check_exportability
36 //
37 // dsa_publ_check_required_attributes
38 // dsa_publ_validate_attribute
39 // dsa_priv_check_required_attributes
40 // dsa_priv_validate_attribute
41 // dsa_priv_check_exportability
42 //
43 // ecdsa_publ_check_required_attributes
44 // ecdsa_publ_validate_attribute
45 // ecdsa_priv_checK_required_attributes
46 // ecdsa_priv_validate_attribute
47 // ecdsa_priv_check_exportability
48 //
49 // dh_publ_check_required_attributes
50 // dh_publ_validate_attribute
51 // dh_priv_check_required_attributes
52 // dh_priv_validate_attribute
53 // dh_priv_check_exportability
54 //
55 // kea_publ_check_required_attributes
56 // kea_publ_validate_attribute
57 // kea_priv_check_required_attributes
58 // kea_priv_validate_attribute
59 // kea_priv_check_exportability
60 //
61 // generic_secret_check_required_attributes
62 // generic_secret_validate_attribute
63 // generic_secret_set_default_attributes
64 //
65 // rc2_check_required_attributes
66 // rc2_validate_attribute
67 // rc2_priv_check_exportability
68 //
69 // rc4_check_required_attributes
70 // rc4_validate_attribute
71 // rc4_priv_check_exportability
72 //
73 // rc5_check_required_attributes
74 // rc5_validate_attribute
75 // rc5_priv_check_exportability
76 //
77 // des_check_required_attributes
78 // des_validate_attribute
79 // des_priv_check_exportability
80 //
81 // des2_check_required_attributes
82 // des2_validate_attribute
83 // des2_priv_check_exportability
84 //
85 // des3_check_required_attributes
86 // des3_validate_attribute
87 // des3_priv_check_exportability
88 //
89 // cast_check_required_attributes
90 // cast_validate_attribute
91 // cast_priv_check_exportability
92 //
93 // cast3_check_required_attributes
94 // cast3_validate_attribute
95 // cast3_priv_check_exportability
96 //
97 // cast5_check_required_attributes
98 // cast5_validate_attribute
99 // cast5_priv_check_exportability
100 //
101 // idea_check_required_attributes
102 // idea_validate_attribute
103 // idea_priv_check_exportability
104 //
105 // cdmf_check_required_attributes
106 // cdmf_validate_attribute
107 // cdmf_priv_check_exportability
108 //
109 // skipjack_check_required_attributes
110 // skipjack_validate_attribute
111 // skipjack_priv_check_exportability
112 //
113 // baton_check_required_attributes
114 // baton_validate_attribute
115 // baton_priv_check_exportability
116 //
117 // juniper_check_required_attributes
118 // juniper_validate_attribute
119 // juniper_priv_check_exportability
120 //
121
122 #include <pthread.h>
123 #include <stdlib.h>
124
125 #include <string.h> // for memcmp() et al
126
127 #include "pkcs11types.h"
128 #include "p11util.h"
129 #include "defs.h"
130 #include "host_defs.h"
131 #include "h_extern.h"
132 #include "trace.h"
133
134 #include "tok_spec_struct.h"
135
136
137 // key_object_check_required_attributes()
138 //
139 // Check required common attributes for key objects
140 //
key_object_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)141 CK_RV key_object_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
142 {
143 CK_ATTRIBUTE *attr = NULL;
144 CK_BBOOL found;
145
146 found = template_attribute_find(tmpl, CKA_KEY_TYPE, &attr);
147 if (!found) {
148 if (mode == MODE_CREATE) {
149 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
150 return CKR_TEMPLATE_INCOMPLETE;
151 }
152 }
153
154 return template_check_required_base_attributes(tmpl, mode);
155 }
156
157
158 // key_object_set_default_attributes()
159 //
key_object_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)160 CK_RV key_object_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
161 {
162 CK_ATTRIBUTE *id_attr = NULL;
163 CK_ATTRIBUTE *sdate_attr = NULL;
164 CK_ATTRIBUTE *edate_attr = NULL;
165 CK_ATTRIBUTE *derive_attr = NULL;
166 CK_ATTRIBUTE *local_attr = NULL;
167 CK_ATTRIBUTE *keygenmech_attr = NULL;
168
169 // satisfy the compiler
170 //
171 if (mode)
172 id_attr = NULL;
173
174 id_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
175 sdate_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
176 edate_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
177 derive_attr =
178 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
179 local_attr =
180 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
181 keygenmech_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE)
182 + sizeof(CK_MECHANISM_TYPE));
183
184 if (!id_attr || !sdate_attr || !edate_attr || !derive_attr || !local_attr
185 || !keygenmech_attr) {
186 if (id_attr)
187 free(id_attr);
188 if (sdate_attr)
189 free(sdate_attr);
190 if (edate_attr)
191 free(edate_attr);
192 if (derive_attr)
193 free(derive_attr);
194 if (local_attr)
195 free(local_attr);
196 if (keygenmech_attr)
197 free(keygenmech_attr);
198 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
199 return CKR_HOST_MEMORY;
200 }
201
202 id_attr->type = CKA_ID;
203 id_attr->ulValueLen = 0;
204 id_attr->pValue = NULL;
205
206 sdate_attr->type = CKA_START_DATE;
207 sdate_attr->ulValueLen = 0;
208 sdate_attr->pValue = NULL;
209
210 edate_attr->type = CKA_END_DATE;
211 edate_attr->ulValueLen = 0;
212 edate_attr->pValue = NULL;
213
214 derive_attr->type = CKA_DERIVE;
215 derive_attr->ulValueLen = sizeof(CK_BBOOL);
216 derive_attr->pValue = (CK_BYTE *) derive_attr + sizeof(CK_ATTRIBUTE);
217 *(CK_BBOOL *) derive_attr->pValue = FALSE;
218
219 local_attr->type = CKA_LOCAL;
220 local_attr->ulValueLen = sizeof(CK_BBOOL);
221 local_attr->pValue = (CK_BYTE *) local_attr + sizeof(CK_ATTRIBUTE);
222 *(CK_BBOOL *) local_attr->pValue = FALSE;
223
224 keygenmech_attr->type = CKA_KEY_GEN_MECHANISM;
225 keygenmech_attr->ulValueLen = sizeof(CK_MECHANISM_TYPE);
226 keygenmech_attr->pValue = (CK_BYTE *) keygenmech_attr + sizeof(CK_ATTRIBUTE);
227 *(CK_MECHANISM_TYPE *) keygenmech_attr->pValue = CK_UNAVAILABLE_INFORMATION;
228
229 template_update_attribute(tmpl, id_attr);
230 template_update_attribute(tmpl, sdate_attr);
231 template_update_attribute(tmpl, edate_attr);
232 template_update_attribute(tmpl, derive_attr);
233 template_update_attribute(tmpl, local_attr);
234 template_update_attribute(tmpl, keygenmech_attr);
235 return CKR_OK;
236 }
237
238
239 // key_object_validate_attribute()
240 //
key_object_validate_attribute(TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)241 CK_RV key_object_validate_attribute(TEMPLATE *tmpl, CK_ATTRIBUTE *attr,
242 CK_ULONG mode)
243 {
244 switch (attr->type) {
245 case CKA_KEY_TYPE:
246 if (mode == MODE_CREATE || mode == MODE_DERIVE ||
247 mode == MODE_KEYGEN || mode == MODE_UNWRAP)
248 return CKR_OK;
249
250 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
251 return CKR_ATTRIBUTE_READ_ONLY;
252 case CKA_ID:
253 case CKA_START_DATE:
254 case CKA_END_DATE:
255 case CKA_DERIVE:
256 return CKR_OK;
257 case CKA_LOCAL:
258 // CKA_LOCAL is only set by the key-generate routine
259 //
260 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
261 return CKR_ATTRIBUTE_READ_ONLY;
262 default:
263 return template_validate_base_attribute(tmpl, attr, mode);
264 }
265
266 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_TYPE_INVALID));
267
268 return CKR_ATTRIBUTE_TYPE_INVALID;
269 }
270
271
272 // publ_key_check_required_attributes()
273 //
publ_key_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)274 CK_RV publ_key_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
275 {
276 // CKO_PUBLIC_KEY has no required attributes
277 //
278 return key_object_check_required_attributes(tmpl, mode);
279 }
280
281
282 // publ_key_set_default_attributes()
283 //
284 // some of the common public key attributes have defaults but none of the
285 // specific public keytypes have default attributes
286 //
publ_key_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)287 CK_RV publ_key_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
288 {
289 CK_ATTRIBUTE *class_attr = NULL;
290 CK_ATTRIBUTE *subject_attr = NULL;
291 CK_ATTRIBUTE *encrypt_attr = NULL;
292 CK_ATTRIBUTE *verify_attr = NULL;
293 CK_ATTRIBUTE *verify_recover_attr = NULL;
294 CK_ATTRIBUTE *wrap_attr = NULL;
295
296 CK_OBJECT_CLASS class = CKO_PUBLIC_KEY;
297 CK_RV rc;
298
299
300 rc = key_object_set_default_attributes(tmpl, mode);
301 if (rc != CKR_OK) {
302 TRACE_DEVEL("key_object_set_default_attributes failed\n");
303 return rc;
304 }
305 // add the default CKO_PUBLIC_KEY attributes
306 //
307 class_attr =
308 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS));
309 subject_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
310 encrypt_attr =
311 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
312 verify_attr =
313 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
314 verify_recover_attr =
315 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
316 wrap_attr =
317 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
318
319 if (!class || !subject_attr || !encrypt_attr ||
320 !verify_attr || !verify_recover_attr || !wrap_attr) {
321 if (class_attr)
322 free(class_attr);
323 if (subject_attr)
324 free(subject_attr);
325 if (encrypt_attr)
326 free(encrypt_attr);
327 if (verify_attr)
328 free(verify_attr);
329 if (verify_recover_attr)
330 free(verify_recover_attr);
331 if (wrap_attr)
332 free(wrap_attr);
333
334 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
335 return CKR_HOST_MEMORY;
336 }
337
338 class_attr->type = CKA_CLASS;
339 class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS);
340 class_attr->pValue = (CK_BYTE *) class_attr + sizeof(CK_ATTRIBUTE);
341 *(CK_OBJECT_CLASS *) class_attr->pValue = CKO_PUBLIC_KEY;
342
343 subject_attr->type = CKA_SUBJECT;
344 subject_attr->ulValueLen = 0; // empty string
345 subject_attr->pValue = NULL;
346
347 encrypt_attr->type = CKA_ENCRYPT;
348 encrypt_attr->ulValueLen = sizeof(CK_BBOOL);
349 encrypt_attr->pValue = (CK_BYTE *) encrypt_attr + sizeof(CK_ATTRIBUTE);
350 *(CK_BBOOL *) encrypt_attr->pValue = TRUE;
351
352 verify_attr->type = CKA_VERIFY;
353 verify_attr->ulValueLen = sizeof(CK_BBOOL);
354 verify_attr->pValue = (CK_BYTE *) verify_attr + sizeof(CK_ATTRIBUTE);
355 *(CK_BBOOL *) verify_attr->pValue = TRUE;
356
357 verify_recover_attr->type = CKA_VERIFY_RECOVER;
358 verify_recover_attr->ulValueLen = sizeof(CK_BBOOL);
359 verify_recover_attr->pValue =
360 (CK_BYTE *) verify_recover_attr + sizeof(CK_ATTRIBUTE);
361 *(CK_BBOOL *) verify_recover_attr->pValue = TRUE;
362
363 wrap_attr->type = CKA_WRAP;
364 wrap_attr->ulValueLen = sizeof(CK_BBOOL);
365 wrap_attr->pValue = (CK_BYTE *) wrap_attr + sizeof(CK_ATTRIBUTE);
366 *(CK_BBOOL *) wrap_attr->pValue = TRUE;
367
368 template_update_attribute(tmpl, class_attr);
369 template_update_attribute(tmpl, subject_attr);
370 template_update_attribute(tmpl, encrypt_attr);
371 template_update_attribute(tmpl, verify_attr);
372 template_update_attribute(tmpl, verify_recover_attr);
373 template_update_attribute(tmpl, wrap_attr);
374
375 return CKR_OK;
376 }
377
378
379 // publ_key_validate_attribute
380 //
publ_key_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)381 CK_RV publ_key_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
382 CK_ATTRIBUTE *attr, CK_ULONG mode)
383 {
384 switch (attr->type) {
385 case CKA_SUBJECT:
386 return CKR_OK;
387 case CKA_ENCRYPT:
388 case CKA_VERIFY:
389 case CKA_VERIFY_RECOVER:
390 case CKA_WRAP:
391 if (mode == MODE_MODIFY) {
392 if (tokdata->nv_token_data->tweak_vector.allow_key_mods == TRUE)
393 return CKR_OK;
394
395 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
396 return CKR_ATTRIBUTE_READ_ONLY;
397 }
398 return CKR_OK;
399 default:
400 return key_object_validate_attribute(tmpl, attr, mode);
401 }
402
403 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_TYPE_INVALID));
404
405 return CKR_ATTRIBUTE_TYPE_INVALID;
406 }
407
408
409 // priv_key_check_required_attributes()
410 //
priv_key_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)411 CK_RV priv_key_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
412 {
413 // CKO_PRIVATE_KEY has no required attributes
414 //
415 return key_object_check_required_attributes(tmpl, mode);
416 }
417
418
419 // priv_key_set_default_attributes()
420 //
421 // some of the common private key attributes have defaults but none of the
422 // specific private keytypes have default attributes
423 //
priv_key_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)424 CK_RV priv_key_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
425 {
426 CK_ATTRIBUTE *class_attr = NULL;
427 CK_ATTRIBUTE *subject_attr = NULL;
428 CK_ATTRIBUTE *sensitive_attr = NULL;
429 CK_ATTRIBUTE *decrypt_attr = NULL;
430 CK_ATTRIBUTE *sign_attr = NULL;
431 CK_ATTRIBUTE *sign_recover_attr = NULL;
432 CK_ATTRIBUTE *unwrap_attr = NULL;
433 CK_ATTRIBUTE *extractable_attr = NULL;
434 CK_ATTRIBUTE *never_extr_attr = NULL;
435 CK_ATTRIBUTE *always_sens_attr = NULL;
436 CK_ATTRIBUTE *always_auth_attr = NULL;
437 CK_RV rc;
438
439
440 rc = key_object_set_default_attributes(tmpl, mode);
441 if (rc != CKR_OK) {
442 TRACE_DEVEL("key_object_set_default_attributes failed\n");
443 return rc;
444 }
445 // add the default CKO_PUBLIC_KEY attributes
446 //
447 class_attr =
448 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS));
449 subject_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
450 sensitive_attr =
451 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
452 decrypt_attr =
453 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
454 sign_attr =
455 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
456 sign_recover_attr =
457 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
458 unwrap_attr =
459 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
460 extractable_attr =
461 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
462 never_extr_attr =
463 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
464 always_sens_attr =
465 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
466 always_auth_attr =
467 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
468
469 if (!class_attr || !subject_attr || !sensitive_attr || !decrypt_attr ||
470 !sign_attr || !sign_recover_attr || !unwrap_attr || !extractable_attr ||
471 !never_extr_attr || !always_sens_attr || !always_auth_attr) {
472 if (class_attr)
473 free(class_attr);
474 if (subject_attr)
475 free(subject_attr);
476 if (sensitive_attr)
477 free(sensitive_attr);
478 if (decrypt_attr)
479 free(decrypt_attr);
480 if (sign_attr)
481 free(sign_attr);
482 if (sign_recover_attr)
483 free(sign_recover_attr);
484 if (unwrap_attr)
485 free(unwrap_attr);
486 if (extractable_attr)
487 free(extractable_attr);
488 if (always_sens_attr)
489 free(always_sens_attr);
490 if (never_extr_attr)
491 free(never_extr_attr);
492 if (always_auth_attr)
493 free(always_auth_attr);
494
495 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
496 return CKR_HOST_MEMORY;
497 }
498
499 class_attr->type = CKA_CLASS;
500 class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS);
501 class_attr->pValue = (CK_BYTE *) class_attr + sizeof(CK_ATTRIBUTE);
502 *(CK_OBJECT_CLASS *) class_attr->pValue = CKO_PRIVATE_KEY;
503
504 subject_attr->type = CKA_SUBJECT;
505 subject_attr->ulValueLen = 0; // empty string
506 subject_attr->pValue = NULL;
507
508 sensitive_attr->type = CKA_SENSITIVE;
509 sensitive_attr->ulValueLen = sizeof(CK_BBOOL);
510 sensitive_attr->pValue = (CK_BYTE *) sensitive_attr + sizeof(CK_ATTRIBUTE);
511 *(CK_BBOOL *) sensitive_attr->pValue = FALSE;
512
513 decrypt_attr->type = CKA_DECRYPT;
514 decrypt_attr->ulValueLen = sizeof(CK_BBOOL);
515 decrypt_attr->pValue = (CK_BYTE *) decrypt_attr + sizeof(CK_ATTRIBUTE);
516 *(CK_BBOOL *) decrypt_attr->pValue = TRUE;
517
518 sign_attr->type = CKA_SIGN;
519 sign_attr->ulValueLen = sizeof(CK_BBOOL);
520 sign_attr->pValue = (CK_BYTE *) sign_attr + sizeof(CK_ATTRIBUTE);
521 *(CK_BBOOL *) sign_attr->pValue = TRUE;
522
523 sign_recover_attr->type = CKA_SIGN_RECOVER;
524 sign_recover_attr->ulValueLen = sizeof(CK_BBOOL);
525 sign_recover_attr->pValue =
526 (CK_BYTE *) sign_recover_attr + sizeof(CK_ATTRIBUTE);
527 *(CK_BBOOL *) sign_recover_attr->pValue = TRUE;
528
529 unwrap_attr->type = CKA_UNWRAP;
530 unwrap_attr->ulValueLen = sizeof(CK_BBOOL);
531 unwrap_attr->pValue = (CK_BYTE *) unwrap_attr + sizeof(CK_ATTRIBUTE);
532 *(CK_BBOOL *) unwrap_attr->pValue = TRUE;
533
534 extractable_attr->type = CKA_EXTRACTABLE;
535 extractable_attr->ulValueLen = sizeof(CK_BBOOL);
536 extractable_attr->pValue =
537 (CK_BYTE *) extractable_attr + sizeof(CK_ATTRIBUTE);
538 *(CK_BBOOL *) extractable_attr->pValue = TRUE;
539
540 // by default, we'll set NEVER_EXTRACTABLE == FALSE and
541 // ALWAYS_SENSITIVE == FALSE
542 // If the key is being created with KEYGEN, it will adjust as necessary.
543 //
544 never_extr_attr->type = CKA_NEVER_EXTRACTABLE;
545 never_extr_attr->ulValueLen = sizeof(CK_BBOOL);
546 never_extr_attr->pValue =
547 (CK_BYTE *) never_extr_attr + sizeof(CK_ATTRIBUTE);
548 *(CK_BBOOL *) never_extr_attr->pValue = FALSE;
549
550 always_sens_attr->type = CKA_ALWAYS_SENSITIVE;
551 always_sens_attr->ulValueLen = sizeof(CK_BBOOL);
552 always_sens_attr->pValue =
553 (CK_BYTE *) always_sens_attr + sizeof(CK_ATTRIBUTE);
554 *(CK_BBOOL *) always_sens_attr->pValue = FALSE;
555
556 always_auth_attr->type = CKA_ALWAYS_AUTHENTICATE;
557 always_auth_attr->ulValueLen = sizeof(CK_BBOOL);
558 always_auth_attr->pValue =
559 (CK_BYTE *) always_auth_attr + sizeof(CK_ATTRIBUTE);
560 *(CK_BBOOL *) always_auth_attr->pValue = FALSE;
561
562 template_update_attribute(tmpl, class_attr);
563 template_update_attribute(tmpl, subject_attr);
564 template_update_attribute(tmpl, sensitive_attr);
565 template_update_attribute(tmpl, decrypt_attr);
566 template_update_attribute(tmpl, sign_attr);
567 template_update_attribute(tmpl, sign_recover_attr);
568 template_update_attribute(tmpl, unwrap_attr);
569 template_update_attribute(tmpl, extractable_attr);
570 template_update_attribute(tmpl, never_extr_attr);
571 template_update_attribute(tmpl, always_sens_attr);
572 template_update_attribute(tmpl, always_auth_attr);
573
574 return CKR_OK;
575 }
576
577
578 //
579 //
priv_key_unwrap(TEMPLATE * tmpl,CK_ULONG keytype,CK_BYTE * data,CK_ULONG data_len,CK_BBOOL isopaque)580 CK_RV priv_key_unwrap(TEMPLATE *tmpl,
581 CK_ULONG keytype,
582 CK_BYTE *data, CK_ULONG data_len, CK_BBOOL isopaque)
583 {
584 CK_ATTRIBUTE *extractable = NULL;
585 CK_ATTRIBUTE *always_sens = NULL;
586 CK_ATTRIBUTE *never_extract = NULL;
587 CK_ATTRIBUTE *sensitive = NULL;
588 CK_ATTRIBUTE *local = NULL;
589 CK_BBOOL true = TRUE;
590 CK_BBOOL false = FALSE;
591 CK_RV rc;
592
593 switch (keytype) {
594 case CKK_RSA:
595 rc = rsa_priv_unwrap(tmpl, data, data_len, isopaque);
596 break;
597 case CKK_DSA:
598 rc = dsa_priv_unwrap(tmpl, data, data_len);
599 break;
600 case CKK_DH:
601 rc = dh_priv_unwrap(tmpl, data, data_len);
602 break;
603 case CKK_EC:
604 rc = ec_priv_unwrap(tmpl, data, data_len, isopaque);
605 break;
606 default:
607 TRACE_ERROR("%s\n", ock_err(ERR_WRAPPED_KEY_INVALID));
608 return CKR_WRAPPED_KEY_INVALID;
609 }
610
611 if (rc != CKR_OK) {
612 TRACE_DEVEL("priv unwrap failed\n");
613 return rc;
614 }
615 // make sure
616 // CKA_LOCAL == FALSE
617 // CKA_ALWAYS_SENSITIVE == FALSE
618 // CKA_EXTRACTABLE == TRUE
619 // CKA_NEVER_EXTRACTABLE == FALSE
620 //
621 rc = build_attribute(CKA_LOCAL, &false, 1, &local);
622 if (rc != CKR_OK) {
623 TRACE_DEVEL("build_attribute failed\n");
624 goto cleanup;
625 }
626
627 rc = build_attribute(CKA_ALWAYS_SENSITIVE, &false, 1, &always_sens);
628 if (rc != CKR_OK) {
629 TRACE_DEVEL("build_attribute failed\n");
630 goto cleanup;
631 }
632
633 rc = build_attribute(CKA_SENSITIVE, &false, 1, &sensitive);
634 if (rc != CKR_OK) {
635 TRACE_DEVEL("build_attribute failed\n");
636 goto cleanup;
637 }
638
639 rc = build_attribute(CKA_EXTRACTABLE, &true, 1, &extractable);
640 if (rc != CKR_OK) {
641 TRACE_DEVEL("build_attribute failed\n");
642 goto cleanup;
643 }
644
645 rc = build_attribute(CKA_NEVER_EXTRACTABLE, &false, 1, &never_extract);
646 if (rc != CKR_OK) {
647 TRACE_DEVEL("build_attribute failed\n");
648 goto cleanup;
649 }
650
651 template_update_attribute(tmpl, local);
652 template_update_attribute(tmpl, always_sens);
653 template_update_attribute(tmpl, sensitive);
654 template_update_attribute(tmpl, extractable);
655 template_update_attribute(tmpl, never_extract);
656
657 return CKR_OK;
658
659 cleanup:
660 if (local)
661 free(local);
662 if (always_sens)
663 free(always_sens);
664 if (extractable)
665 free(extractable);
666 if (never_extract)
667 free(never_extract);
668
669 return rc;
670 }
671
672
673 // priv_key_validate_attribute()
674 //
priv_key_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)675 CK_RV priv_key_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
676 CK_ATTRIBUTE *attr, CK_ULONG mode)
677 {
678 switch (attr->type) {
679 case CKA_SUBJECT:
680 return CKR_OK;
681 case CKA_DECRYPT:
682 case CKA_SIGN:
683 case CKA_SIGN_RECOVER:
684 case CKA_UNWRAP:
685 // we might want to do this for MODE_COPY too
686 //
687 if (mode == MODE_MODIFY) {
688 if (tokdata->nv_token_data->tweak_vector.allow_key_mods == TRUE)
689 return CKR_OK;
690
691 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
692 return CKR_ATTRIBUTE_READ_ONLY;
693 }
694 return CKR_OK;
695 // after key creation, CKA_SENSITIVE may only be set to TRUE
696 //
697 case CKA_SENSITIVE:
698 {
699 CK_BBOOL value;
700
701 if (mode == MODE_CREATE || mode == MODE_KEYGEN)
702 return CKR_OK;
703
704 value = *(CK_BBOOL *) attr->pValue;
705 if (value != TRUE) {
706 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
707 return CKR_ATTRIBUTE_READ_ONLY;
708 }
709 return CKR_OK;
710 }
711 // after key creation, CKA_EXTRACTABLE may only be set to FALSE
712 //
713 case CKA_EXTRACTABLE:
714 {
715 CK_BBOOL value;
716
717 value = *(CK_BBOOL *) attr->pValue;
718 if ((mode != MODE_CREATE && mode != MODE_KEYGEN) &&
719 value != FALSE) {
720 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
721 return CKR_ATTRIBUTE_READ_ONLY;
722 }
723 if (value == FALSE) {
724 CK_ATTRIBUTE *attr;
725
726 attr =
727 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) +
728 sizeof(CK_BBOOL));
729 if (!attr) {
730 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
731 return CKR_HOST_MEMORY;
732 }
733 attr->type = CKA_NEVER_EXTRACTABLE;
734 attr->ulValueLen = sizeof(CK_BBOOL);
735 attr->pValue = (CK_BYTE *) attr + sizeof(CK_ATTRIBUTE);
736 *(CK_BBOOL *) attr->pValue = FALSE;
737
738 template_update_attribute(tmpl, attr);
739 }
740 return CKR_OK;
741 }
742 case CKA_ALWAYS_SENSITIVE:
743 case CKA_NEVER_EXTRACTABLE:
744 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
745 return CKR_ATTRIBUTE_READ_ONLY;
746 default:
747 return key_object_validate_attribute(tmpl, attr, mode);
748 }
749
750 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_TYPE_INVALID));
751
752 return CKR_ATTRIBUTE_TYPE_INVALID;
753 }
754
755
756
757
758 // secret_key_check_required_attributes()
759 //
secret_key_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)760 CK_RV secret_key_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
761 {
762 return key_object_check_required_attributes(tmpl, mode);
763 }
764
765
766 // secret_key_set_default_attributes()
767 //
768 // some of the common secret key attributes have defaults but none of the
769 // specific secret keytypes have default attributes
770 //
secret_key_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)771 CK_RV secret_key_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
772 {
773 CK_ATTRIBUTE *class_attr = NULL;
774 CK_ATTRIBUTE *sensitive_attr = NULL;
775 CK_ATTRIBUTE *encrypt_attr = NULL;
776 CK_ATTRIBUTE *decrypt_attr = NULL;
777 CK_ATTRIBUTE *sign_attr = NULL;
778 CK_ATTRIBUTE *verify_attr = NULL;
779 CK_ATTRIBUTE *wrap_attr = NULL;
780 CK_ATTRIBUTE *unwrap_attr = NULL;
781 CK_ATTRIBUTE *extractable_attr = NULL;
782 CK_ATTRIBUTE *never_extr_attr = NULL;
783 CK_ATTRIBUTE *always_sens_attr = NULL;
784 CK_RV rc;
785
786
787 rc = key_object_set_default_attributes(tmpl, mode);
788 if (rc != CKR_OK)
789 return rc;
790
791 // add the default CKO_DATA attributes
792 //
793 class_attr =
794 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS));
795 sensitive_attr =
796 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
797 encrypt_attr =
798 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
799 decrypt_attr =
800 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
801 sign_attr =
802 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
803 verify_attr =
804 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
805 wrap_attr =
806 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
807 unwrap_attr =
808 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
809 extractable_attr =
810 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
811 never_extr_attr =
812 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
813 always_sens_attr =
814 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
815
816 if (!class_attr || !sensitive_attr || !encrypt_attr || !decrypt_attr ||
817 !sign_attr || !verify_attr || !wrap_attr ||
818 !unwrap_attr || !extractable_attr || !never_extr_attr
819 || !always_sens_attr) {
820 if (class_attr)
821 free(class_attr);
822 if (sensitive_attr)
823 free(sensitive_attr);
824 if (encrypt_attr)
825 free(encrypt_attr);
826 if (decrypt_attr)
827 free(decrypt_attr);
828 if (sign_attr)
829 free(sign_attr);
830 if (verify_attr)
831 free(verify_attr);
832 if (wrap_attr)
833 free(wrap_attr);
834 if (unwrap_attr)
835 free(unwrap_attr);
836 if (extractable_attr)
837 free(extractable_attr);
838 if (never_extr_attr)
839 free(never_extr_attr);
840 if (always_sens_attr)
841 free(always_sens_attr);
842
843 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
844 return CKR_HOST_MEMORY;
845 }
846
847 class_attr->type = CKA_CLASS;
848 class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS);
849 class_attr->pValue = (CK_BYTE *) class_attr + sizeof(CK_ATTRIBUTE);
850 *(CK_OBJECT_CLASS *) class_attr->pValue = CKO_SECRET_KEY;
851
852 sensitive_attr->type = CKA_SENSITIVE;
853 sensitive_attr->ulValueLen = sizeof(CK_BBOOL);
854 sensitive_attr->pValue = (CK_BYTE *) sensitive_attr + sizeof(CK_ATTRIBUTE);
855 *(CK_BBOOL *) sensitive_attr->pValue = FALSE;
856
857 encrypt_attr->type = CKA_ENCRYPT;
858 encrypt_attr->ulValueLen = sizeof(CK_BBOOL);
859 encrypt_attr->pValue = (CK_BYTE *) encrypt_attr + sizeof(CK_ATTRIBUTE);
860 *(CK_BBOOL *) encrypt_attr->pValue = TRUE;
861
862 decrypt_attr->type = CKA_DECRYPT;
863 decrypt_attr->ulValueLen = sizeof(CK_BBOOL);
864 decrypt_attr->pValue = (CK_BYTE *) decrypt_attr + sizeof(CK_ATTRIBUTE);
865 *(CK_BBOOL *) decrypt_attr->pValue = TRUE;
866
867 sign_attr->type = CKA_SIGN;
868 sign_attr->ulValueLen = sizeof(CK_BBOOL);
869 sign_attr->pValue = (CK_BYTE *) sign_attr + sizeof(CK_ATTRIBUTE);
870 *(CK_BBOOL *) sign_attr->pValue = TRUE;
871
872 verify_attr->type = CKA_VERIFY;
873 verify_attr->ulValueLen = sizeof(CK_BBOOL);
874 verify_attr->pValue = (CK_BYTE *) verify_attr + sizeof(CK_ATTRIBUTE);
875 *(CK_BBOOL *) verify_attr->pValue = TRUE;
876
877 wrap_attr->type = CKA_WRAP;
878 wrap_attr->ulValueLen = sizeof(CK_BBOOL);
879 wrap_attr->pValue = (CK_BYTE *) wrap_attr + sizeof(CK_ATTRIBUTE);
880 *(CK_BBOOL *) wrap_attr->pValue = TRUE;
881
882 unwrap_attr->type = CKA_UNWRAP;
883 unwrap_attr->ulValueLen = sizeof(CK_BBOOL);
884 unwrap_attr->pValue = (CK_BYTE *) unwrap_attr + sizeof(CK_ATTRIBUTE);
885 *(CK_BBOOL *) unwrap_attr->pValue = TRUE;
886
887 extractable_attr->type = CKA_EXTRACTABLE;
888 extractable_attr->ulValueLen = sizeof(CK_BBOOL);
889 extractable_attr->pValue =
890 (CK_BYTE *) extractable_attr + sizeof(CK_ATTRIBUTE);
891 *(CK_BBOOL *) extractable_attr->pValue = TRUE;
892
893 // by default, we'll set NEVER_EXTRACTABLE == FALSE and
894 // ALWAYS_SENSITIVE == FALSE
895 // If the key is being created with KEYGEN, it will adjust as necessary.
896 //
897 always_sens_attr->type = CKA_ALWAYS_SENSITIVE;
898 always_sens_attr->ulValueLen = sizeof(CK_BBOOL);
899 always_sens_attr->pValue =
900 (CK_BYTE *) always_sens_attr + sizeof(CK_ATTRIBUTE);
901 *(CK_BBOOL *) always_sens_attr->pValue = FALSE;
902
903 never_extr_attr->type = CKA_NEVER_EXTRACTABLE;
904 never_extr_attr->ulValueLen = sizeof(CK_BBOOL);
905 never_extr_attr->pValue =
906 (CK_BYTE *) never_extr_attr + sizeof(CK_ATTRIBUTE);
907 *(CK_BBOOL *) never_extr_attr->pValue = FALSE;
908
909 template_update_attribute(tmpl, class_attr);
910 template_update_attribute(tmpl, sensitive_attr);
911 template_update_attribute(tmpl, encrypt_attr);
912 template_update_attribute(tmpl, decrypt_attr);
913 template_update_attribute(tmpl, sign_attr);
914 template_update_attribute(tmpl, verify_attr);
915 template_update_attribute(tmpl, wrap_attr);
916 template_update_attribute(tmpl, unwrap_attr);
917 template_update_attribute(tmpl, extractable_attr);
918 template_update_attribute(tmpl, never_extr_attr);
919 template_update_attribute(tmpl, always_sens_attr);
920
921 return CKR_OK;
922 }
923
924
925 //
926 //
secret_key_unwrap(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ULONG keytype,CK_BYTE * data,CK_ULONG data_len,CK_BBOOL fromend,CK_BBOOL isopaque)927 CK_RV secret_key_unwrap(STDLL_TokData_t *tokdata,
928 TEMPLATE *tmpl,
929 CK_ULONG keytype,
930 CK_BYTE *data,
931 CK_ULONG data_len, CK_BBOOL fromend, CK_BBOOL isopaque)
932 {
933 CK_ATTRIBUTE *local = NULL;
934 CK_ATTRIBUTE *always_sens = NULL;
935 CK_ATTRIBUTE *sensitive = NULL;
936 CK_ATTRIBUTE *extractable = NULL;
937 CK_ATTRIBUTE *never_extract = NULL;
938 CK_BBOOL true = TRUE;
939 CK_BBOOL false = FALSE;
940 CK_RV rc;
941
942 switch (keytype) {
943 case CKK_CDMF:
944 case CKK_DES:
945 rc = des_unwrap(tokdata, tmpl, data, data_len, fromend, isopaque);
946 break;
947 case CKK_DES3:
948 rc = des3_unwrap(tokdata, tmpl, data, data_len, fromend, isopaque);
949 break;
950 case CKK_AES:
951 rc = aes_unwrap(tokdata, tmpl, data, data_len, fromend, isopaque);
952 break;
953 case CKK_GENERIC_SECRET:
954 case CKK_RC2:
955 case CKK_RC4:
956 case CKK_RC5:
957 case CKK_CAST:
958 case CKK_CAST3:
959 case CKK_CAST5:
960 rc = generic_secret_unwrap(tmpl, data, data_len, fromend, isopaque);
961 break;
962 default:
963 TRACE_ERROR("%s\n", ock_err(ERR_WRAPPED_KEY_INVALID));
964 return CKR_WRAPPED_KEY_INVALID;
965 }
966
967 if (rc != CKR_OK)
968 return rc;
969
970 // make sure
971 // CKA_LOCAL == FALSE
972 // CKA_ALWAYS_SENSITIVE == FALSE
973 // CKA_EXTRACTABLE == TRUE
974 // CKA_NEVER_EXTRACTABLE == FALSE
975 //
976 rc = build_attribute(CKA_LOCAL, &false, 1, &local);
977 if (rc != CKR_OK) {
978 TRACE_DEVEL("build attribute failed\n");
979 goto cleanup;
980 }
981 rc = build_attribute(CKA_ALWAYS_SENSITIVE, &false, 1, &always_sens);
982 if (rc != CKR_OK) {
983 TRACE_DEVEL("build attribute failed\n");
984 goto cleanup;
985 }
986 rc = build_attribute(CKA_SENSITIVE, &false, 1, &sensitive);
987 if (rc != CKR_OK) {
988 TRACE_DEVEL("build_attribute failed\n");
989 goto cleanup;
990 }
991 rc = build_attribute(CKA_EXTRACTABLE, &true, 1, &extractable);
992 if (rc != CKR_OK) {
993 TRACE_DEVEL("build_attribute failed\n");
994 goto cleanup;
995 }
996 rc = build_attribute(CKA_NEVER_EXTRACTABLE, &false, 1, &never_extract);
997 if (rc != CKR_OK) {
998 TRACE_DEVEL("build_attribute failed\n");
999 goto cleanup;
1000 }
1001 template_update_attribute(tmpl, local);
1002 template_update_attribute(tmpl, always_sens);
1003 template_update_attribute(tmpl, sensitive);
1004 template_update_attribute(tmpl, extractable);
1005 template_update_attribute(tmpl, never_extract);
1006
1007 return CKR_OK;
1008
1009 cleanup:
1010 if (local)
1011 free(local);
1012 if (extractable)
1013 free(extractable);
1014 if (always_sens)
1015 free(always_sens);
1016 if (never_extract)
1017 free(never_extract);
1018
1019 return rc;
1020 }
1021
1022
1023
1024
1025 // secret_key_validate_attribute()
1026 //
secret_key_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)1027 CK_RV secret_key_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
1028 CK_ATTRIBUTE *attr, CK_ULONG mode)
1029 {
1030 switch (attr->type) {
1031 case CKA_ENCRYPT:
1032 case CKA_DECRYPT:
1033 case CKA_SIGN:
1034 case CKA_VERIFY:
1035 case CKA_WRAP:
1036 case CKA_UNWRAP:
1037 if (mode == MODE_MODIFY) {
1038 if (tokdata->nv_token_data->tweak_vector.allow_key_mods == TRUE)
1039 return CKR_OK;
1040
1041 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
1042 return CKR_ATTRIBUTE_READ_ONLY;
1043 }
1044 return CKR_OK;
1045 // after key creation, CKA_SENSITIVE may only be set to TRUE
1046 //
1047 case CKA_SENSITIVE:
1048 {
1049 CK_BBOOL value;
1050
1051 value = *(CK_BBOOL *) attr->pValue;
1052 if ((mode != MODE_CREATE && mode != MODE_DERIVE &&
1053 mode != MODE_KEYGEN) && (value != TRUE)) {
1054 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
1055 return CKR_ATTRIBUTE_READ_ONLY;
1056 }
1057 return CKR_OK;
1058 }
1059 // after key creation, CKA_EXTRACTABLE may only be set to FALSE
1060 //
1061 case CKA_EXTRACTABLE:
1062 {
1063 CK_BBOOL value;
1064
1065 // the unwrap routine will automatically set extractable to TRUE
1066 //
1067 value = *(CK_BBOOL *) attr->pValue;
1068 if ((mode != MODE_CREATE && mode != MODE_DERIVE &&
1069 mode != MODE_KEYGEN) && (value != FALSE)) {
1070 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
1071 return CKR_ATTRIBUTE_READ_ONLY;
1072 }
1073 if (value == FALSE) {
1074 CK_ATTRIBUTE *attr;
1075
1076 attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) +
1077 sizeof(CK_BBOOL));
1078 if (!attr) {
1079 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
1080 return CKR_HOST_MEMORY;
1081 }
1082 attr->type = CKA_NEVER_EXTRACTABLE;
1083 attr->ulValueLen = sizeof(CK_BBOOL);
1084 attr->pValue = (CK_BYTE *) attr + sizeof(CK_ATTRIBUTE);
1085 *(CK_BBOOL *) attr->pValue = FALSE;
1086
1087 template_update_attribute(tmpl, attr);
1088 }
1089 return CKR_OK;
1090 }
1091 case CKA_ALWAYS_SENSITIVE:
1092 case CKA_NEVER_EXTRACTABLE:
1093 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
1094 return CKR_ATTRIBUTE_READ_ONLY;
1095 default:
1096 return key_object_validate_attribute(tmpl, attr, mode);
1097 }
1098
1099 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_TYPE_INVALID));
1100
1101 return CKR_ATTRIBUTE_TYPE_INVALID;
1102 }
1103
1104
1105 // secret_key_check_exportability()
1106 //
secret_key_check_exportability(CK_ATTRIBUTE_TYPE type)1107 CK_BBOOL secret_key_check_exportability(CK_ATTRIBUTE_TYPE type)
1108 {
1109 switch (type) {
1110 case CKA_VALUE:
1111 TRACE_ERROR("%s\n", ock_err(ERR_KEY_UNEXTRACTABLE));
1112 return FALSE;
1113 }
1114
1115 return TRUE;
1116 }
1117
1118
1119 // rsa_publ_check_required_attributes()
1120 //
rsa_publ_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)1121 CK_RV rsa_publ_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
1122 {
1123 CK_ATTRIBUTE *attr = NULL;
1124 CK_BBOOL found;
1125
1126
1127 found = template_attribute_find(tmpl, CKA_MODULUS, &attr);
1128 if (!found) {
1129 if (mode == MODE_CREATE) {
1130 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
1131 return CKR_TEMPLATE_INCOMPLETE;
1132 }
1133 }
1134
1135 found = template_attribute_find(tmpl, CKA_MODULUS_BITS, &attr);
1136 if (!found) {
1137 if (mode == MODE_KEYGEN) {
1138 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
1139 return CKR_TEMPLATE_INCOMPLETE;
1140 }
1141 }
1142
1143 found = template_attribute_find(tmpl, CKA_PUBLIC_EXPONENT, &attr);
1144 if (!found) {
1145 if (mode == MODE_CREATE) {
1146 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
1147 return CKR_TEMPLATE_INCOMPLETE;
1148 }
1149 }
1150
1151 return publ_key_check_required_attributes(tmpl, mode);
1152 }
1153
1154
1155 // rsa_publ_set_default_attributes()
1156 //
rsa_publ_set_default_attributes(TEMPLATE * tmpl,TEMPLATE * basetmpl,CK_ULONG mode)1157 CK_RV rsa_publ_set_default_attributes(TEMPLATE *tmpl, TEMPLATE *basetmpl,
1158 CK_ULONG mode)
1159 {
1160 CK_ATTRIBUTE *type_attr = NULL;
1161 CK_ATTRIBUTE *modulus_attr = NULL;
1162 CK_ATTRIBUTE *modulus_bits_attr = NULL;
1163 CK_ATTRIBUTE *public_exp_attr = NULL;
1164 CK_ATTRIBUTE *tmpattr = NULL;
1165 CK_ULONG bits = 0L;
1166 CK_BYTE pubExp[3] = { 0x01, 0x00, 0x01 };
1167
1168 publ_key_set_default_attributes(tmpl, mode);
1169
1170 type_attr =
1171 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
1172 modulus_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
1173 modulus_bits_attr =
1174 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG));
1175 public_exp_attr =
1176 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(pubExp));
1177
1178 if (!type_attr || !modulus_attr || !modulus_bits_attr || !public_exp_attr) {
1179 if (type_attr)
1180 free(type_attr);
1181 if (modulus_attr)
1182 free(modulus_attr);
1183 if (modulus_bits_attr)
1184 free(modulus_bits_attr);
1185 if (public_exp_attr)
1186 free(public_exp_attr);
1187 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
1188
1189 return CKR_HOST_MEMORY;
1190 }
1191
1192 type_attr->type = CKA_KEY_TYPE;
1193 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
1194 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
1195 *(CK_KEY_TYPE *) type_attr->pValue = CKK_RSA;
1196
1197 modulus_attr->type = CKA_MODULUS;
1198 modulus_attr->ulValueLen = 0;
1199 modulus_attr->pValue = NULL;
1200
1201 modulus_bits_attr->type = CKA_MODULUS_BITS;
1202 modulus_bits_attr->ulValueLen = sizeof(CK_ULONG);
1203 modulus_bits_attr->pValue =
1204 (CK_BYTE *) modulus_bits_attr + sizeof(CK_ATTRIBUTE);
1205
1206 if (template_attribute_find(basetmpl, CKA_MODULUS, &tmpattr)) {
1207 *(CK_ULONG *) modulus_bits_attr->pValue = 8 * tmpattr->ulValueLen;
1208 } else {
1209 *(CK_ULONG *) modulus_bits_attr->pValue = bits;
1210 }
1211
1212 public_exp_attr->type = CKA_PUBLIC_EXPONENT;
1213 public_exp_attr->ulValueLen = sizeof(pubExp);
1214 public_exp_attr->pValue =
1215 (CK_BYTE *) public_exp_attr + sizeof(CK_ATTRIBUTE);
1216 memcpy(public_exp_attr->pValue, pubExp, sizeof(pubExp));
1217
1218 template_update_attribute(tmpl, type_attr);
1219 template_update_attribute(tmpl, modulus_attr);
1220 template_update_attribute(tmpl, modulus_bits_attr);
1221 template_update_attribute(tmpl, public_exp_attr);
1222
1223 return CKR_OK;
1224 }
1225
1226
1227 // rsa_publ_validate_attributes()
1228 //
rsa_publ_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)1229 CK_RV rsa_publ_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
1230 CK_ATTRIBUTE *attr, CK_ULONG mode)
1231 {
1232 switch (attr->type) {
1233 case CKA_MODULUS_BITS:
1234 if (mode == MODE_KEYGEN) {
1235 if (attr->ulValueLen != sizeof(CK_ULONG)) {
1236 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
1237 return CKR_ATTRIBUTE_VALUE_INVALID;
1238 } else {
1239 CK_ULONG mod_bits = *(CK_ULONG *) attr->pValue;
1240
1241 if (mod_bits < 512 || mod_bits > 4096) {
1242 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
1243 return CKR_ATTRIBUTE_VALUE_INVALID;
1244 }
1245
1246 if (mod_bits % 8 != 0) {
1247 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
1248 return CKR_ATTRIBUTE_VALUE_INVALID;
1249 }
1250 return CKR_OK;
1251 }
1252 }
1253 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
1254 return CKR_ATTRIBUTE_READ_ONLY;
1255 case CKA_MODULUS:
1256 if (mode == MODE_CREATE) {
1257 p11_attribute_trim(attr);
1258 return CKR_OK;
1259 }
1260 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
1261 return CKR_ATTRIBUTE_READ_ONLY;
1262 case CKA_PUBLIC_EXPONENT:
1263 if (mode == MODE_CREATE || mode == MODE_KEYGEN) {
1264 p11_attribute_trim(attr);
1265 return CKR_OK;
1266 }
1267 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
1268 return CKR_ATTRIBUTE_READ_ONLY;
1269 default:
1270 return publ_key_validate_attribute(tokdata, tmpl, attr, mode);
1271 }
1272 }
1273
1274
1275 // rsa_priv_check_required_attributes()
1276 //
rsa_priv_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)1277 CK_RV rsa_priv_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
1278 {
1279 CK_ATTRIBUTE *attr = NULL;
1280 CK_BBOOL found;
1281
1282
1283 found = template_attribute_find(tmpl, CKA_MODULUS, &attr);
1284 if (!found) {
1285 if (mode == MODE_CREATE) {
1286 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
1287 return CKR_TEMPLATE_INCOMPLETE;
1288 }
1289 }
1290 //
1291 // PKCS #11 is flexible with respect to which attributes must be present
1292 // in an RSA key. Keys can be specified in Chinese-Remainder format or
1293 // they can be specified in modular-exponent format. Right now, I only
1294 // support keys created in Chinese-Remainder format. That is, we return
1295 // CKR_TEMPLATE_INCOMPLETE if a modular-exponent key is specified. This
1296 // is allowed by PKCS #11.
1297 //
1298 // In the future, we should allow for creation of keys in modular-exponent
1299 // format too. This raises some issues. It's easy enough to recognize
1300 // when a key has been specified in modular-exponent format. And it's
1301 // easy enough to recognize when all attributes have been specified
1302 // (which is what we require right now). What's trickier to handle is
1303 // the "middle" cases in which more than the minimum yet less than the
1304 // full number of attributes have been specified. Do we revert back to
1305 // modular-exponent representation? Do we compute the missing attributes
1306 // ourselves? Do we simply return CKR_TEMPLATE_INCOMPLETE?
1307 //
1308
1309 found = template_attribute_find(tmpl, CKA_PUBLIC_EXPONENT, &attr);
1310 if (!found) {
1311 if (mode == MODE_CREATE) {
1312 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
1313 return CKR_TEMPLATE_INCOMPLETE;
1314 }
1315 }
1316
1317 found = template_attribute_find(tmpl, CKA_PRIVATE_EXPONENT, &attr);
1318 if (!found) {
1319 if (mode == MODE_CREATE) {
1320 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
1321 return CKR_TEMPLATE_INCOMPLETE;
1322 }
1323 }
1324
1325 found = template_attribute_find(tmpl, CKA_PRIME_1, &attr);
1326 if (!found) {
1327 if (mode == MODE_CREATE) {
1328 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
1329 return CKR_TEMPLATE_INCOMPLETE;
1330 }
1331 }
1332
1333 found = template_attribute_find(tmpl, CKA_PRIME_2, &attr);
1334 if (!found) {
1335 if (mode == MODE_CREATE) {
1336 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
1337 return CKR_TEMPLATE_INCOMPLETE;
1338 }
1339 }
1340
1341 found = template_attribute_find(tmpl, CKA_EXPONENT_1, &attr);
1342 if (!found) {
1343 if (mode == MODE_CREATE) {
1344 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
1345 return CKR_TEMPLATE_INCOMPLETE;
1346 }
1347 }
1348
1349 found = template_attribute_find(tmpl, CKA_EXPONENT_2, &attr);
1350 if (!found) {
1351 if (mode == MODE_CREATE) {
1352 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
1353 return CKR_TEMPLATE_INCOMPLETE;
1354 }
1355 }
1356
1357 found = template_attribute_find(tmpl, CKA_COEFFICIENT, &attr);
1358 if (!found) {
1359 if (mode == MODE_CREATE) {
1360 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
1361 return CKR_TEMPLATE_INCOMPLETE;
1362 }
1363 }
1364 // we should probably verify that the (e != p) and (e != q).
1365 // ie. gcd(e,n) == 1
1366 //
1367
1368 return priv_key_check_required_attributes(tmpl, mode);
1369 }
1370
1371
1372 // rsa_priv_set_default_attributes()
1373 //
rsa_priv_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)1374 CK_RV rsa_priv_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
1375 {
1376 CK_ATTRIBUTE *modulus_attr = NULL;
1377 CK_ATTRIBUTE *public_exp_attr = NULL;
1378 CK_ATTRIBUTE *private_exp_attr = NULL;
1379 CK_ATTRIBUTE *type_attr = NULL;
1380
1381 // satisfy the compiler
1382 //
1383 if (mode)
1384 modulus_attr = NULL;
1385
1386 priv_key_set_default_attributes(tmpl, mode);
1387
1388 type_attr =
1389 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
1390 modulus_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
1391 public_exp_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
1392 private_exp_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
1393
1394 if (!type_attr || !modulus_attr || !public_exp_attr || !private_exp_attr) {
1395 if (type_attr)
1396 free(type_attr);
1397 if (modulus_attr)
1398 free(modulus_attr);
1399 if (public_exp_attr)
1400 free(public_exp_attr);
1401 if (private_exp_attr)
1402 free(private_exp_attr);
1403
1404 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
1405 return CKR_HOST_MEMORY;
1406 }
1407
1408 modulus_attr->type = CKA_MODULUS;
1409 modulus_attr->ulValueLen = 0;
1410 modulus_attr->pValue = NULL;
1411
1412 public_exp_attr->type = CKA_PUBLIC_EXPONENT;
1413 public_exp_attr->ulValueLen = 0;
1414 public_exp_attr->pValue = NULL;
1415
1416 private_exp_attr->type = CKA_PRIVATE_EXPONENT;
1417 private_exp_attr->ulValueLen = 0;
1418 private_exp_attr->pValue = NULL;
1419
1420 type_attr->type = CKA_KEY_TYPE;
1421 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
1422 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
1423 *(CK_KEY_TYPE *) type_attr->pValue = CKK_RSA;
1424
1425 template_update_attribute(tmpl, type_attr);
1426 template_update_attribute(tmpl, modulus_attr);
1427 template_update_attribute(tmpl, public_exp_attr);
1428 template_update_attribute(tmpl, private_exp_attr);
1429
1430 return CKR_OK;
1431 }
1432
1433
1434 // rsa_priv_validate_attributes()
1435 //
rsa_priv_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)1436 CK_RV rsa_priv_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
1437 CK_ATTRIBUTE *attr, CK_ULONG mode)
1438 {
1439 switch (attr->type) {
1440 case CKA_MODULUS:
1441 case CKA_PRIVATE_EXPONENT:
1442 if (mode == MODE_CREATE) {
1443 p11_attribute_trim(attr);
1444 return CKR_OK;
1445 }
1446 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
1447 return CKR_ATTRIBUTE_READ_ONLY;
1448 case CKA_PUBLIC_EXPONENT:
1449 case CKA_PRIME_1:
1450 case CKA_PRIME_2:
1451 case CKA_EXPONENT_1:
1452 case CKA_EXPONENT_2:
1453 case CKA_COEFFICIENT:
1454 if (mode == MODE_CREATE) {
1455 p11_attribute_trim(attr);
1456 return CKR_OK;
1457 }
1458 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
1459 return CKR_ATTRIBUTE_READ_ONLY;
1460 default:
1461 return priv_key_validate_attribute(tokdata, tmpl, attr, mode);
1462 }
1463 }
1464
1465
1466 // rsa_priv_check_exportability()
1467 //
rsa_priv_check_exportability(CK_ATTRIBUTE_TYPE type)1468 CK_BBOOL rsa_priv_check_exportability(CK_ATTRIBUTE_TYPE type)
1469 {
1470 switch (type) {
1471 case CKA_PRIVATE_EXPONENT:
1472 case CKA_PRIME_1:
1473 case CKA_PRIME_2:
1474 case CKA_EXPONENT_1:
1475 case CKA_EXPONENT_2:
1476 case CKA_COEFFICIENT:
1477 TRACE_ERROR("%s\n", ock_err(ERR_KEY_UNEXTRACTABLE));
1478 return FALSE;
1479 }
1480
1481 return TRUE;
1482 }
1483
1484
1485 // create the ASN.1 encoding for the private key for wrapping as defined
1486 // in PKCS #8
1487 //
1488 // ASN.1 type PrivateKeyInfo ::= SEQUENCE {
1489 // version Version
1490 // privateKeyAlgorithm PrivateKeyAlgorithmIdentifier
1491 // privateKey PrivateKey
1492 // attributes OPTIONAL
1493 // }
1494 //
1495 // Where PrivateKey is defined as follows for RSA:
1496 //
1497 // ASN.1 type RSAPrivateKey
1498 //
1499 // RSAPrivateKey ::= SEQUENCE {
1500 // version Version
1501 // modulus INTEGER
1502 // publicExponent INTEGER
1503 // privateExponent INTEGER
1504 // prime1 INTEGER
1505 // prime2 INTEGER
1506 // exponent1 INTEGER
1507 // exponent2 INTEGER
1508 // coefficient INTEGER
1509 // }
1510 //
rsa_priv_wrap_get_data(TEMPLATE * tmpl,CK_BBOOL length_only,CK_BYTE ** data,CK_ULONG * data_len)1511 CK_RV rsa_priv_wrap_get_data(TEMPLATE *tmpl,
1512 CK_BBOOL length_only,
1513 CK_BYTE **data, CK_ULONG *data_len)
1514 {
1515 CK_ATTRIBUTE *modulus = NULL;
1516 CK_ATTRIBUTE *publ_exp = NULL, *priv_exp = NULL;
1517 CK_ATTRIBUTE *prime1 = NULL, *prime2 = NULL;
1518 CK_ATTRIBUTE *exponent1 = NULL, *exponent2 = NULL;
1519 CK_ATTRIBUTE *coeff = NULL;
1520 CK_ATTRIBUTE *opaque = NULL;
1521 CK_RV rc;
1522
1523
1524 // compute the total length of the BER-encoded data
1525 //
1526 if (template_attribute_find(tmpl, CKA_MODULUS, &modulus) == FALSE) {
1527 TRACE_ERROR("Could not find CKA_MODULUS for the key.\n");
1528 return CKR_FUNCTION_FAILED;
1529 }
1530 if (template_attribute_find(tmpl, CKA_PUBLIC_EXPONENT, &publ_exp) == FALSE) {
1531 TRACE_ERROR("Could not find CKA_PUBLIC_EXPONENT for the key.\n");
1532 return CKR_FUNCTION_FAILED;
1533 }
1534 // CKA_IBM_OPAQUE is used for secure key, if it is not available, then
1535 // assume using clear key and get rest of attributes required for clear key.
1536
1537 if (template_attribute_find(tmpl, CKA_IBM_OPAQUE, &opaque) == FALSE) {
1538 if (template_attribute_find(tmpl, CKA_PRIVATE_EXPONENT, &priv_exp) ==
1539 FALSE) {
1540 TRACE_ERROR("Could not find private exponent for the key.\n");
1541 return CKR_FUNCTION_FAILED;
1542 }
1543 if (template_attribute_find(tmpl, CKA_PRIME_1, &prime1) == FALSE) {
1544 TRACE_ERROR("Could not find CKA_PRIME_1 for the key.\n");
1545 return CKR_FUNCTION_FAILED;
1546 }
1547 if (template_attribute_find(tmpl, CKA_PRIME_2, &prime2) == FALSE) {
1548 TRACE_ERROR("Could not find CKA_PRIME_2 for the key.\n");
1549 return CKR_FUNCTION_FAILED;
1550 }
1551 if (template_attribute_find(tmpl, CKA_EXPONENT_1, &exponent1) == FALSE) {
1552 TRACE_ERROR("Could not find CKA_EXPONENT_1 for the key.\n");
1553 return CKR_FUNCTION_FAILED;
1554 }
1555 if (template_attribute_find(tmpl, CKA_EXPONENT_2, &exponent2) == FALSE) {
1556 TRACE_ERROR("Could not find CKA_EXPONENT_2 for the key.\n");
1557 return CKR_FUNCTION_FAILED;
1558 }
1559 if (template_attribute_find(tmpl, CKA_COEFFICIENT, &coeff) == FALSE) {
1560 TRACE_ERROR("Could not find CKA_COEFFICIENT for the key.\n");
1561 return CKR_FUNCTION_FAILED;
1562 }
1563 }
1564
1565 rc = ber_encode_RSAPrivateKey(length_only, data, data_len, modulus,
1566 publ_exp, priv_exp, prime1, prime2,
1567 exponent1, exponent2, coeff, opaque);
1568 if (rc != CKR_OK) {
1569 TRACE_DEVEL("ber_encode_RSAPrivateKey failed\n");
1570 }
1571
1572 return rc;
1573 }
1574
1575
1576 //
1577 //
rsa_priv_unwrap(TEMPLATE * tmpl,CK_BYTE * data,CK_ULONG total_length,CK_BBOOL isopaque)1578 CK_RV rsa_priv_unwrap(TEMPLATE *tmpl,
1579 CK_BYTE *data, CK_ULONG total_length, CK_BBOOL isopaque)
1580 {
1581 CK_ATTRIBUTE *modulus = NULL;
1582 CK_ATTRIBUTE *publ_exp = NULL;
1583 CK_ATTRIBUTE *priv_exp = NULL;
1584 CK_ATTRIBUTE *prime1 = NULL;
1585 CK_ATTRIBUTE *prime2 = NULL;
1586 CK_ATTRIBUTE *exponent1 = NULL;
1587 CK_ATTRIBUTE *exponent2 = NULL;
1588 CK_ATTRIBUTE *coeff = NULL;
1589 CK_ATTRIBUTE *opaque = NULL;
1590 CK_RV rc;
1591
1592 rc = ber_decode_RSAPrivateKey(data,
1593 total_length,
1594 &modulus,
1595 &publ_exp,
1596 &priv_exp,
1597 &prime1,
1598 &prime2,
1599 &exponent1,
1600 &exponent2, &coeff, &opaque, isopaque);
1601
1602 if (rc != CKR_OK) {
1603 TRACE_DEVEL("ber_decode_RSAPrivateKey failed\n");
1604 return rc;
1605 }
1606 p11_attribute_trim(modulus);
1607 p11_attribute_trim(publ_exp);
1608 if (isopaque) {
1609 p11_attribute_trim(opaque);
1610 } else {
1611 p11_attribute_trim(priv_exp);
1612 p11_attribute_trim(prime1);
1613 p11_attribute_trim(prime2);
1614 p11_attribute_trim(exponent1);
1615 p11_attribute_trim(exponent2);
1616 p11_attribute_trim(coeff);
1617 }
1618
1619 template_update_attribute(tmpl, modulus);
1620 template_update_attribute(tmpl, publ_exp);
1621 if (isopaque) {
1622 template_update_attribute(tmpl, opaque);
1623 } else {
1624 template_update_attribute(tmpl, priv_exp);
1625 template_update_attribute(tmpl, prime1);
1626 template_update_attribute(tmpl, prime2);
1627 template_update_attribute(tmpl, exponent1);
1628 template_update_attribute(tmpl, exponent2);
1629 template_update_attribute(tmpl, coeff);
1630 }
1631
1632 return CKR_OK;
1633 }
1634
1635 /*
1636 * create the ASN.1 encoding for the private key for wrapping as defined
1637 * in PKCS #8
1638 *
1639 * ASN.1 type PrivateKeyInfo ::= SEQUENCE {
1640 * version Version
1641 * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier
1642 * privateKey PrivateKey
1643 * attributes OPTIONAL
1644 * }
1645 *
1646 * Where PrivateKey is defined as follows for EC:
1647 *
1648 * ASN.1 type RSAPrivateKey
1649 *
1650 * ECPrivateKey ::= SEQUENCE {
1651 * version Version
1652 * privateKey OCTET STRING
1653 * parameters [0] ECParameters (OPTIONAL)
1654 * publicKey [1] BIT STRING (OPTIONAL)
1655 * }
1656 */
ecdsa_priv_wrap_get_data(TEMPLATE * tmpl,CK_BBOOL length_only,CK_BYTE ** data,CK_ULONG * data_len)1657 CK_RV ecdsa_priv_wrap_get_data(TEMPLATE *tmpl,
1658 CK_BBOOL length_only,
1659 CK_BYTE **data, CK_ULONG *data_len)
1660 {
1661 CK_ATTRIBUTE *params = NULL;
1662 CK_ATTRIBUTE *point = NULL;
1663 CK_ATTRIBUTE *opaque = NULL;
1664 CK_ATTRIBUTE *pubkey = NULL;
1665 CK_RV rc;
1666
1667
1668 // compute the total length of the BER-encoded data
1669 //
1670 if (template_attribute_find(tmpl, CKA_EC_PARAMS, ¶ms) == FALSE) {
1671 TRACE_ERROR("Could not find CKA_EC_PARAMS for the key.\n");
1672 return CKR_FUNCTION_FAILED;
1673 }
1674 if (template_attribute_find(tmpl, CKA_VALUE, &point) == FALSE) {
1675 TRACE_ERROR("Could not find CKA_EC_POINT for the key.\n");
1676 return CKR_FUNCTION_FAILED;
1677 }
1678 // CKA_IBM_OPAQUE is used for secure key, if it is not available, then
1679 // assume using clear key and get rest of attributes required for clear key.
1680
1681 if (template_attribute_find(tmpl, CKA_IBM_OPAQUE, &opaque) == FALSE) {
1682 if (template_attribute_find(tmpl, CKA_VALUE, &point) == FALSE) {
1683 TRACE_ERROR("Could not find EC Point for the key.\n");
1684 return CKR_FUNCTION_FAILED;
1685 }
1686 }
1687
1688 /* check if optional public-key part was defined */
1689 template_attribute_find(tmpl, CKA_EC_POINT, &pubkey);
1690
1691 rc = der_encode_ECPrivateKey(length_only, data, data_len, params,
1692 point, opaque, pubkey);
1693 if (rc != CKR_OK) {
1694 TRACE_DEVEL("der_encode_ECPrivateKey failed\n");
1695 }
1696
1697 return rc;
1698 }
1699
1700
1701 // dsa_publ_check_required_attributes()
1702 //
dsa_publ_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)1703 CK_RV dsa_publ_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
1704 {
1705 CK_ATTRIBUTE *attr = NULL;
1706 CK_BBOOL found;
1707
1708
1709 found = template_attribute_find(tmpl, CKA_PRIME, &attr);
1710 if (!found) {
1711 if (mode == MODE_CREATE || mode == MODE_KEYGEN) {
1712 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
1713 return CKR_TEMPLATE_INCOMPLETE;
1714 }
1715 }
1716 found = template_attribute_find(tmpl, CKA_SUBPRIME, &attr);
1717 if (!found) {
1718 if (mode == MODE_CREATE || mode == MODE_KEYGEN) {
1719 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
1720 return CKR_TEMPLATE_INCOMPLETE;
1721 }
1722 }
1723
1724 found = template_attribute_find(tmpl, CKA_BASE, &attr);
1725 if (!found) {
1726 if (mode == MODE_CREATE || mode == MODE_KEYGEN) {
1727 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
1728 return CKR_TEMPLATE_INCOMPLETE;
1729 }
1730 }
1731
1732 found = template_attribute_find(tmpl, CKA_VALUE, &attr);
1733 if (!found) {
1734 if (mode == MODE_CREATE) {
1735 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
1736 return CKR_TEMPLATE_INCOMPLETE;
1737 }
1738 }
1739
1740 return publ_key_check_required_attributes(tmpl, mode);
1741 }
1742
1743
1744 // dsa_publ_set_default_attributes()
1745 //
dsa_publ_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)1746 CK_RV dsa_publ_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
1747 {
1748 CK_ATTRIBUTE *prime_attr = NULL;
1749 CK_ATTRIBUTE *subprime_attr = NULL;
1750 CK_ATTRIBUTE *base_attr = NULL;
1751 CK_ATTRIBUTE *value_attr = NULL;
1752 CK_ATTRIBUTE *type_attr = NULL;
1753
1754 if (mode)
1755 prime_attr = NULL;
1756
1757 publ_key_set_default_attributes(tmpl, mode);
1758
1759 type_attr =
1760 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
1761 prime_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
1762 subprime_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
1763 base_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
1764 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
1765
1766 if (!type_attr || !prime_attr || !subprime_attr || !base_attr
1767 || !value_attr) {
1768 if (type_attr)
1769 free(type_attr);
1770 if (prime_attr)
1771 free(prime_attr);
1772 if (subprime_attr)
1773 free(subprime_attr);
1774 if (base_attr)
1775 free(base_attr);
1776 if (value_attr)
1777 free(value_attr);
1778 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
1779
1780 return CKR_HOST_MEMORY;
1781 }
1782
1783 prime_attr->type = CKA_PRIME;
1784 prime_attr->ulValueLen = 0;
1785 prime_attr->pValue = NULL;
1786
1787 subprime_attr->type = CKA_SUBPRIME;
1788 subprime_attr->ulValueLen = 0;
1789 subprime_attr->pValue = NULL;
1790
1791 base_attr->type = CKA_BASE;
1792 base_attr->ulValueLen = 0;
1793 base_attr->pValue = NULL;
1794
1795 value_attr->type = CKA_VALUE;
1796 value_attr->ulValueLen = 0;
1797 value_attr->pValue = NULL;
1798
1799 type_attr->type = CKA_KEY_TYPE;
1800 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
1801 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
1802 *(CK_KEY_TYPE *) type_attr->pValue = CKK_DSA;
1803
1804 template_update_attribute(tmpl, type_attr);
1805 template_update_attribute(tmpl, prime_attr);
1806 template_update_attribute(tmpl, subprime_attr);
1807 template_update_attribute(tmpl, base_attr);
1808 template_update_attribute(tmpl, value_attr);
1809
1810 return CKR_OK;
1811 }
1812
1813
1814 // dsa_publ_validate_attributes()
1815 //
dsa_publ_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)1816 CK_RV dsa_publ_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
1817 CK_ATTRIBUTE *attr, CK_ULONG mode)
1818 {
1819 switch (attr->type) {
1820 case CKA_PRIME:
1821 {
1822 CK_ULONG size;
1823
1824 if (mode != MODE_CREATE && mode != MODE_KEYGEN) {
1825 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
1826 return CKR_ATTRIBUTE_READ_ONLY;
1827 }
1828 // must be between [512, 1024] bits, and a multiple of 64 bits
1829 //
1830 size = attr->ulValueLen;
1831 if (size < 64 || size > 128 || (size % 8 != 0)) {
1832 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
1833 return CKR_ATTRIBUTE_VALUE_INVALID;
1834 }
1835 p11_attribute_trim(attr);
1836 return CKR_OK;
1837 }
1838 case CKA_SUBPRIME:
1839 if (mode != MODE_CREATE && mode != MODE_KEYGEN) {
1840 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
1841 return CKR_ATTRIBUTE_READ_ONLY;
1842 }
1843 // subprime must be 160 bits
1844 //
1845 if (attr->ulValueLen != 20) {
1846 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
1847 return CKR_ATTRIBUTE_VALUE_INVALID;
1848 }
1849 p11_attribute_trim(attr);
1850 return CKR_OK;
1851 case CKA_BASE:
1852 if (mode == MODE_CREATE || mode == MODE_KEYGEN) {
1853 p11_attribute_trim(attr);
1854 return CKR_OK;
1855 }
1856 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
1857 return CKR_ATTRIBUTE_READ_ONLY;
1858 case CKA_VALUE:
1859 if (mode == MODE_CREATE) {
1860 p11_attribute_trim(attr);
1861 return CKR_OK;
1862 }
1863 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
1864 return CKR_ATTRIBUTE_READ_ONLY;
1865 default:
1866 return publ_key_validate_attribute(tokdata, tmpl, attr, mode);
1867 }
1868 }
1869
1870
1871 // dsa_priv_check_required_attributes()
1872 //
dsa_priv_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)1873 CK_RV dsa_priv_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
1874 {
1875 CK_ATTRIBUTE *attr = NULL;
1876 CK_BBOOL found;
1877
1878
1879 found = template_attribute_find(tmpl, CKA_PRIME, &attr);
1880 if (!found) {
1881 if (mode == MODE_CREATE) {
1882 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
1883 return CKR_TEMPLATE_INCOMPLETE;
1884 }
1885 }
1886
1887 found = template_attribute_find(tmpl, CKA_SUBPRIME, &attr);
1888 if (!found) {
1889 if (mode == MODE_CREATE) {
1890 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
1891 return CKR_TEMPLATE_INCOMPLETE;
1892 }
1893 }
1894
1895 found = template_attribute_find(tmpl, CKA_BASE, &attr);
1896 if (!found) {
1897 if (mode == MODE_CREATE) {
1898 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
1899 return CKR_TEMPLATE_INCOMPLETE;
1900 }
1901 }
1902
1903 found = template_attribute_find(tmpl, CKA_VALUE, &attr);
1904 if (!found) {
1905 if (mode == MODE_CREATE) {
1906 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
1907 return CKR_TEMPLATE_INCOMPLETE;
1908 }
1909 }
1910
1911 return priv_key_check_required_attributes(tmpl, mode);
1912 }
1913
1914
1915 // dsa_priv_set_default_attributes()
1916 //
dsa_priv_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)1917 CK_RV dsa_priv_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
1918 {
1919 CK_ATTRIBUTE *prime_attr = NULL;
1920 CK_ATTRIBUTE *subprime_attr = NULL;
1921 CK_ATTRIBUTE *base_attr = NULL;
1922 CK_ATTRIBUTE *value_attr = NULL;
1923 CK_ATTRIBUTE *type_attr = NULL;
1924
1925 if (mode)
1926 prime_attr = NULL;
1927
1928 priv_key_set_default_attributes(tmpl, mode);
1929
1930 type_attr =
1931 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
1932 prime_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
1933 subprime_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
1934 base_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
1935 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
1936
1937 if (!type_attr || !prime_attr || !subprime_attr || !base_attr
1938 || !value_attr) {
1939 if (type_attr)
1940 free(type_attr);
1941 if (prime_attr)
1942 free(prime_attr);
1943 if (subprime_attr)
1944 free(subprime_attr);
1945 if (base_attr)
1946 free(base_attr);
1947 if (value_attr)
1948 free(value_attr);
1949
1950 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
1951
1952 return CKR_HOST_MEMORY;
1953 }
1954
1955 prime_attr->type = CKA_PRIME;
1956 prime_attr->ulValueLen = 0;
1957 prime_attr->pValue = NULL;
1958
1959 subprime_attr->type = CKA_SUBPRIME;
1960 subprime_attr->ulValueLen = 0;
1961 subprime_attr->pValue = NULL;
1962
1963 base_attr->type = CKA_BASE;
1964 base_attr->ulValueLen = 0;
1965 base_attr->pValue = NULL;
1966
1967 value_attr->type = CKA_VALUE;
1968 value_attr->ulValueLen = 0;
1969 value_attr->pValue = NULL;
1970
1971 type_attr->type = CKA_KEY_TYPE;
1972 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
1973 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
1974 *(CK_KEY_TYPE *) type_attr->pValue = CKK_DSA;
1975
1976 template_update_attribute(tmpl, type_attr);
1977 template_update_attribute(tmpl, prime_attr);
1978 template_update_attribute(tmpl, subprime_attr);
1979 template_update_attribute(tmpl, base_attr);
1980 template_update_attribute(tmpl, value_attr);
1981
1982 return CKR_OK;
1983 }
1984
1985
1986 // dsa_priv_validate_attributes()
1987 //
dsa_priv_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)1988 CK_RV dsa_priv_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
1989 CK_ATTRIBUTE *attr, CK_ULONG mode)
1990 {
1991 switch (attr->type) {
1992 case CKA_PRIME:
1993 {
1994 CK_ULONG size;
1995
1996 if (mode != MODE_CREATE) {
1997 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
1998 return CKR_ATTRIBUTE_READ_ONLY;
1999 }
2000 // must be between [512, 1024] bits, and a multiple of 64 bits
2001 //
2002 size = attr->ulValueLen;
2003 if (size < 64 || size > 128 || (size % 8 != 0)) {
2004 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
2005 return CKR_ATTRIBUTE_VALUE_INVALID;
2006 }
2007 p11_attribute_trim(attr);
2008 return CKR_OK;
2009 }
2010 case CKA_SUBPRIME:
2011 if (mode != MODE_CREATE) {
2012 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
2013 return CKR_ATTRIBUTE_READ_ONLY;
2014 }
2015 // subprime must be 160 bits
2016 //
2017 if (attr->ulValueLen != 20) {
2018 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
2019 return CKR_ATTRIBUTE_VALUE_INVALID;
2020 }
2021 p11_attribute_trim(attr);
2022 return CKR_OK;
2023 case CKA_BASE:
2024 case CKA_VALUE:
2025 if (mode == MODE_CREATE) {
2026 p11_attribute_trim(attr);
2027 return CKR_OK;
2028 }
2029 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
2030 return CKR_ATTRIBUTE_READ_ONLY;
2031 default:
2032 return priv_key_validate_attribute(tokdata, tmpl, attr, mode);
2033 }
2034 }
2035
2036
2037 // dsa_priv_check_exportability()
2038 //
dsa_priv_check_exportability(CK_ATTRIBUTE_TYPE type)2039 CK_BBOOL dsa_priv_check_exportability(CK_ATTRIBUTE_TYPE type)
2040 {
2041 switch (type) {
2042 case CKA_VALUE:
2043 return FALSE;
2044 }
2045
2046 return TRUE;
2047 }
2048
2049
2050 // create the ASN.1 encoding for the private key for wrapping as defined
2051 // in PKCS #8
2052 //
2053 // ASN.1 type PrivateKeyInfo ::= SEQUENCE {
2054 // version Version
2055 // privateKeyAlgorithm PrivateKeyAlgorithmIdentifier
2056 // privateKey PrivateKey
2057 // attributes OPTIONAL
2058 // }
2059 //
2060 // PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
2061 //
2062 // AlgorithmIdentifier ::= SEQUENCE {
2063 // algorithm OBJECT IDENTIFIER
2064 // parameters ANY DEFINED BY algorithm OPTIONAL
2065 // }
2066 //
2067 // paramters ::= SEQUENCE {
2068 // p INTEGER
2069 // q INTEGER
2070 // g INTEGER
2071 // }
2072 //
2073 // privateKey ::= INTEGER
2074 //
2075 //
dsa_priv_wrap_get_data(TEMPLATE * tmpl,CK_BBOOL length_only,CK_BYTE ** data,CK_ULONG * data_len)2076 CK_RV dsa_priv_wrap_get_data(TEMPLATE *tmpl,
2077 CK_BBOOL length_only,
2078 CK_BYTE **data, CK_ULONG *data_len)
2079 {
2080 CK_ATTRIBUTE *prime = NULL;
2081 CK_ATTRIBUTE *subprime = NULL;
2082 CK_ATTRIBUTE *base = NULL;
2083 CK_ATTRIBUTE *value = NULL;
2084 CK_RV rc;
2085
2086
2087 // compute the total length of the BER-encoded data
2088 //
2089 if (template_attribute_find(tmpl, CKA_PRIME, &prime) == FALSE) {
2090 TRACE_ERROR("Could not find CKA_PRIME for the key.\n");
2091 return CKR_FUNCTION_FAILED;
2092 }
2093 if (template_attribute_find(tmpl, CKA_SUBPRIME, &subprime) == FALSE) {
2094 TRACE_ERROR("Could not find CKA_SUBPRIME for the key.\n");
2095 return CKR_FUNCTION_FAILED;
2096 }
2097 if (template_attribute_find(tmpl, CKA_BASE, &base) == FALSE) {
2098 TRACE_ERROR("Could not find CKA_BASE for the key.\n");
2099 return CKR_FUNCTION_FAILED;
2100 }
2101 if (template_attribute_find(tmpl, CKA_VALUE, &value) == FALSE) {
2102 TRACE_ERROR("Could not find CKA_VALUE for the key.\n");
2103 return CKR_FUNCTION_FAILED;
2104 }
2105 rc = ber_encode_DSAPrivateKey(length_only, data, data_len,
2106 prime, subprime, base, value);
2107 if (rc != CKR_OK)
2108 TRACE_DEVEL("ber_encode_DSAPrivateKe failed\n");
2109
2110 return rc;
2111 }
2112
2113
2114 //
2115 //
dsa_priv_unwrap(TEMPLATE * tmpl,CK_BYTE * data,CK_ULONG total_length)2116 CK_RV dsa_priv_unwrap(TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG total_length)
2117 {
2118 CK_ATTRIBUTE *prime = NULL;
2119 CK_ATTRIBUTE *subprime = NULL;
2120 CK_ATTRIBUTE *base = NULL;
2121 CK_ATTRIBUTE *value = NULL;
2122 CK_RV rc;
2123
2124 rc = ber_decode_DSAPrivateKey(data, total_length,
2125 &prime, &subprime, &base, &value);
2126
2127 if (rc != CKR_OK) {
2128 TRACE_DEVEL("ber_decode_DSAPrivateKey failed\n");
2129 return rc;
2130 }
2131 p11_attribute_trim(prime);
2132 p11_attribute_trim(subprime);
2133 p11_attribute_trim(base);
2134 p11_attribute_trim(value);
2135
2136 template_update_attribute(tmpl, prime);
2137 template_update_attribute(tmpl, subprime);
2138 template_update_attribute(tmpl, base);
2139 template_update_attribute(tmpl, value);
2140
2141 return CKR_OK;
2142 }
2143
2144
2145 // ecdsa_publ_check_required_attributes()
2146 //
ecdsa_publ_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)2147 CK_RV ecdsa_publ_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
2148 {
2149 CK_ATTRIBUTE *attr = NULL;
2150 CK_BBOOL found;
2151
2152
2153 found = template_attribute_find(tmpl, CKA_ECDSA_PARAMS, &attr);
2154 if (!found) {
2155 if (mode == MODE_CREATE || mode == MODE_KEYGEN) {
2156 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
2157 return CKR_TEMPLATE_INCOMPLETE;
2158 }
2159 }
2160
2161 found = template_attribute_find(tmpl, CKA_EC_POINT, &attr);
2162 if (!found) {
2163 if (mode == MODE_CREATE) {
2164 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
2165 return CKR_TEMPLATE_INCOMPLETE;
2166 }
2167 }
2168
2169 return publ_key_check_required_attributes(tmpl, mode);
2170 }
2171
2172
2173 // ecdsa_publ_set_default_attributes()
2174 //
ecdsa_publ_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)2175 CK_RV ecdsa_publ_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
2176 {
2177 CK_ATTRIBUTE *params_attr = NULL;
2178 CK_ATTRIBUTE *ec_point_attr = NULL;
2179 CK_ATTRIBUTE *type_attr = NULL;
2180
2181 if (mode)
2182 params_attr = NULL;
2183
2184 publ_key_set_default_attributes(tmpl, mode);
2185
2186 type_attr =
2187 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
2188 params_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
2189 ec_point_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
2190
2191 if (!type_attr || !params_attr || !ec_point_attr) {
2192 if (type_attr)
2193 free(type_attr);
2194 if (params_attr)
2195 free(params_attr);
2196 if (ec_point_attr)
2197 free(ec_point_attr);
2198 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2199
2200 return CKR_HOST_MEMORY;
2201 }
2202
2203 params_attr->type = CKA_ECDSA_PARAMS;
2204 params_attr->ulValueLen = 0;
2205 params_attr->pValue = NULL;
2206
2207 ec_point_attr->type = CKA_EC_POINT;
2208 ec_point_attr->ulValueLen = 0;
2209 ec_point_attr->pValue = NULL;
2210
2211 type_attr->type = CKA_KEY_TYPE;
2212 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
2213 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
2214 *(CK_KEY_TYPE *) type_attr->pValue = CKK_ECDSA;
2215
2216 template_update_attribute(tmpl, type_attr);
2217 template_update_attribute(tmpl, params_attr);
2218 template_update_attribute(tmpl, ec_point_attr);
2219
2220 return CKR_OK;
2221 }
2222
2223
2224 // ecdsa_publ_validate_attributes()
2225 //
ecdsa_publ_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)2226 CK_RV ecdsa_publ_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
2227 CK_ATTRIBUTE *attr, CK_ULONG mode)
2228 {
2229 switch (attr->type) {
2230 case CKA_ECDSA_PARAMS:
2231 if (mode == MODE_CREATE || mode == MODE_KEYGEN)
2232 return CKR_OK;
2233
2234 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
2235 return CKR_ATTRIBUTE_READ_ONLY;
2236 case CKA_EC_POINT:
2237 if (mode == MODE_CREATE)
2238 return CKR_OK;
2239
2240 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
2241 return CKR_ATTRIBUTE_READ_ONLY;
2242 default:
2243 return publ_key_validate_attribute(tokdata, tmpl, attr, mode);
2244 }
2245 }
2246
2247
2248 // ecdsa_priv_check_required_attributes()
2249 //
ecdsa_priv_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)2250 CK_RV ecdsa_priv_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
2251 {
2252 CK_ATTRIBUTE *attr = NULL;
2253 CK_BBOOL found;
2254
2255
2256 found = template_attribute_find(tmpl, CKA_ECDSA_PARAMS, &attr);
2257 if (!found) {
2258 if (mode == MODE_CREATE) {
2259 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
2260 return CKR_TEMPLATE_INCOMPLETE;
2261 }
2262 }
2263
2264 found = template_attribute_find(tmpl, CKA_VALUE, &attr);
2265 if (!found) {
2266 if (mode == MODE_CREATE) {
2267 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
2268 return CKR_TEMPLATE_INCOMPLETE;
2269 }
2270 }
2271
2272 return priv_key_check_required_attributes(tmpl, mode);
2273 }
2274
2275
2276 // ecdsa_priv_set_default_attributes()
2277 //
ecdsa_priv_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)2278 CK_RV ecdsa_priv_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
2279 {
2280 CK_ATTRIBUTE *params_attr = NULL;
2281 CK_ATTRIBUTE *value_attr = NULL;
2282 CK_ATTRIBUTE *type_attr = NULL;
2283
2284 if (mode)
2285 params_attr = NULL;
2286
2287 priv_key_set_default_attributes(tmpl, mode);
2288
2289 type_attr =
2290 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
2291 params_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
2292 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
2293
2294 if (!type_attr || !params_attr || !value_attr) {
2295 if (type_attr)
2296 free(type_attr);
2297 if (params_attr)
2298 free(params_attr);
2299 if (value_attr)
2300 free(value_attr);
2301 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2302
2303 return CKR_HOST_MEMORY;
2304 }
2305
2306 params_attr->type = CKA_ECDSA_PARAMS;
2307 params_attr->ulValueLen = 0;
2308 params_attr->pValue = NULL;
2309
2310 value_attr->type = CKA_VALUE;
2311 value_attr->ulValueLen = 0;
2312 value_attr->pValue = NULL;
2313
2314 type_attr->type = CKA_KEY_TYPE;
2315 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
2316 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
2317 *(CK_KEY_TYPE *) type_attr->pValue = CKK_ECDSA;
2318
2319 template_update_attribute(tmpl, type_attr);
2320 template_update_attribute(tmpl, params_attr);
2321 template_update_attribute(tmpl, value_attr);
2322
2323 return CKR_OK;
2324 }
2325
2326
2327 // ecdsa_priv_validate_attributes()
2328 //
ecdsa_priv_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)2329 CK_RV ecdsa_priv_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
2330 CK_ATTRIBUTE *attr, CK_ULONG mode)
2331 {
2332 switch (attr->type) {
2333 case CKA_ECDSA_PARAMS:
2334 if (mode == MODE_CREATE)
2335 return CKR_OK;
2336
2337 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
2338 return CKR_ATTRIBUTE_READ_ONLY;
2339 case CKA_VALUE:
2340 if (mode == MODE_CREATE) {
2341 p11_attribute_trim(attr);
2342 return CKR_OK;
2343 }
2344 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
2345 return CKR_ATTRIBUTE_READ_ONLY;
2346 case CKA_EC_POINT:
2347 if (mode == MODE_CREATE) {
2348 p11_attribute_trim(attr);
2349 return CKR_OK;
2350 }
2351 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
2352 return CKR_ATTRIBUTE_READ_ONLY;
2353 default:
2354 return priv_key_validate_attribute(tokdata, tmpl, attr, mode);
2355 }
2356 }
2357
2358
2359 // ecdsa_priv_check_exportability()
2360 //
ecdsa_priv_check_exportability(CK_ATTRIBUTE_TYPE type)2361 CK_BBOOL ecdsa_priv_check_exportability(CK_ATTRIBUTE_TYPE type)
2362 {
2363 switch (type) {
2364 case CKA_VALUE:
2365 return FALSE;
2366 }
2367
2368 return TRUE;
2369 }
2370
2371
2372 // dh_publ_check_required_attributes()
2373 //
dh_publ_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)2374 CK_RV dh_publ_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
2375 {
2376 CK_ATTRIBUTE *attr = NULL;
2377 CK_BBOOL found;
2378
2379
2380 found = template_attribute_find(tmpl, CKA_PRIME, &attr);
2381 if (!found) {
2382 if (mode == MODE_CREATE || mode == MODE_KEYGEN) {
2383 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
2384 return CKR_TEMPLATE_INCOMPLETE;
2385 }
2386 }
2387
2388 found = template_attribute_find(tmpl, CKA_BASE, &attr);
2389 if (!found) {
2390 if (mode == MODE_CREATE || mode == MODE_KEYGEN) {
2391 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
2392 return CKR_TEMPLATE_INCOMPLETE;
2393 }
2394 }
2395
2396 found = template_attribute_find(tmpl, CKA_VALUE, &attr);
2397 if (!found) {
2398 if (mode == MODE_CREATE) {
2399 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
2400 return CKR_TEMPLATE_INCOMPLETE;
2401 }
2402 }
2403
2404 return publ_key_check_required_attributes(tmpl, mode);
2405 }
2406
2407
2408 // dh_publ_set_default_attributes()
2409 //
dh_publ_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)2410 CK_RV dh_publ_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
2411 {
2412 CK_ATTRIBUTE *prime_attr = NULL;
2413 CK_ATTRIBUTE *base_attr = NULL;
2414 CK_ATTRIBUTE *value_attr = NULL;
2415 CK_ATTRIBUTE *type_attr = NULL;
2416
2417 if (mode)
2418 prime_attr = NULL;
2419
2420 publ_key_set_default_attributes(tmpl, mode);
2421
2422 type_attr =
2423 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
2424 prime_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
2425 base_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
2426 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
2427
2428 if (!type_attr || !prime_attr || !base_attr || !value_attr) {
2429 if (type_attr)
2430 free(type_attr);
2431 if (prime_attr)
2432 free(prime_attr);
2433 if (base_attr)
2434 free(base_attr);
2435 if (value_attr)
2436 free(value_attr);
2437 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2438
2439 return CKR_HOST_MEMORY;
2440 }
2441
2442 prime_attr->type = CKA_PRIME;
2443 prime_attr->ulValueLen = 0;
2444 prime_attr->pValue = NULL;
2445
2446 base_attr->type = CKA_BASE;
2447 base_attr->ulValueLen = 0;
2448 base_attr->pValue = NULL;
2449
2450 value_attr->type = CKA_VALUE;
2451 value_attr->ulValueLen = 0;
2452 value_attr->pValue = NULL;
2453
2454 type_attr->type = CKA_KEY_TYPE;
2455 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
2456 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
2457 *(CK_KEY_TYPE *) type_attr->pValue = CKK_DH;
2458
2459 template_update_attribute(tmpl, type_attr);
2460 template_update_attribute(tmpl, prime_attr);
2461 template_update_attribute(tmpl, base_attr);
2462 template_update_attribute(tmpl, value_attr);
2463
2464 return CKR_OK;
2465 }
2466
2467
2468
2469
2470 // dh_publ_validate_attribute()
2471 //
dh_publ_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)2472 CK_RV dh_publ_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
2473 CK_ATTRIBUTE *attr, CK_ULONG mode)
2474 {
2475 switch (attr->type) {
2476 case CKA_PRIME:
2477 case CKA_BASE:
2478 if (mode == MODE_CREATE || mode == MODE_KEYGEN) {
2479 p11_attribute_trim(attr);
2480 return CKR_OK;
2481 }
2482 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
2483 return CKR_ATTRIBUTE_READ_ONLY;
2484 case CKA_VALUE:
2485 if (mode == MODE_CREATE) {
2486 p11_attribute_trim(attr);
2487 return CKR_OK;
2488 }
2489 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
2490 return CKR_ATTRIBUTE_READ_ONLY;
2491 default:
2492 return publ_key_validate_attribute(tokdata, tmpl, attr, mode);
2493 }
2494 }
2495
2496
2497 // dh_priv_check_required_attributes()
2498 //
dh_priv_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)2499 CK_RV dh_priv_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
2500 {
2501 CK_ATTRIBUTE *attr = NULL;
2502 CK_BBOOL found;
2503
2504
2505 found = template_attribute_find(tmpl, CKA_PRIME, &attr);
2506 if (!found) {
2507 if (mode == MODE_CREATE) {
2508 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
2509 return CKR_TEMPLATE_INCOMPLETE;
2510 }
2511 }
2512
2513 found = template_attribute_find(tmpl, CKA_BASE, &attr);
2514 if (!found) {
2515 if (mode == MODE_CREATE) {
2516 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
2517 return CKR_TEMPLATE_INCOMPLETE;
2518 }
2519 }
2520
2521 found = template_attribute_find(tmpl, CKA_VALUE, &attr);
2522 if (!found) {
2523 if (mode == MODE_CREATE) {
2524 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
2525 return CKR_TEMPLATE_INCOMPLETE;
2526 }
2527 }
2528
2529 found = template_attribute_find(tmpl, CKA_VALUE_BITS, &attr);
2530 if (found) {
2531 if (mode == MODE_CREATE || mode == MODE_UNWRAP) {
2532 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
2533 return CKR_ATTRIBUTE_READ_ONLY;
2534 }
2535 }
2536
2537 return priv_key_check_required_attributes(tmpl, mode);
2538 }
2539
2540
2541 // dh_priv_set_default_attributes()
2542 //
dh_priv_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)2543 CK_RV dh_priv_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
2544 {
2545 CK_ATTRIBUTE *prime_attr = NULL;
2546 CK_ATTRIBUTE *base_attr = NULL;
2547 CK_ATTRIBUTE *value_attr = NULL;
2548 CK_ATTRIBUTE *value_bits_attr = NULL;
2549 CK_ATTRIBUTE *type_attr = NULL;
2550 CK_ULONG bits = 0L;
2551
2552 priv_key_set_default_attributes(tmpl, mode);
2553
2554 type_attr =
2555 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
2556 prime_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
2557 base_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
2558 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
2559 value_bits_attr =
2560 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG));
2561
2562 if (!type_attr || !prime_attr || !base_attr || !value_attr
2563 || !value_bits_attr) {
2564 if (type_attr)
2565 free(type_attr);
2566 if (prime_attr)
2567 free(prime_attr);
2568 if (base_attr)
2569 free(base_attr);
2570 if (value_attr)
2571 free(value_attr);
2572 if (value_bits_attr)
2573 free(value_bits_attr);
2574
2575 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2576 return CKR_HOST_MEMORY;
2577 }
2578
2579 prime_attr->type = CKA_PRIME;
2580 prime_attr->ulValueLen = 0;
2581 prime_attr->pValue = NULL;
2582
2583 base_attr->type = CKA_BASE;
2584 base_attr->ulValueLen = 0;
2585 base_attr->pValue = NULL;
2586
2587 value_attr->type = CKA_VALUE;
2588 value_attr->ulValueLen = 0;
2589 value_attr->pValue = NULL;
2590
2591 value_bits_attr->type = CKA_VALUE_BITS;
2592 value_bits_attr->ulValueLen = sizeof(CK_ULONG);
2593 value_bits_attr->pValue =
2594 (CK_BYTE *) value_bits_attr + sizeof(CK_ATTRIBUTE);
2595 *(CK_ULONG *) value_bits_attr->pValue = bits;
2596
2597 type_attr->type = CKA_KEY_TYPE;
2598 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
2599 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
2600 *(CK_KEY_TYPE *) type_attr->pValue = CKK_DH;
2601
2602 template_update_attribute(tmpl, type_attr);
2603 template_update_attribute(tmpl, prime_attr);
2604 template_update_attribute(tmpl, base_attr);
2605 template_update_attribute(tmpl, value_attr);
2606 template_update_attribute(tmpl, value_bits_attr);
2607
2608 return CKR_OK;
2609 }
2610
2611
2612 // dh_priv_validate_attribute()
2613 //
dh_priv_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)2614 CK_RV dh_priv_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
2615 CK_ATTRIBUTE *attr, CK_ULONG mode)
2616 {
2617 switch (attr->type) {
2618 case CKA_PRIME:
2619 case CKA_BASE:
2620 case CKA_VALUE:
2621 if (mode == MODE_CREATE || mode == MODE_KEYGEN) {
2622 p11_attribute_trim(attr);
2623 return CKR_OK;
2624 }
2625 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
2626 return CKR_ATTRIBUTE_READ_ONLY;
2627 // I'm not sure what to do about VALUE_BITS...we don't really support
2628 // Diffie-Hellman keys other than for storage...when the object is
2629 // created, we're supposed to add CKA_VALUE_BITS outselves...which we
2630 // don't do at this time. (we'd need to add code in C_CreateObject to
2631 // call some sort of objecttype-specific callback)
2632 //
2633 // kapil 05/08/03 : Commented out error flagging, as CKA_VALUE_BITS is
2634 // valid attribute for creating DH priv object. The
2635 // above is an older comment.
2636 case CKA_VALUE_BITS:
2637 // TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
2638 // return CKR_ATTRIBUTE_READ_ONLY;
2639 return CKR_OK;
2640 break;
2641 default:
2642 return priv_key_validate_attribute(tokdata, tmpl, attr, mode);
2643 }
2644 }
2645
2646
2647 // dh_priv_check_exportability()
2648 //
dh_priv_check_exportability(CK_ATTRIBUTE_TYPE type)2649 CK_BBOOL dh_priv_check_exportability(CK_ATTRIBUTE_TYPE type)
2650 {
2651 switch (type) {
2652 case CKA_VALUE:
2653 return FALSE;
2654 }
2655
2656 return TRUE;
2657 }
2658
2659 //
2660 //
dh_priv_unwrap(TEMPLATE * tmpl,CK_BYTE * data,CK_ULONG total_length)2661 CK_RV dh_priv_unwrap(TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG total_length)
2662 {
2663 CK_ATTRIBUTE *prime = NULL;
2664 CK_ATTRIBUTE *base = NULL;
2665 CK_ATTRIBUTE *value = NULL;
2666 CK_RV rc;
2667
2668 rc = ber_decode_DHPrivateKey(data, total_length, &prime, &base, &value);
2669
2670 if (rc != CKR_OK) {
2671 TRACE_DEVEL("ber_decode_DHPrivateKey failed\n");
2672 return rc;
2673 }
2674 p11_attribute_trim(prime);
2675 p11_attribute_trim(base);
2676 p11_attribute_trim(value);
2677
2678 template_update_attribute(tmpl, prime);
2679 template_update_attribute(tmpl, base);
2680 template_update_attribute(tmpl, value);
2681
2682 return CKR_OK;
2683 }
2684
2685 //
2686 //
ec_priv_unwrap(TEMPLATE * tmpl,CK_BYTE * data,CK_ULONG total_length,CK_BBOOL isOpaque)2687 CK_RV ec_priv_unwrap(TEMPLATE *tmpl,
2688 CK_BYTE *data, CK_ULONG total_length, CK_BBOOL isOpaque)
2689 {
2690 CK_ATTRIBUTE *pubkey = NULL;
2691 CK_ATTRIBUTE *privkey = NULL;
2692 CK_ATTRIBUTE *opaque = NULL;
2693 CK_ATTRIBUTE *ecparam = NULL;
2694 CK_RV rc;
2695
2696 rc = der_decode_ECPrivateKey(data, total_length, &ecparam,
2697 &pubkey, &privkey, &opaque, isOpaque);
2698
2699 if (rc != CKR_OK) {
2700 TRACE_DEVEL("der_decode_ECPrivateKey failed\n");
2701 return rc;
2702 }
2703 p11_attribute_trim(pubkey);
2704 p11_attribute_trim(privkey);
2705
2706 if (isOpaque)
2707 template_update_attribute(tmpl, opaque);
2708 if (pubkey)
2709 template_update_attribute(tmpl, pubkey);
2710 if (privkey)
2711 template_update_attribute(tmpl, privkey);
2712 template_update_attribute(tmpl, ecparam);
2713
2714 return CKR_OK;
2715 }
2716
2717 // create the ASN.1 encoding for the private key for wrapping as defined
2718 // in PKCS #8
2719 //
2720 // ASN.1 type PrivateKeyInfo ::= SEQUENCE {
2721 // version Version
2722 // privateKeyAlgorithm PrivateKeyAlgorithmIdentifier
2723 // privateKey PrivateKey
2724 // attributes OPTIONAL
2725 // }
2726 //
2727 // PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
2728 //
2729 // AlgorithmIdentifier ::= SEQUENCE {
2730 // algorithm OBJECT IDENTIFIER
2731 // parameters ANY DEFINED BY algorithm OPTIONAL
2732 // }
2733 //
2734 // paramters ::= SEQUENCE {
2735 // p INTEGER
2736 // g INTEGER
2737 // }
2738 //
2739 // privateKey ::= INTEGER
2740 //
2741 //
dh_priv_wrap_get_data(TEMPLATE * tmpl,CK_BBOOL length_only,CK_BYTE ** data,CK_ULONG * data_len)2742 CK_RV dh_priv_wrap_get_data(TEMPLATE *tmpl,
2743 CK_BBOOL length_only,
2744 CK_BYTE **data, CK_ULONG *data_len)
2745 {
2746 CK_ATTRIBUTE *prime = NULL;
2747 CK_ATTRIBUTE *base = NULL;
2748 CK_ATTRIBUTE *value = NULL;
2749 CK_RV rc;
2750
2751 // compute the total length of the BER-encoded data
2752 if (template_attribute_find(tmpl, CKA_PRIME, &prime) == FALSE) {
2753 TRACE_ERROR("Could not find CKA_PRIME for the key.\n");
2754 return CKR_FUNCTION_FAILED;
2755 }
2756 if (template_attribute_find(tmpl, CKA_BASE, &base) == FALSE) {
2757 TRACE_ERROR("Could not find CKA_BASE for the key.\n");
2758 return CKR_FUNCTION_FAILED;
2759 }
2760 if (template_attribute_find(tmpl, CKA_VALUE, &value) == FALSE) {
2761 TRACE_ERROR("Could not find CKA_VALUE for the key.\n");
2762 return CKR_FUNCTION_FAILED;
2763 }
2764 rc = ber_encode_DHPrivateKey(length_only, data, data_len,
2765 prime, base, value);
2766 if (rc != CKR_OK)
2767 TRACE_DEVEL("ber_encode_DSAPrivateKe failed\n");
2768
2769 return rc;
2770 }
2771
2772
2773 // kea_publ_check_required_attributes()
2774 //
kea_publ_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)2775 CK_RV kea_publ_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
2776 {
2777 CK_ATTRIBUTE *attr = NULL;
2778 CK_BBOOL found;
2779
2780
2781 found = template_attribute_find(tmpl, CKA_PRIME, &attr);
2782 if (!found) {
2783 if (mode == MODE_CREATE || mode == MODE_KEYGEN) {
2784 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
2785 return CKR_TEMPLATE_INCOMPLETE;
2786 }
2787 }
2788
2789 found = template_attribute_find(tmpl, CKA_SUBPRIME, &attr);
2790 if (!found) {
2791 if (mode == MODE_CREATE || mode == MODE_KEYGEN) {
2792 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
2793 return CKR_TEMPLATE_INCOMPLETE;
2794 }
2795 }
2796
2797 found = template_attribute_find(tmpl, CKA_BASE, &attr);
2798 if (!found) {
2799 if (mode == MODE_CREATE || mode == MODE_KEYGEN) {
2800 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
2801 return CKR_TEMPLATE_INCOMPLETE;
2802 }
2803 }
2804
2805 found = template_attribute_find(tmpl, CKA_VALUE, &attr);
2806 if (!found) {
2807 if (mode == MODE_CREATE) {
2808 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
2809 return CKR_TEMPLATE_INCOMPLETE;
2810 }
2811 }
2812
2813 return publ_key_check_required_attributes(tmpl, mode);
2814 }
2815
2816
2817 // kea_publ_set_default_attributes()
2818 //
kea_publ_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)2819 CK_RV kea_publ_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
2820 {
2821 CK_ATTRIBUTE *prime_attr = NULL;
2822 CK_ATTRIBUTE *subprime_attr = NULL;
2823 CK_ATTRIBUTE *base_attr = NULL;
2824 CK_ATTRIBUTE *value_attr = NULL;
2825 CK_ATTRIBUTE *type_attr = NULL;
2826
2827 if (mode)
2828 prime_attr = NULL;
2829
2830
2831 publ_key_set_default_attributes(tmpl, mode);
2832
2833 type_attr =
2834 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
2835 prime_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
2836 subprime_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
2837 base_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
2838 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
2839
2840 if (!type_attr || !prime_attr || !subprime_attr || !base_attr
2841 || !value_attr) {
2842 if (type_attr)
2843 free(type_attr);
2844 if (prime_attr)
2845 free(prime_attr);
2846 if (subprime_attr)
2847 free(subprime_attr);
2848 if (base_attr)
2849 free(base_attr);
2850 if (value_attr)
2851 free(value_attr);
2852
2853 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2854 return CKR_HOST_MEMORY;
2855 }
2856
2857 prime_attr->type = CKA_PRIME;
2858 prime_attr->ulValueLen = 0;
2859 prime_attr->pValue = NULL;
2860
2861 subprime_attr->type = CKA_SUBPRIME;
2862 subprime_attr->ulValueLen = 0;
2863 subprime_attr->pValue = NULL;
2864
2865 base_attr->type = CKA_BASE;
2866 base_attr->ulValueLen = 0;
2867 base_attr->pValue = NULL;
2868
2869 value_attr->type = CKA_VALUE;
2870 value_attr->ulValueLen = 0;
2871 value_attr->pValue = NULL;
2872
2873 type_attr->type = CKA_KEY_TYPE;
2874 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
2875 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
2876 *(CK_KEY_TYPE *) type_attr->pValue = CKK_KEA;
2877
2878 template_update_attribute(tmpl, type_attr);
2879 template_update_attribute(tmpl, prime_attr);
2880 template_update_attribute(tmpl, subprime_attr);
2881 template_update_attribute(tmpl, base_attr);
2882 template_update_attribute(tmpl, value_attr);
2883
2884 return CKR_OK;
2885 }
2886
2887
2888 // kea_publ_validate_attribute()
2889 //
kea_publ_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)2890 CK_RV kea_publ_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
2891 CK_ATTRIBUTE *attr, CK_ULONG mode)
2892 {
2893 switch (attr->type) {
2894 case CKA_PRIME:
2895 case CKA_SUBPRIME:
2896 case CKA_BASE:
2897 if (mode == MODE_CREATE || mode == MODE_KEYGEN) {
2898 p11_attribute_trim(attr);
2899 return CKR_OK;
2900 }
2901 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
2902 return CKR_ATTRIBUTE_READ_ONLY;
2903 case CKA_VALUE:
2904 if (mode == MODE_CREATE) {
2905 p11_attribute_trim(attr);
2906 return CKR_OK;
2907 }
2908 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
2909 return CKR_ATTRIBUTE_READ_ONLY;
2910 default:
2911 return publ_key_validate_attribute(tokdata, tmpl, attr, mode);
2912 }
2913 }
2914
2915
2916 // kea_priv_check_required_attributes()
2917 //
kea_priv_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)2918 CK_RV kea_priv_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
2919 {
2920 CK_ATTRIBUTE *attr = NULL;
2921 CK_BBOOL found;
2922
2923
2924 found = template_attribute_find(tmpl, CKA_PRIME, &attr);
2925 if (!found) {
2926 if (mode == MODE_CREATE) {
2927 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
2928 return CKR_TEMPLATE_INCOMPLETE;
2929 }
2930 }
2931
2932 found = template_attribute_find(tmpl, CKA_SUBPRIME, &attr);
2933 if (!found) {
2934 if (mode == MODE_CREATE) {
2935 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
2936 return CKR_TEMPLATE_INCOMPLETE;
2937 }
2938 }
2939
2940 found = template_attribute_find(tmpl, CKA_BASE, &attr);
2941 if (!found) {
2942 if (mode == MODE_CREATE) {
2943 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
2944 return CKR_TEMPLATE_INCOMPLETE;
2945 }
2946 }
2947
2948 found = template_attribute_find(tmpl, CKA_VALUE, &attr);
2949 if (!found) {
2950 if (mode == MODE_CREATE) {
2951 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
2952 return CKR_TEMPLATE_INCOMPLETE;
2953 }
2954 }
2955
2956 return priv_key_check_required_attributes(tmpl, mode);
2957 }
2958
2959
2960 // kea_priv_set_default_attributes()
2961 //
kea_priv_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)2962 CK_RV kea_priv_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
2963 {
2964 CK_ATTRIBUTE *prime_attr = NULL;
2965 CK_ATTRIBUTE *subprime_attr = NULL;
2966 CK_ATTRIBUTE *base_attr = NULL;
2967 CK_ATTRIBUTE *value_attr = NULL;
2968 CK_ATTRIBUTE *type_attr = NULL;
2969
2970 if (mode)
2971 prime_attr = NULL;
2972
2973 priv_key_set_default_attributes(tmpl, mode);
2974
2975 type_attr =
2976 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
2977 prime_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
2978 subprime_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
2979 base_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
2980 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
2981
2982 if (!type_attr || !prime_attr || !base_attr || !value_attr
2983 || !subprime_attr) {
2984 if (type_attr)
2985 free(type_attr);
2986 if (prime_attr)
2987 free(prime_attr);
2988 if (subprime_attr)
2989 free(subprime_attr);
2990 if (base_attr)
2991 free(base_attr);
2992 if (value_attr)
2993 free(value_attr);
2994
2995 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2996 return CKR_HOST_MEMORY;
2997 }
2998
2999 prime_attr->type = CKA_PRIME;
3000 prime_attr->ulValueLen = 0;
3001 prime_attr->pValue = NULL;
3002
3003 subprime_attr->type = CKA_SUBPRIME;
3004 subprime_attr->ulValueLen = 0;
3005 subprime_attr->pValue = NULL;
3006
3007 base_attr->type = CKA_BASE;
3008 base_attr->ulValueLen = 0;
3009 base_attr->pValue = NULL;
3010
3011 value_attr->type = CKA_VALUE;
3012 value_attr->ulValueLen = 0;
3013 value_attr->pValue = NULL;
3014
3015 type_attr->type = CKA_KEY_TYPE;
3016 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
3017 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
3018 *(CK_KEY_TYPE *) type_attr->pValue = CKK_KEA;
3019
3020 template_update_attribute(tmpl, type_attr);
3021 template_update_attribute(tmpl, prime_attr);
3022 template_update_attribute(tmpl, subprime_attr);
3023 template_update_attribute(tmpl, base_attr);
3024 template_update_attribute(tmpl, value_attr);
3025
3026 return CKR_OK;
3027 }
3028
3029
3030 // kea_priv_validate_attribute()
3031 //
kea_priv_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)3032 CK_RV kea_priv_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
3033 CK_ATTRIBUTE *attr, CK_ULONG mode)
3034 {
3035 switch (attr->type) {
3036 case CKA_PRIME:
3037 case CKA_SUBPRIME:
3038 case CKA_BASE:
3039 case CKA_VALUE:
3040 if (mode == MODE_CREATE) {
3041 p11_attribute_trim(attr);
3042 return CKR_OK;
3043 }
3044 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
3045 return CKR_ATTRIBUTE_READ_ONLY;
3046 default:
3047 return priv_key_validate_attribute(tokdata, tmpl, attr, mode);
3048 }
3049 }
3050
3051
3052 // kea_priv_check_exportability()
3053 //
kea_priv_check_exportability(CK_ATTRIBUTE_TYPE type)3054 CK_BBOOL kea_priv_check_exportability(CK_ATTRIBUTE_TYPE type)
3055 {
3056 switch (type) {
3057 case CKA_VALUE:
3058 return FALSE;
3059 }
3060
3061 return TRUE;
3062 }
3063
3064
3065 // generic_secret_check_required_attributes()
3066 //
generic_secret_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)3067 CK_RV generic_secret_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
3068 {
3069 CK_ATTRIBUTE *attr = NULL;
3070 CK_BBOOL found;
3071
3072 found = template_attribute_find(tmpl, CKA_VALUE, &attr);
3073 if (!found) {
3074 if (mode == MODE_CREATE) {
3075 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
3076 return CKR_TEMPLATE_INCOMPLETE;
3077 }
3078 }
3079
3080
3081 found = template_attribute_find(tmpl, CKA_VALUE_LEN, &attr);
3082 if (!found) {
3083 // here's another place where PKCS #11 deviates from its own
3084 // specification.
3085 // the spec states that VALUE_LEN must be present for KEYGEN but later
3086 // it's merely optional if the mechanism is CKM_SSL3_PRE_MASTER_KEY_GEN.
3087 // Unfortunately, we can't check the mechanism at this point
3088 //
3089 return CKR_OK;
3090 } else {
3091 // Another contradiction within the spec: When describing the key types
3092 // the spec says that VALUE_LEN must not be specified when unwrapping
3093 // a key. In the section describing the mechanisms, though, it's allowed
3094 // for most unwrapping mechanisms. Netscape DOES does specify this
3095 // attribute when unwrapping.
3096 //
3097 if (mode == MODE_CREATE) {
3098 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
3099 return CKR_ATTRIBUTE_READ_ONLY;
3100 }
3101 }
3102
3103 return secret_key_check_required_attributes(tmpl, mode);
3104 }
3105
3106
3107 // generic_secret_set_default_attributes()
3108 //
generic_secret_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)3109 CK_RV generic_secret_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
3110 {
3111 CK_ATTRIBUTE *value_attr = NULL;
3112 CK_ATTRIBUTE *value_len_attr = NULL;
3113 CK_ATTRIBUTE *type_attr = NULL;
3114 CK_ATTRIBUTE *class_attr = NULL;
3115 CK_ATTRIBUTE *sensitive_attr = NULL;
3116 CK_ATTRIBUTE *encrypt_attr = NULL;
3117 CK_ATTRIBUTE *decrypt_attr = NULL;
3118 CK_ATTRIBUTE *sign_attr = NULL;
3119 CK_ATTRIBUTE *verify_attr = NULL;
3120 CK_ATTRIBUTE *wrap_attr = NULL;
3121 CK_ATTRIBUTE *unwrap_attr = NULL;
3122 CK_ATTRIBUTE *extractable_attr = NULL;
3123 CK_ATTRIBUTE *never_extr_attr = NULL;
3124 CK_ATTRIBUTE *always_sens_attr = NULL;
3125 CK_ATTRIBUTE *id_attr = NULL;
3126 CK_ATTRIBUTE *sdate_attr = NULL;
3127 CK_ATTRIBUTE *edate_attr = NULL;
3128 CK_ATTRIBUTE *derive_attr = NULL;
3129 CK_ATTRIBUTE *local_attr = NULL;
3130 CK_ULONG len = 0L;
3131
3132 if (mode) {
3133 value_attr = NULL;
3134 id_attr = NULL;
3135 }
3136
3137 /* First set the Common Key Attributes's defaults for Generic Secret Keys */
3138
3139 id_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
3140 sdate_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
3141 edate_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
3142 derive_attr =
3143 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
3144 local_attr =
3145 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
3146
3147 if (!id_attr || !sdate_attr || !edate_attr || !derive_attr || !local_attr) {
3148 if (id_attr)
3149 free(id_attr);
3150 if (sdate_attr)
3151 free(sdate_attr);
3152 if (edate_attr)
3153 free(edate_attr);
3154 if (derive_attr)
3155 free(derive_attr);
3156 if (local_attr)
3157 free(local_attr);
3158
3159 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
3160 return CKR_HOST_MEMORY;
3161 }
3162
3163 id_attr->type = CKA_ID;
3164 id_attr->ulValueLen = 0;
3165 id_attr->pValue = NULL;
3166
3167 sdate_attr->type = CKA_START_DATE;
3168 sdate_attr->ulValueLen = 0;
3169 sdate_attr->pValue = NULL;
3170
3171 edate_attr->type = CKA_END_DATE;
3172 edate_attr->ulValueLen = 0;
3173 edate_attr->pValue = NULL;
3174
3175 derive_attr->type = CKA_DERIVE;
3176 derive_attr->ulValueLen = sizeof(CK_BBOOL);
3177 derive_attr->pValue = (CK_BYTE *) derive_attr + sizeof(CK_ATTRIBUTE);
3178 *(CK_BBOOL *) derive_attr->pValue = TRUE;
3179
3180 /* should be safe to set CKA_LOCAL here... */
3181 local_attr->type = CKA_LOCAL;
3182 local_attr->ulValueLen = sizeof(CK_BBOOL);
3183 local_attr->pValue = (CK_BYTE *) local_attr + sizeof(CK_ATTRIBUTE);
3184 if (mode == MODE_KEYGEN)
3185 *(CK_BBOOL *) local_attr->pValue = TRUE;
3186 else
3187 *(CK_BBOOL *) local_attr->pValue = FALSE;
3188
3189 template_update_attribute(tmpl, id_attr);
3190 template_update_attribute(tmpl, sdate_attr);
3191 template_update_attribute(tmpl, edate_attr);
3192 template_update_attribute(tmpl, derive_attr);
3193 template_update_attribute(tmpl, local_attr);
3194
3195 /* Next, set the Common Secret Key Attributes and defaults for
3196 * Generic Secret Keys.
3197 */
3198
3199 class_attr =
3200 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS));
3201 sensitive_attr =
3202 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
3203 encrypt_attr =
3204 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
3205 decrypt_attr =
3206 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
3207 sign_attr =
3208 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
3209 verify_attr =
3210 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
3211 wrap_attr =
3212 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
3213 unwrap_attr =
3214 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
3215 extractable_attr =
3216 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
3217 never_extr_attr =
3218 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
3219 always_sens_attr =
3220 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
3221 if (!class_attr || !sensitive_attr || !encrypt_attr || !decrypt_attr
3222 || !sign_attr || !verify_attr | !wrap_attr || !unwrap_attr
3223 || !extractable_attr || !never_extr_attr || !always_sens_attr) {
3224 if (class_attr)
3225 free(class_attr);
3226 if (sensitive_attr)
3227 free(sensitive_attr);
3228 if (encrypt_attr)
3229 free(encrypt_attr);
3230 if (decrypt_attr)
3231 free(decrypt_attr);
3232 if (sign_attr)
3233 free(sign_attr);
3234 if (verify_attr)
3235 free(verify_attr);
3236 if (wrap_attr)
3237 free(wrap_attr);
3238 if (unwrap_attr)
3239 free(unwrap_attr);
3240 if (extractable_attr)
3241 free(extractable_attr);
3242 if (never_extr_attr)
3243 free(never_extr_attr);
3244 if (always_sens_attr)
3245 free(always_sens_attr);
3246
3247 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
3248 return CKR_HOST_MEMORY;
3249 }
3250
3251 class_attr->type = CKA_CLASS;
3252 class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS);
3253 class_attr->pValue = (CK_BYTE *) class_attr + sizeof(CK_ATTRIBUTE);
3254 *(CK_OBJECT_CLASS *) class_attr->pValue = CKO_SECRET_KEY;
3255
3256 sensitive_attr->type = CKA_SENSITIVE;
3257 sensitive_attr->ulValueLen = sizeof(CK_BBOOL);
3258 sensitive_attr->pValue = (CK_BYTE *) sensitive_attr + sizeof(CK_ATTRIBUTE);
3259 *(CK_BBOOL *) sensitive_attr->pValue = FALSE;
3260
3261 encrypt_attr->type = CKA_ENCRYPT;
3262 encrypt_attr->ulValueLen = sizeof(CK_BBOOL);
3263 encrypt_attr->pValue = (CK_BYTE *) encrypt_attr + sizeof(CK_ATTRIBUTE);
3264 *(CK_BBOOL *) encrypt_attr->pValue = FALSE;
3265
3266 decrypt_attr->type = CKA_DECRYPT;
3267 decrypt_attr->ulValueLen = sizeof(CK_BBOOL);
3268 decrypt_attr->pValue = (CK_BYTE *) decrypt_attr + sizeof(CK_ATTRIBUTE);
3269 *(CK_BBOOL *) decrypt_attr->pValue = FALSE;
3270
3271 sign_attr->type = CKA_SIGN;
3272 sign_attr->ulValueLen = sizeof(CK_BBOOL);
3273 sign_attr->pValue = (CK_BYTE *) sign_attr + sizeof(CK_ATTRIBUTE);
3274 *(CK_BBOOL *) sign_attr->pValue = TRUE;
3275
3276 verify_attr->type = CKA_VERIFY;
3277 verify_attr->ulValueLen = sizeof(CK_BBOOL);
3278 verify_attr->pValue = (CK_BYTE *) verify_attr + sizeof(CK_ATTRIBUTE);
3279 *(CK_BBOOL *) verify_attr->pValue = TRUE;
3280
3281 wrap_attr->type = CKA_WRAP;
3282 wrap_attr->ulValueLen = sizeof(CK_BBOOL);
3283 wrap_attr->pValue = (CK_BYTE *) wrap_attr + sizeof(CK_ATTRIBUTE);
3284 *(CK_BBOOL *) wrap_attr->pValue = FALSE;
3285
3286 unwrap_attr->type = CKA_UNWRAP;
3287 unwrap_attr->ulValueLen = sizeof(CK_BBOOL);
3288 unwrap_attr->pValue = (CK_BYTE *) unwrap_attr + sizeof(CK_ATTRIBUTE);
3289 *(CK_BBOOL *) unwrap_attr->pValue = FALSE;
3290
3291 extractable_attr->type = CKA_EXTRACTABLE;
3292 extractable_attr->ulValueLen = sizeof(CK_BBOOL);
3293 extractable_attr->pValue =
3294 (CK_BYTE *) extractable_attr + sizeof(CK_ATTRIBUTE);
3295 *(CK_BBOOL *) extractable_attr->pValue = TRUE;
3296
3297 /* by default, we'll set NEVER_EXTRACTABLE == FALSE and
3298 * ALWAYS_SENSITIVE == FALSE
3299 * If the key is being created with KEYGEN, it will adjust as necessary.
3300 */
3301 always_sens_attr->type = CKA_ALWAYS_SENSITIVE;
3302 always_sens_attr->ulValueLen = sizeof(CK_BBOOL);
3303 always_sens_attr->pValue =
3304 (CK_BYTE *) always_sens_attr + sizeof(CK_ATTRIBUTE);
3305 *(CK_BBOOL *) always_sens_attr->pValue = FALSE;
3306
3307 never_extr_attr->type = CKA_NEVER_EXTRACTABLE;
3308 never_extr_attr->ulValueLen = sizeof(CK_BBOOL);
3309 never_extr_attr->pValue =
3310 (CK_BYTE *) never_extr_attr + sizeof(CK_ATTRIBUTE);
3311 *(CK_BBOOL *) never_extr_attr->pValue = FALSE;
3312
3313 template_update_attribute(tmpl, class_attr);
3314 template_update_attribute(tmpl, sensitive_attr);
3315 template_update_attribute(tmpl, encrypt_attr);
3316 template_update_attribute(tmpl, decrypt_attr);
3317 template_update_attribute(tmpl, sign_attr);
3318 template_update_attribute(tmpl, verify_attr);
3319 template_update_attribute(tmpl, wrap_attr);
3320 template_update_attribute(tmpl, unwrap_attr);
3321 template_update_attribute(tmpl, extractable_attr);
3322 template_update_attribute(tmpl, never_extr_attr);
3323 template_update_attribute(tmpl, always_sens_attr);
3324
3325 /* Now set the type, value and value_len */
3326 type_attr =
3327 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
3328 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
3329 value_len_attr =
3330 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG));
3331
3332 if (!type_attr || !value_attr || !value_len_attr) {
3333 if (type_attr)
3334 free(type_attr);
3335 if (value_attr)
3336 free(value_attr);
3337 if (value_len_attr)
3338 free(value_len_attr);
3339
3340 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
3341 return CKR_HOST_MEMORY;
3342 }
3343
3344 value_attr->type = CKA_VALUE;
3345 value_attr->ulValueLen = 0;
3346 value_attr->pValue = NULL;
3347
3348 value_len_attr->type = CKA_VALUE_LEN;
3349 value_len_attr->ulValueLen = sizeof(CK_ULONG);
3350 value_len_attr->pValue = (CK_BYTE *) value_len_attr + sizeof(CK_ATTRIBUTE);
3351 *(CK_ULONG *) value_len_attr->pValue = len;
3352
3353 type_attr->type = CKA_KEY_TYPE;
3354 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
3355 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
3356 *(CK_KEY_TYPE *) type_attr->pValue = CKK_GENERIC_SECRET;
3357
3358 template_update_attribute(tmpl, type_attr);
3359 template_update_attribute(tmpl, value_attr);
3360 template_update_attribute(tmpl, value_len_attr);
3361
3362 return CKR_OK;
3363 }
3364
3365 // generic_secret_validate_attribute()
3366 //
generic_secret_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)3367 CK_RV generic_secret_validate_attribute(STDLL_TokData_t *tokdata,
3368 TEMPLATE *tmpl, CK_ATTRIBUTE *attr,
3369 CK_ULONG mode)
3370 {
3371 switch (attr->type) {
3372 case CKA_VALUE:
3373 if (mode == MODE_CREATE)
3374 return CKR_OK;
3375
3376 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
3377 return CKR_ATTRIBUTE_READ_ONLY;
3378 // Another contradiction within the spec: When describing the key types
3379 // the spec says that VALUE_LEN must not be specified when unwrapping
3380 // a key. In the section describing the mechanisms, though, it's allowed
3381 // for most unwrapping mechanisms. Netscape DOES does specify this
3382 // attribute when unwrapping.
3383 //
3384 case CKA_VALUE_LEN:
3385 if (mode == MODE_KEYGEN || mode == MODE_DERIVE)
3386 return CKR_OK;
3387 if (mode == MODE_UNWRAP) {
3388 if (tokdata->nv_token_data->tweak_vector.netscape_mods == TRUE)
3389 return CKR_OK;
3390 }
3391 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
3392 return CKR_ATTRIBUTE_READ_ONLY;
3393 default:
3394 return secret_key_validate_attribute(tokdata, tmpl, attr, mode);
3395 }
3396 }
3397
3398
3399 // generic_secret_check_exportability()
3400 //
generic_secret_check_exportability(CK_ATTRIBUTE_TYPE type)3401 CK_BBOOL generic_secret_check_exportability(CK_ATTRIBUTE_TYPE type)
3402 {
3403 switch (type) {
3404 case CKA_VALUE:
3405 return FALSE;
3406 }
3407
3408 return TRUE;
3409 }
3410
3411
3412 //
3413 //
generic_secret_wrap_get_data(TEMPLATE * tmpl,CK_BBOOL length_only,CK_BYTE ** data,CK_ULONG * data_len)3414 CK_RV generic_secret_wrap_get_data(TEMPLATE *tmpl,
3415 CK_BBOOL length_only,
3416 CK_BYTE **data, CK_ULONG *data_len)
3417 {
3418 CK_ATTRIBUTE *attr = NULL;
3419 CK_BYTE *ptr = NULL;
3420 CK_RV rc;
3421
3422
3423 if (!tmpl || !data_len) {
3424 TRACE_ERROR("Invalid function arguments.\n");
3425 return CKR_FUNCTION_FAILED;
3426 }
3427
3428 rc = template_attribute_find(tmpl, CKA_IBM_OPAQUE, &attr);
3429 if (rc == FALSE) {
3430 rc = template_attribute_find(tmpl, CKA_VALUE, &attr);
3431 if (rc == FALSE) {
3432 TRACE_ERROR("%s\n", ock_err(ERR_KEY_NOT_WRAPPABLE));
3433 return CKR_KEY_NOT_WRAPPABLE;
3434 }
3435 }
3436 *data_len = attr->ulValueLen;
3437
3438 if (length_only == FALSE) {
3439 ptr = (CK_BYTE *) malloc(attr->ulValueLen);
3440 if (!ptr) {
3441 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
3442 return CKR_HOST_MEMORY;
3443 }
3444 memcpy(ptr, attr->pValue, attr->ulValueLen);
3445
3446 *data = ptr;
3447 }
3448
3449 return CKR_OK;
3450 }
3451
3452
3453 //
3454 //
generic_secret_unwrap(TEMPLATE * tmpl,CK_BYTE * data,CK_ULONG data_len,CK_BBOOL fromend,CK_BBOOL isopaque)3455 CK_RV generic_secret_unwrap(TEMPLATE *tmpl,
3456 CK_BYTE *data,
3457 CK_ULONG data_len,
3458 CK_BBOOL fromend, CK_BBOOL isopaque)
3459 {
3460 CK_ATTRIBUTE *attr = NULL;
3461 CK_ATTRIBUTE *value_attr = NULL;
3462 CK_ATTRIBUTE *value_len_attr = NULL;
3463 CK_BYTE *ptr = NULL;
3464 CK_ULONG rc, len = 0;
3465
3466
3467 if (fromend == TRUE)
3468 ptr = data + data_len;
3469 else
3470 ptr = data;
3471
3472 // it's possible that the user specified CKA_VALUE_LEN in the
3473 // template. if so, try to use it. by default, CKA_VALUE_LEN is 0
3474 //
3475 rc = template_attribute_find(tmpl, CKA_VALUE_LEN, &attr);
3476 if (rc) {
3477 len = *(CK_ULONG *) attr->pValue;
3478 if (len > data_len) {
3479 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
3480 rc = CKR_ATTRIBUTE_VALUE_INVALID;
3481 goto error;
3482 }
3483
3484 if (len != 0)
3485 data_len = len;
3486 }
3487
3488 if (fromend == TRUE)
3489 ptr -= data_len;
3490
3491 if (isopaque)
3492 rc = build_attribute(CKA_IBM_OPAQUE, ptr, data_len, &value_attr);
3493 else
3494 rc = build_attribute(CKA_VALUE, ptr, data_len, &value_attr);
3495
3496 if (rc != CKR_OK) {
3497 TRACE_DEVEL("build_attribute failed\n");
3498 goto error;
3499 }
3500 if (data_len != len) {
3501 rc = build_attribute(CKA_VALUE_LEN, (CK_BYTE *) & data_len,
3502 sizeof(CK_ULONG), &value_len_attr);
3503 if (rc != CKR_OK) {
3504 TRACE_DEVEL("build_attribute failed\n");
3505 goto error;
3506 }
3507 }
3508
3509 template_update_attribute(tmpl, value_attr);
3510
3511 if (data_len != len)
3512 template_update_attribute(tmpl, value_len_attr);
3513
3514 return CKR_OK;
3515
3516 error:
3517 if (value_attr)
3518 free(value_attr);
3519 if (value_len_attr)
3520 free(value_len_attr);
3521
3522 return rc;
3523 }
3524
3525
3526 // rc2_check_required_attributes()
3527 //
rc2_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)3528 CK_RV rc2_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
3529 {
3530 CK_ATTRIBUTE *attr = NULL;
3531 CK_BBOOL found;
3532
3533 found = template_attribute_find(tmpl, CKA_VALUE, &attr);
3534 if (!found) {
3535 if (mode == MODE_CREATE) {
3536 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
3537 return CKR_TEMPLATE_INCOMPLETE;
3538 }
3539 }
3540
3541 found = template_attribute_find(tmpl, CKA_VALUE_LEN, &attr);
3542 if (!found) {
3543 if (mode == MODE_KEYGEN) {
3544 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
3545 return CKR_TEMPLATE_INCOMPLETE;
3546 }
3547 }
3548
3549 return secret_key_check_required_attributes(tmpl, mode);
3550 }
3551
3552
3553 // rc2_set_default_attributes()
3554 //
rc2_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)3555 CK_RV rc2_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
3556 {
3557 CK_ATTRIBUTE *value_attr = NULL;
3558 CK_ATTRIBUTE *value_len_attr = NULL;
3559 CK_ATTRIBUTE *type_attr = NULL;
3560 CK_ULONG len = 0L;
3561
3562 secret_key_set_default_attributes(tmpl, mode);
3563
3564 type_attr =
3565 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
3566 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
3567 value_len_attr =
3568 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG));
3569
3570 if (!type_attr || !value_attr || !value_len_attr) {
3571 if (type_attr)
3572 free(type_attr);
3573 if (value_attr)
3574 free(value_attr);
3575 if (value_len_attr)
3576 free(value_len_attr);
3577 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
3578
3579 return CKR_HOST_MEMORY;
3580 }
3581
3582 value_attr->type = CKA_VALUE;
3583 value_attr->ulValueLen = 0;
3584 value_attr->pValue = NULL;
3585
3586 value_len_attr->type = CKA_VALUE_LEN;
3587 value_len_attr->ulValueLen = sizeof(CK_ULONG);
3588 value_len_attr->pValue = (CK_BYTE *) value_len_attr + sizeof(CK_ATTRIBUTE);
3589 *(CK_ULONG *) value_len_attr->pValue = len;
3590
3591 type_attr->type = CKA_KEY_TYPE;
3592 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
3593 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
3594 *(CK_KEY_TYPE *) type_attr->pValue = CKK_RC2;
3595
3596 template_update_attribute(tmpl, type_attr);
3597 template_update_attribute(tmpl, value_attr);
3598 template_update_attribute(tmpl, value_len_attr);
3599
3600 return CKR_OK;
3601 }
3602
3603
3604 // rc2_validate_attribute()
3605 //
rc2_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)3606 CK_RV rc2_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
3607 CK_ATTRIBUTE *attr, CK_ULONG mode)
3608 {
3609 switch (attr->type) {
3610 case CKA_VALUE:
3611 if (mode != MODE_CREATE) {
3612 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
3613 return CKR_ATTRIBUTE_READ_ONLY;
3614 }
3615 // rc2 key length <= 128 bytes
3616 //
3617 if (attr->ulValueLen > 128)
3618 return CKR_ATTRIBUTE_VALUE_INVALID;
3619
3620 return CKR_OK;
3621 case CKA_VALUE_LEN:
3622 {
3623 CK_ULONG len;
3624
3625 if (mode != MODE_KEYGEN && mode != MODE_DERIVE) {
3626 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
3627 return CKR_ATTRIBUTE_READ_ONLY;
3628 }
3629 len = *(CK_ULONG *) attr->pValue;
3630 if (len > 128) {
3631 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
3632 return CKR_ATTRIBUTE_VALUE_INVALID;
3633 }
3634 return CKR_OK;
3635 }
3636 default:
3637 return secret_key_validate_attribute(tokdata, tmpl, attr, mode);
3638 }
3639 }
3640
3641
3642 // rc4_set_default_attributes()
3643 //
rc4_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)3644 CK_RV rc4_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
3645 {
3646 CK_ATTRIBUTE *value_attr = NULL;
3647 CK_ATTRIBUTE *value_len_attr = NULL;
3648 CK_ATTRIBUTE *type_attr = NULL;
3649 CK_ULONG len = 0L;
3650
3651 secret_key_set_default_attributes(tmpl, mode);
3652
3653 type_attr =
3654 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
3655 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
3656 value_len_attr =
3657 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG));
3658
3659 if (!type_attr || !value_attr || !value_len_attr) {
3660 if (type_attr)
3661 free(type_attr);
3662 if (value_attr)
3663 free(value_attr);
3664 if (value_len_attr)
3665 free(value_len_attr);
3666 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
3667
3668 return CKR_HOST_MEMORY;
3669 }
3670
3671 value_attr->type = CKA_VALUE;
3672 value_attr->ulValueLen = 0;
3673 value_attr->pValue = NULL;
3674
3675 value_len_attr->type = CKA_VALUE_LEN;
3676 value_len_attr->ulValueLen = sizeof(CK_ULONG);
3677 value_len_attr->pValue = (CK_BYTE *) value_len_attr + sizeof(CK_ATTRIBUTE);
3678 *(CK_ULONG *) value_len_attr->pValue = len;
3679
3680 type_attr->type = CKA_KEY_TYPE;
3681 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
3682 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
3683 *(CK_KEY_TYPE *) type_attr->pValue = CKK_RC4;
3684
3685 template_update_attribute(tmpl, type_attr);
3686 template_update_attribute(tmpl, value_attr);
3687 template_update_attribute(tmpl, value_len_attr);
3688
3689 return CKR_OK;
3690 }
3691
3692
3693 // rc4_check_required_attributes()
3694 //
rc4_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)3695 CK_RV rc4_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
3696 {
3697 CK_ATTRIBUTE *attr = NULL;
3698 CK_BBOOL found;
3699
3700 found = template_attribute_find(tmpl, CKA_VALUE, &attr);
3701 if (!found) {
3702 if (mode == MODE_CREATE) {
3703 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
3704 return CKR_TEMPLATE_INCOMPLETE;
3705 }
3706 }
3707
3708 found = template_attribute_find(tmpl, CKA_VALUE_LEN, &attr);
3709 if (!found) {
3710 if (mode == MODE_KEYGEN) {
3711 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
3712 return CKR_TEMPLATE_INCOMPLETE;
3713 }
3714 }
3715
3716 return secret_key_check_required_attributes(tmpl, mode);
3717 }
3718
3719
3720 // rc4_validate_attribute()
3721 //
rc4_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)3722 CK_RV rc4_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
3723 CK_ATTRIBUTE *attr, CK_ULONG mode)
3724 {
3725 switch (attr->type) {
3726 case CKA_VALUE:
3727 if (mode != MODE_CREATE) {
3728 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
3729 return CKR_ATTRIBUTE_READ_ONLY;
3730 }
3731 // key length <= 256 bytes
3732 //
3733 if (attr->ulValueLen > 256) {
3734 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
3735 return CKR_ATTRIBUTE_VALUE_INVALID;
3736 }
3737 return CKR_OK;
3738 case CKA_VALUE_LEN:
3739 {
3740 CK_ULONG len;
3741
3742 if (mode != MODE_KEYGEN && mode != MODE_DERIVE) {
3743 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
3744 return CKR_ATTRIBUTE_READ_ONLY;
3745 }
3746 len = *(CK_ULONG *) attr->pValue;
3747 if (len > 255) {
3748 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
3749 return CKR_ATTRIBUTE_VALUE_INVALID;
3750 }
3751 return CKR_OK;
3752 }
3753 default:
3754 return secret_key_validate_attribute(tokdata, tmpl, attr, mode);
3755 }
3756 }
3757
3758
3759 // rc5_check_required_attributes()
3760 //
rc5_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)3761 CK_RV rc5_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
3762 {
3763 CK_ATTRIBUTE *attr = NULL;
3764 CK_BBOOL found;
3765
3766 found = template_attribute_find(tmpl, CKA_VALUE, &attr);
3767 if (!found) {
3768 if (mode == MODE_CREATE) {
3769 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
3770 return CKR_TEMPLATE_INCOMPLETE;
3771 }
3772 }
3773
3774 found = template_attribute_find(tmpl, CKA_VALUE_LEN, &attr);
3775 if (!found) {
3776 if (mode == MODE_KEYGEN) {
3777 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
3778 return CKR_TEMPLATE_INCOMPLETE;
3779 }
3780 }
3781
3782 return secret_key_check_required_attributes(tmpl, mode);
3783 }
3784
3785
3786 // rc5_set_default_attributes()
3787 //
rc5_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)3788 CK_RV rc5_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
3789 {
3790 CK_ATTRIBUTE *value_attr = NULL;
3791 CK_ATTRIBUTE *value_len_attr = NULL;
3792 CK_ATTRIBUTE *type_attr = NULL;
3793 CK_ULONG len = 0L;
3794
3795 secret_key_set_default_attributes(tmpl, mode);
3796
3797 type_attr =
3798 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
3799 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
3800 value_len_attr =
3801 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG));
3802
3803 if (!type_attr || !value_attr || !value_len_attr) {
3804 if (type_attr)
3805 free(type_attr);
3806 if (value_attr)
3807 free(value_attr);
3808 if (value_len_attr)
3809 free(value_len_attr);
3810
3811 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
3812 return CKR_HOST_MEMORY;
3813 }
3814
3815 value_attr->type = CKA_VALUE;
3816 value_attr->ulValueLen = 0;
3817 value_attr->pValue = NULL;
3818
3819 value_len_attr->type = CKA_VALUE_LEN;
3820 value_len_attr->ulValueLen = sizeof(CK_ULONG);
3821 value_len_attr->pValue = (CK_BYTE *) value_len_attr + sizeof(CK_ATTRIBUTE);
3822 *(CK_ULONG *) value_len_attr->pValue = len;
3823
3824 type_attr->type = CKA_KEY_TYPE;
3825 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
3826 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
3827 *(CK_KEY_TYPE *) type_attr->pValue = CKK_RC5;
3828
3829 template_update_attribute(tmpl, type_attr);
3830 template_update_attribute(tmpl, value_attr);
3831 template_update_attribute(tmpl, value_len_attr);
3832
3833 return CKR_OK;
3834 }
3835
3836
3837 // rc5_validate_attribute()
3838 //
rc5_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)3839 CK_RV rc5_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
3840 CK_ATTRIBUTE *attr, CK_ULONG mode)
3841 {
3842 switch (attr->type) {
3843 case CKA_VALUE:
3844 if (mode != MODE_CREATE) {
3845 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
3846 return CKR_ATTRIBUTE_READ_ONLY;
3847 }
3848 // key length <= 256 bytes
3849 //
3850 if (attr->ulValueLen > 255) {
3851 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
3852 return CKR_ATTRIBUTE_VALUE_INVALID;
3853 }
3854 return CKR_OK;
3855 case CKA_VALUE_LEN:
3856 {
3857 CK_ULONG len;
3858
3859 if (mode != MODE_KEYGEN && mode != MODE_DERIVE) {
3860 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
3861 return CKR_ATTRIBUTE_READ_ONLY;
3862 }
3863 len = *(CK_ULONG *) attr->pValue;
3864 if (len > 255) {
3865 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
3866 return CKR_ATTRIBUTE_VALUE_INVALID;
3867 }
3868 return CKR_OK;
3869 }
3870 default:
3871 return secret_key_validate_attribute(tokdata, tmpl, attr, mode);
3872 }
3873 }
3874
3875
3876 //
3877 //
des_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)3878 CK_RV des_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
3879 {
3880 CK_ATTRIBUTE *attr = NULL;
3881 CK_BBOOL found;
3882
3883 found = template_attribute_find(tmpl, CKA_VALUE, &attr);
3884 if (!found) {
3885 if (mode == MODE_CREATE) {
3886 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
3887 return CKR_TEMPLATE_INCOMPLETE;
3888 }
3889 }
3890
3891 return secret_key_check_required_attributes(tmpl, mode);
3892 }
3893
3894
3895 //
3896 //
des_check_weak_key(CK_BYTE * key)3897 CK_BBOOL des_check_weak_key(CK_BYTE *key)
3898 {
3899 CK_ULONG i;
3900
3901 for (i = 0; i < des_weak_count; i++) {
3902 if (memcmp(key, des_weak_keys[i], DES_KEY_SIZE) == 0)
3903 return TRUE;
3904 }
3905
3906 for (i = 0; i < des_semi_weak_count; i++) {
3907 if (memcmp(key, des_semi_weak_keys[i], DES_KEY_SIZE) == 0)
3908 return TRUE;
3909 }
3910
3911 for (i = 0; i < des_possibly_weak_count; i++) {
3912 if (memcmp(key, des_possibly_weak_keys[i], DES_KEY_SIZE) == 0)
3913 return TRUE;
3914 }
3915
3916 return FALSE;
3917 }
3918
3919
3920
3921 //
3922 //
des_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)3923 CK_RV des_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
3924 {
3925 CK_ATTRIBUTE *value_attr = NULL;
3926 CK_ATTRIBUTE *type_attr = NULL;
3927
3928 if (mode)
3929 value_attr = NULL;
3930
3931 secret_key_set_default_attributes(tmpl, mode);
3932
3933 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
3934 type_attr =
3935 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
3936
3937 if (!value_attr || !type_attr) {
3938 if (value_attr)
3939 free(value_attr);
3940 if (type_attr)
3941 free(type_attr);
3942
3943 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
3944 return CKR_HOST_MEMORY;
3945 }
3946
3947 value_attr->type = CKA_VALUE;
3948 value_attr->ulValueLen = 0;
3949 value_attr->pValue = NULL;
3950
3951 type_attr->type = CKA_KEY_TYPE;
3952 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
3953 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
3954 *(CK_KEY_TYPE *) type_attr->pValue = CKK_DES;
3955
3956 template_update_attribute(tmpl, type_attr);
3957 template_update_attribute(tmpl, value_attr);
3958
3959 return CKR_OK;
3960 }
3961
3962
3963 //
3964 //
des_unwrap(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_BYTE * data,CK_ULONG data_len,CK_BBOOL fromend,CK_BBOOL isopaque)3965 CK_RV des_unwrap(STDLL_TokData_t *tokdata,
3966 TEMPLATE *tmpl,
3967 CK_BYTE *data,
3968 CK_ULONG data_len, CK_BBOOL fromend, CK_BBOOL isopaque)
3969 {
3970 CK_ATTRIBUTE *value_attr = NULL;
3971 CK_BYTE *ptr = NULL;
3972 CK_ULONG i;
3973
3974
3975 if (data_len < DES_BLOCK_SIZE) {
3976 TRACE_ERROR("%s\n", ock_err(ERR_WRAPPED_KEY_INVALID));
3977 return CKR_WRAPPED_KEY_INVALID;
3978 }
3979 if (fromend == TRUE) {
3980 if (isopaque)
3981 ptr = data + data_len;
3982 else
3983 ptr = data + data_len - DES_BLOCK_SIZE;
3984 } else {
3985 ptr = data;
3986 }
3987
3988 if (isopaque) {
3989 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + data_len);
3990 } else {
3991 if (tokdata->nv_token_data->tweak_vector.check_des_parity == TRUE) {
3992 for (i = 0; i < DES_KEY_SIZE; i++) {
3993 if (parity_is_odd(ptr[i]) == FALSE) {
3994 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
3995 return CKR_ATTRIBUTE_VALUE_INVALID;
3996 }
3997 }
3998 }
3999 value_attr =
4000 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + DES_BLOCK_SIZE);
4001 }
4002
4003 if (!value_attr) {
4004 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
4005 return CKR_HOST_MEMORY;
4006 }
4007
4008 if (isopaque) {
4009 value_attr->type = CKA_IBM_OPAQUE;
4010 value_attr->ulValueLen = data_len;
4011 value_attr->pValue = (CK_BYTE *) value_attr + sizeof(CK_ATTRIBUTE);
4012 memcpy(value_attr->pValue, ptr, data_len);
4013 } else {
4014 value_attr->type = CKA_VALUE;
4015 value_attr->ulValueLen = DES_BLOCK_SIZE;
4016 value_attr->pValue = (CK_BYTE *) value_attr + sizeof(CK_ATTRIBUTE);
4017 memcpy(value_attr->pValue, ptr, DES_BLOCK_SIZE);
4018 }
4019
4020 template_update_attribute(tmpl, value_attr);
4021
4022 return CKR_OK;
4023 }
4024
4025
4026 // des_validate_attribute()
4027 //
des_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)4028 CK_RV des_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
4029 CK_ATTRIBUTE *attr, CK_ULONG mode)
4030 {
4031 CK_BYTE *ptr = NULL;
4032 CK_ULONG i;
4033
4034 switch (attr->type) {
4035 case CKA_VALUE:
4036 // key length always 8 bytes
4037 //
4038 if (mode == MODE_CREATE) {
4039 if (attr->ulValueLen != DES_KEY_SIZE) {
4040 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
4041 return CKR_ATTRIBUTE_VALUE_INVALID;
4042 }
4043 if (tokdata->nv_token_data->tweak_vector.check_des_parity == TRUE) {
4044 ptr = attr->pValue;
4045 for (i = 0; i < DES_KEY_SIZE; i++) {
4046 if (parity_is_odd(ptr[i]) == FALSE) {
4047 TRACE_ERROR("%s\n",
4048 ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
4049 return CKR_ATTRIBUTE_VALUE_INVALID;
4050 }
4051 }
4052 }
4053 return CKR_OK;
4054 }
4055 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
4056 return CKR_ATTRIBUTE_READ_ONLY;
4057 case CKA_VALUE_LEN:
4058 // Cryptoki doesn't allow this but Netscape tries uses it
4059 //
4060 if (tokdata->nv_token_data->tweak_vector.netscape_mods == TRUE) {
4061 if (mode == MODE_CREATE || mode == MODE_DERIVE ||
4062 mode == MODE_KEYGEN || mode == MODE_UNWRAP) {
4063 CK_ULONG len = *(CK_ULONG *) attr->pValue;
4064 if (len != DES_KEY_SIZE) {
4065 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
4066 return CKR_ATTRIBUTE_VALUE_INVALID;
4067 }
4068 return CKR_OK;
4069 }
4070 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
4071 return CKR_ATTRIBUTE_READ_ONLY;
4072 }
4073 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT));
4074 return CKR_TEMPLATE_INCONSISTENT;
4075 default:
4076 return secret_key_validate_attribute(tokdata, tmpl, attr, mode);
4077 }
4078 }
4079
4080
4081 //
4082 //
des_wrap_get_data(TEMPLATE * tmpl,CK_BBOOL length_only,CK_BYTE ** data,CK_ULONG * data_len)4083 CK_RV des_wrap_get_data(TEMPLATE *tmpl,
4084 CK_BBOOL length_only,
4085 CK_BYTE **data, CK_ULONG *data_len)
4086 {
4087 CK_ATTRIBUTE *attr = NULL;
4088 CK_BYTE *ptr = NULL;
4089 CK_RV rc;
4090
4091
4092 if (!tmpl || !data_len) {
4093 TRACE_ERROR("Invalid function arguments.\n");
4094 return CKR_FUNCTION_FAILED;
4095 }
4096
4097 rc = template_attribute_find(tmpl, CKA_IBM_OPAQUE, &attr);
4098 if (rc == FALSE) {
4099 rc = template_attribute_find(tmpl, CKA_VALUE, &attr);
4100 if (rc == FALSE) {
4101 TRACE_ERROR("%s\n", ock_err(ERR_KEY_NOT_WRAPPABLE));
4102 return CKR_KEY_NOT_WRAPPABLE;
4103 }
4104 }
4105 *data_len = attr->ulValueLen;
4106
4107 if (length_only == FALSE) {
4108 ptr = (CK_BYTE *) malloc(attr->ulValueLen);
4109 if (!ptr) {
4110 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
4111 return CKR_HOST_MEMORY;
4112 }
4113 memcpy(ptr, attr->pValue, attr->ulValueLen);
4114
4115 *data = ptr;
4116 }
4117
4118 return CKR_OK;
4119 }
4120
4121
4122 // des2_check_required_attributes()
4123 //
des2_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)4124 CK_RV des2_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
4125 {
4126 CK_ATTRIBUTE *attr = NULL;
4127 CK_BBOOL found;
4128
4129 found = template_attribute_find(tmpl, CKA_VALUE, &attr);
4130 if (!found) {
4131 if (mode == MODE_CREATE) {
4132 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
4133 return CKR_TEMPLATE_INCOMPLETE;
4134 }
4135 }
4136
4137 return secret_key_check_required_attributes(tmpl, mode);
4138 }
4139
4140
4141 // des2_set_default_attributes()
4142 //
des2_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)4143 CK_RV des2_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
4144 {
4145 CK_ATTRIBUTE *value_attr = NULL;
4146 CK_ATTRIBUTE *type_attr = NULL;
4147
4148 if (mode)
4149 value_attr = NULL;
4150
4151 secret_key_set_default_attributes(tmpl, mode);
4152
4153 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
4154 type_attr =
4155 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
4156
4157 if (!value_attr || !type_attr) {
4158 if (value_attr)
4159 free(value_attr);
4160 if (type_attr)
4161 free(type_attr);
4162 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
4163
4164 return CKR_HOST_MEMORY;
4165 }
4166
4167 value_attr->type = CKA_VALUE;
4168 value_attr->ulValueLen = 0;
4169 value_attr->pValue = NULL;
4170
4171 type_attr->type = CKA_KEY_TYPE;
4172 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
4173 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
4174 *(CK_KEY_TYPE *) type_attr->pValue = CKK_DES2;
4175
4176 template_update_attribute(tmpl, type_attr);
4177 template_update_attribute(tmpl, value_attr);
4178
4179 return CKR_OK;
4180 }
4181
4182
4183 // des2_validate_attribute()
4184 //
des2_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)4185 CK_RV des2_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
4186 CK_ATTRIBUTE *attr, CK_ULONG mode)
4187 {
4188 CK_BYTE *ptr = NULL;
4189 CK_ULONG i;
4190
4191 switch (attr->type) {
4192 case CKA_VALUE:
4193 // key length always 16 bytes
4194 //
4195 if (mode == MODE_CREATE) {
4196 if (attr->ulValueLen != (2 * DES_KEY_SIZE)) {
4197 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
4198 return CKR_ATTRIBUTE_VALUE_INVALID;
4199 }
4200 if (tokdata->nv_token_data->tweak_vector.check_des_parity == TRUE) {
4201 ptr = attr->pValue;
4202 for (i = 0; i < 2 * DES_KEY_SIZE; i++) {
4203 if (parity_is_odd(ptr[i]) == FALSE) {
4204 TRACE_ERROR("%s\n",
4205 ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
4206 return CKR_ATTRIBUTE_VALUE_INVALID;
4207 }
4208 }
4209 }
4210 return CKR_OK;
4211 }
4212 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
4213 return CKR_ATTRIBUTE_READ_ONLY;
4214 case CKA_VALUE_LEN:
4215 // Cryptoki doesn't allow this but Netscape tries uses it
4216 //
4217 if (tokdata->nv_token_data->tweak_vector.netscape_mods == TRUE) {
4218 if (mode == MODE_CREATE || mode == MODE_DERIVE ||
4219 mode == MODE_KEYGEN || mode == MODE_UNWRAP) {
4220 CK_ULONG len = *(CK_ULONG *) attr->pValue;
4221 if (len != (2 * DES_KEY_SIZE)) {
4222 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
4223 return CKR_ATTRIBUTE_VALUE_INVALID;
4224 }
4225 return CKR_OK;
4226 }
4227 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
4228 return CKR_ATTRIBUTE_READ_ONLY;
4229 }
4230 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT));
4231 return CKR_TEMPLATE_INCONSISTENT;
4232 default:
4233 return secret_key_validate_attribute(tokdata, tmpl, attr, mode);
4234 }
4235 }
4236
4237
4238 // des3_check_required_attributes()
4239 //
des3_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)4240 CK_RV des3_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
4241 {
4242 CK_ATTRIBUTE *attr = NULL;
4243 CK_BBOOL found;
4244
4245 found = template_attribute_find(tmpl, CKA_VALUE, &attr);
4246 if (!found) {
4247 if (mode == MODE_CREATE) {
4248 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
4249 return CKR_TEMPLATE_INCOMPLETE;
4250 }
4251 }
4252
4253 return secret_key_check_required_attributes(tmpl, mode);
4254 }
4255
4256
4257 // des3_set_default_attributes()
4258 //
des3_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)4259 CK_RV des3_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
4260 {
4261 CK_ATTRIBUTE *value_attr = NULL;
4262 CK_ATTRIBUTE *type_attr = NULL;
4263
4264 if (mode)
4265 value_attr = NULL;
4266
4267 secret_key_set_default_attributes(tmpl, mode);
4268
4269 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
4270 type_attr =
4271 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
4272
4273 if (!value_attr || !type_attr) {
4274 if (value_attr)
4275 free(value_attr);
4276 if (type_attr)
4277 free(type_attr);
4278 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
4279
4280 return CKR_HOST_MEMORY;
4281 }
4282
4283 value_attr->type = CKA_VALUE;
4284 value_attr->ulValueLen = 0;
4285 value_attr->pValue = NULL;
4286
4287 type_attr->type = CKA_KEY_TYPE;
4288 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
4289 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
4290 *(CK_KEY_TYPE *) type_attr->pValue = CKK_DES3;
4291
4292 template_update_attribute(tmpl, type_attr);
4293 template_update_attribute(tmpl, value_attr);
4294
4295 return CKR_OK;
4296 }
4297
4298
4299 //
4300 //
des3_unwrap(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_BYTE * data,CK_ULONG data_len,CK_BBOOL fromend,CK_BBOOL isopaque)4301 CK_RV des3_unwrap(STDLL_TokData_t *tokdata,
4302 TEMPLATE *tmpl,
4303 CK_BYTE *data,
4304 CK_ULONG data_len, CK_BBOOL fromend, CK_BBOOL isopaque)
4305 {
4306 CK_ATTRIBUTE *value_attr = NULL;
4307 CK_BYTE *ptr = NULL;
4308 CK_ULONG i;
4309
4310
4311 if (data_len < 3 * DES_BLOCK_SIZE) {
4312 TRACE_ERROR("%s\n", ock_err(ERR_WRAPPED_KEY_INVALID));
4313 return CKR_WRAPPED_KEY_INVALID;
4314 }
4315 if (fromend == TRUE) {
4316 if (isopaque)
4317 ptr = data + data_len;
4318 else
4319 ptr = data + data_len - (3 * DES_BLOCK_SIZE);
4320 } else {
4321 ptr = data;
4322 }
4323
4324 if (isopaque) {
4325 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + data_len);
4326 } else {
4327 if (tokdata->nv_token_data->tweak_vector.check_des_parity == TRUE) {
4328 for (i = 0; i < 3 * DES_KEY_SIZE; i++) {
4329 if (parity_is_odd(ptr[i]) == FALSE) {
4330 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
4331 return CKR_ATTRIBUTE_VALUE_INVALID;
4332 }
4333 }
4334 }
4335 value_attr =
4336 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) +
4337 (3 * DES_BLOCK_SIZE));
4338 }
4339
4340 if (!value_attr) {
4341 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
4342 return CKR_HOST_MEMORY;
4343 }
4344
4345 if (isopaque) {
4346 value_attr->type = CKA_IBM_OPAQUE;
4347 value_attr->ulValueLen = data_len;
4348 value_attr->pValue = (CK_BYTE *) value_attr + sizeof(CK_ATTRIBUTE);
4349 memcpy(value_attr->pValue, ptr, data_len);
4350 } else {
4351 value_attr->type = CKA_VALUE;
4352 value_attr->ulValueLen = 3 * DES_BLOCK_SIZE;
4353 value_attr->pValue = (CK_BYTE *) value_attr + sizeof(CK_ATTRIBUTE);
4354 memcpy(value_attr->pValue, ptr, 3 * DES_BLOCK_SIZE);
4355 }
4356
4357 template_update_attribute(tmpl, value_attr);
4358
4359 return CKR_OK;
4360 }
4361
4362
4363 //
4364 //
des3_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)4365 CK_RV des3_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
4366 CK_ATTRIBUTE *attr, CK_ULONG mode)
4367 {
4368 CK_BYTE *ptr = NULL;
4369 CK_ULONG i;
4370
4371 switch (attr->type) {
4372 case CKA_VALUE:
4373 // key length always 24 bytes
4374 //
4375 if (mode == MODE_CREATE) {
4376 if (attr->ulValueLen != (3 * DES_KEY_SIZE)) {
4377 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
4378 return CKR_ATTRIBUTE_VALUE_INVALID;
4379 }
4380 if (tokdata->nv_token_data->tweak_vector.check_des_parity == TRUE) {
4381 ptr = attr->pValue;
4382 for (i = 0; i < 3 * DES_KEY_SIZE; i++) {
4383 if (parity_is_odd(ptr[i]) == FALSE) {
4384 TRACE_ERROR("%s\n",
4385 ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
4386 return CKR_ATTRIBUTE_VALUE_INVALID;
4387 }
4388 }
4389 }
4390 return CKR_OK;
4391 }
4392 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
4393 return CKR_ATTRIBUTE_READ_ONLY;
4394 case CKA_VALUE_LEN:
4395 // Cryptoki doesn't allow this but Netscape tries uses it
4396 //
4397 if (tokdata->nv_token_data->tweak_vector.netscape_mods == TRUE) {
4398 if (mode == MODE_CREATE || mode == MODE_DERIVE ||
4399 mode == MODE_KEYGEN || mode == MODE_UNWRAP) {
4400 return CKR_OK;
4401 }
4402 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
4403 return CKR_ATTRIBUTE_READ_ONLY;
4404 }
4405 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT));
4406 return CKR_TEMPLATE_INCONSISTENT;
4407 default:
4408 return secret_key_validate_attribute(tokdata, tmpl, attr, mode);
4409 }
4410 }
4411
4412
4413 //
4414 //
des3_wrap_get_data(TEMPLATE * tmpl,CK_BBOOL length_only,CK_BYTE ** data,CK_ULONG * data_len)4415 CK_RV des3_wrap_get_data(TEMPLATE *tmpl,
4416 CK_BBOOL length_only,
4417 CK_BYTE **data, CK_ULONG *data_len)
4418 {
4419 CK_ATTRIBUTE *attr = NULL;
4420 CK_BYTE *ptr = NULL;
4421 CK_RV rc;
4422
4423
4424 if (!tmpl || !data_len) {
4425 TRACE_ERROR("Invalid function arguments.\n");
4426 return CKR_FUNCTION_FAILED;
4427 }
4428 // try secure key first, if not found then try clear key...
4429 rc = template_attribute_find(tmpl, CKA_IBM_OPAQUE, &attr);
4430 if (rc == FALSE) {
4431 rc = template_attribute_find(tmpl, CKA_VALUE, &attr);
4432 if (rc == FALSE) {
4433 TRACE_ERROR("%s\n", ock_err(ERR_KEY_NOT_WRAPPABLE));
4434 return CKR_KEY_NOT_WRAPPABLE;
4435 }
4436 }
4437 *data_len = attr->ulValueLen;
4438
4439 if (length_only == FALSE) {
4440 ptr = (CK_BYTE *) malloc(attr->ulValueLen);
4441 if (!ptr) {
4442 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
4443 return CKR_HOST_MEMORY;
4444 }
4445 memcpy(ptr, attr->pValue, attr->ulValueLen);
4446
4447 *data = ptr;
4448 }
4449
4450 return CKR_OK;
4451 }
4452
4453
4454 // cast_check_required_attributes()
4455 //
cast_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)4456 CK_RV cast_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
4457 {
4458 CK_ATTRIBUTE *attr = NULL;
4459 CK_BBOOL found;
4460
4461 found = template_attribute_find(tmpl, CKA_VALUE, &attr);
4462 if (!found) {
4463 if (mode == MODE_CREATE) {
4464 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
4465 return CKR_TEMPLATE_INCOMPLETE;
4466 }
4467 }
4468
4469 found = template_attribute_find(tmpl, CKA_VALUE_LEN, &attr);
4470 if (!found) {
4471 if (mode == MODE_KEYGEN) {
4472 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
4473 return CKR_TEMPLATE_INCOMPLETE;
4474 }
4475 }
4476
4477 return secret_key_check_required_attributes(tmpl, mode);
4478 }
4479
4480
4481 // cast_set_default_attributes()
4482 //
cast_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)4483 CK_RV cast_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
4484 {
4485 CK_ATTRIBUTE *value_attr = NULL;
4486 CK_ATTRIBUTE *value_len_attr = NULL;
4487 CK_ATTRIBUTE *type_attr = NULL;
4488 CK_ULONG len = 0L;
4489
4490
4491 secret_key_set_default_attributes(tmpl, mode);
4492
4493 type_attr =
4494 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
4495 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
4496 value_len_attr =
4497 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG));
4498
4499 if (!type_attr || !value_attr || !value_len_attr) {
4500 if (type_attr)
4501 free(type_attr);
4502 if (value_attr)
4503 free(value_attr);
4504 if (value_len_attr)
4505 free(value_len_attr);
4506
4507 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
4508 return CKR_HOST_MEMORY;
4509 }
4510
4511 value_attr->type = CKA_VALUE;
4512 value_attr->ulValueLen = 0;
4513 value_attr->pValue = NULL;
4514
4515 value_len_attr->type = CKA_VALUE_LEN;
4516 value_len_attr->ulValueLen = sizeof(CK_ULONG);
4517 value_len_attr->pValue = (CK_BYTE *) value_len_attr + sizeof(CK_ATTRIBUTE);
4518 *(CK_ULONG *) value_len_attr->pValue = len;
4519
4520 type_attr->type = CKA_KEY_TYPE;
4521 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
4522 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
4523 *(CK_KEY_TYPE *) type_attr->pValue = CKK_CAST;
4524
4525 template_update_attribute(tmpl, type_attr);
4526 template_update_attribute(tmpl, value_attr);
4527 template_update_attribute(tmpl, value_len_attr);
4528
4529 return CKR_OK;
4530 }
4531
4532
4533 // cast_validate_attribute()
4534 //
cast_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)4535 CK_RV cast_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
4536 CK_ATTRIBUTE *attr, CK_ULONG mode)
4537 {
4538 CK_ULONG len;
4539
4540 switch (attr->type) {
4541 case CKA_VALUE:
4542 if (mode != MODE_CREATE) {
4543 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
4544 return CKR_ATTRIBUTE_READ_ONLY;
4545 }
4546 if (attr->ulValueLen > 8 || attr->ulValueLen < 1) {
4547 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
4548 return CKR_ATTRIBUTE_VALUE_INVALID;
4549 }
4550 return CKR_OK;
4551 case CKA_VALUE_LEN:
4552 if (mode != MODE_KEYGEN && mode != MODE_DERIVE) {
4553 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
4554 return CKR_ATTRIBUTE_READ_ONLY;
4555 }
4556 len = *(CK_ULONG *) attr->pValue;
4557 if (len > 8 || len < 1) {
4558 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
4559 return CKR_ATTRIBUTE_VALUE_INVALID;
4560 }
4561 return CKR_OK;
4562 default:
4563 return secret_key_validate_attribute(tokdata, tmpl, attr, mode);
4564 }
4565 }
4566
4567
4568 // cast3_check_required_attributes()
4569 //
cast3_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)4570 CK_RV cast3_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
4571 {
4572 CK_ATTRIBUTE *attr = NULL;
4573 CK_BBOOL found;
4574
4575 found = template_attribute_find(tmpl, CKA_VALUE, &attr);
4576 if (!found) {
4577 if (mode == MODE_CREATE) {
4578 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
4579 return CKR_TEMPLATE_INCOMPLETE;
4580 }
4581 }
4582
4583 found = template_attribute_find(tmpl, CKA_VALUE_LEN, &attr);
4584 if (!found) {
4585 if (mode == MODE_KEYGEN) {
4586 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
4587 return CKR_TEMPLATE_INCOMPLETE;
4588 }
4589 }
4590
4591 return secret_key_check_required_attributes(tmpl, mode);
4592 }
4593
4594
4595 // cast3_set_default_attributes()
4596 //
cast3_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)4597 CK_RV cast3_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
4598 {
4599 CK_ATTRIBUTE *value_attr = NULL;
4600 CK_ATTRIBUTE *value_len_attr = NULL;
4601 CK_ATTRIBUTE *type_attr = NULL;
4602 CK_ULONG len = 0L;
4603
4604 if (mode)
4605 value_attr = NULL;
4606
4607 secret_key_set_default_attributes(tmpl, mode);
4608
4609 type_attr =
4610 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
4611 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
4612 value_len_attr =
4613 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG));
4614
4615 if (!type_attr || !value_attr || !value_len_attr) {
4616 if (type_attr)
4617 free(type_attr);
4618 if (value_attr)
4619 free(value_attr);
4620 if (value_len_attr)
4621 free(value_len_attr);
4622
4623 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
4624 return CKR_HOST_MEMORY;
4625 }
4626
4627 value_attr->type = CKA_VALUE;
4628 value_attr->ulValueLen = 0;
4629 value_attr->pValue = NULL;
4630
4631 value_len_attr->type = CKA_VALUE_LEN;
4632 value_len_attr->ulValueLen = sizeof(CK_ULONG);
4633 value_len_attr->pValue = (CK_BYTE *) value_len_attr + sizeof(CK_ATTRIBUTE);
4634 *(CK_ULONG *) value_len_attr->pValue = len;
4635
4636 type_attr->type = CKA_KEY_TYPE;
4637 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
4638 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
4639 *(CK_KEY_TYPE *) type_attr->pValue = CKK_CAST3;
4640
4641 template_update_attribute(tmpl, type_attr);
4642 template_update_attribute(tmpl, value_attr);
4643 template_update_attribute(tmpl, value_len_attr);
4644
4645 return CKR_OK;
4646 }
4647
4648
4649 // cast3_validate_attribute()
4650 //
cast3_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)4651 CK_RV cast3_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
4652 CK_ATTRIBUTE *attr, CK_ULONG mode)
4653 {
4654 CK_ULONG len;
4655
4656 switch (attr->type) {
4657 case CKA_VALUE:
4658 if (mode != MODE_CREATE) {
4659 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
4660 return CKR_ATTRIBUTE_READ_ONLY;
4661 }
4662 if (attr->ulValueLen > 8 || attr->ulValueLen < 1) {
4663 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
4664 return CKR_ATTRIBUTE_VALUE_INVALID;
4665 }
4666 return CKR_OK;
4667 case CKA_VALUE_LEN:
4668 if (mode != MODE_KEYGEN && mode != MODE_DERIVE) {
4669 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
4670 return CKR_ATTRIBUTE_READ_ONLY;
4671 }
4672 len = *(CK_ULONG *) attr->pValue;
4673 if (len > 8 || len < 1) {
4674 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
4675 return CKR_ATTRIBUTE_VALUE_INVALID;
4676 }
4677 return CKR_OK;
4678 default:
4679 return secret_key_validate_attribute(tokdata, tmpl, attr, mode);
4680 }
4681 }
4682
4683
4684 // cast5_check_required_attributes()
4685 //
cast5_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)4686 CK_RV cast5_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
4687 {
4688 CK_ATTRIBUTE *attr = NULL;
4689 CK_BBOOL found;
4690
4691 found = template_attribute_find(tmpl, CKA_VALUE, &attr);
4692 if (!found) {
4693 if (mode == MODE_CREATE) {
4694 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
4695 return CKR_TEMPLATE_INCOMPLETE;
4696 }
4697 }
4698 found = template_attribute_find(tmpl, CKA_VALUE_LEN, &attr);
4699 if (!found) {
4700 if (mode == MODE_KEYGEN) {
4701 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
4702 return CKR_TEMPLATE_INCOMPLETE;
4703 }
4704 }
4705
4706 return secret_key_check_required_attributes(tmpl, mode);
4707 }
4708
4709
4710 // cast5_set_default_attributes()
4711 //
cast5_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)4712 CK_RV cast5_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
4713 {
4714 CK_ATTRIBUTE *value_attr = NULL;
4715 CK_ATTRIBUTE *value_len_attr = NULL;
4716 CK_ATTRIBUTE *type_attr = NULL;
4717 CK_ULONG len = 0L;
4718
4719 secret_key_set_default_attributes(tmpl, mode);
4720
4721 type_attr =
4722 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
4723 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
4724 value_len_attr =
4725 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG));
4726
4727 if (!type_attr || !value_attr || !value_len_attr) {
4728 if (type_attr)
4729 free(type_attr);
4730 if (value_attr)
4731 free(value_attr);
4732 if (value_len_attr)
4733 free(value_len_attr);
4734
4735 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
4736 return CKR_HOST_MEMORY;
4737 }
4738
4739 value_attr->type = CKA_VALUE;
4740 value_attr->ulValueLen = 0;
4741 value_attr->pValue = NULL;
4742
4743 value_len_attr->type = CKA_VALUE_LEN;
4744 value_len_attr->ulValueLen = sizeof(CK_ULONG);
4745 value_len_attr->pValue = (CK_BYTE *) value_len_attr + sizeof(CK_ATTRIBUTE);
4746 *(CK_ULONG *) value_len_attr->pValue = len;
4747
4748 type_attr->type = CKA_KEY_TYPE;
4749 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
4750 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
4751 *(CK_KEY_TYPE *) type_attr->pValue = CKK_CAST5;
4752
4753 template_update_attribute(tmpl, type_attr);
4754 template_update_attribute(tmpl, value_attr);
4755 template_update_attribute(tmpl, value_len_attr);
4756
4757 return CKR_OK;
4758 }
4759
4760
4761 // cast5_validate_attribute()
4762 //
cast5_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)4763 CK_RV cast5_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
4764 CK_ATTRIBUTE *attr, CK_ULONG mode)
4765 {
4766 CK_ULONG len;
4767
4768 switch (attr->type) {
4769 case CKA_VALUE:
4770 if (mode != MODE_CREATE) {
4771 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
4772 return CKR_ATTRIBUTE_READ_ONLY;
4773 }
4774 if (attr->ulValueLen > 16 || attr->ulValueLen < 1) {
4775 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
4776 return CKR_ATTRIBUTE_VALUE_INVALID;
4777 }
4778 return CKR_OK;
4779 case CKA_VALUE_LEN:
4780 if (mode != MODE_KEYGEN && mode != MODE_DERIVE) {
4781 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
4782 return CKR_ATTRIBUTE_READ_ONLY;
4783 }
4784 len = *(CK_ULONG *) attr->pValue;
4785 if (len < 1 || len > 16) {
4786 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
4787 return CKR_ATTRIBUTE_VALUE_INVALID;
4788 }
4789 return CKR_OK;
4790 default:
4791 return secret_key_validate_attribute(tokdata, tmpl, attr, mode);
4792 }
4793 }
4794
4795
4796 // idea_check_required_attributes()
4797 //
idea_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)4798 CK_RV idea_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
4799 {
4800 CK_ATTRIBUTE *attr = NULL;
4801 CK_BBOOL found;
4802
4803 found = template_attribute_find(tmpl, CKA_VALUE, &attr);
4804 if (!found) {
4805 if (mode == MODE_CREATE) {
4806 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
4807 return CKR_TEMPLATE_INCOMPLETE;
4808 }
4809 }
4810
4811 return secret_key_check_required_attributes(tmpl, mode);
4812 }
4813
4814
4815 // idea_set_default_attributes()
4816 //
idea_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)4817 CK_RV idea_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
4818 {
4819 CK_ATTRIBUTE *value_attr = NULL;
4820 CK_ATTRIBUTE *type_attr = NULL;
4821
4822 if (mode)
4823 value_attr = NULL;
4824
4825 secret_key_set_default_attributes(tmpl, mode);
4826
4827 type_attr =
4828 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
4829 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
4830 if (!type_attr || !value_attr) {
4831 if (type_attr)
4832 free(type_attr);
4833 if (value_attr)
4834 free(value_attr);
4835
4836 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
4837 return CKR_HOST_MEMORY;
4838 }
4839
4840 value_attr->type = CKA_VALUE;
4841 value_attr->ulValueLen = 0;
4842 value_attr->pValue = NULL;
4843
4844 type_attr->type = CKA_KEY_TYPE;
4845 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
4846 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
4847 *(CK_KEY_TYPE *) type_attr->pValue = CKK_IDEA;
4848
4849 template_update_attribute(tmpl, type_attr);
4850 template_update_attribute(tmpl, value_attr);
4851
4852 return CKR_OK;
4853 }
4854
4855
4856 // idea_validate_attribute()
4857 //
idea_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)4858 CK_RV idea_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
4859 CK_ATTRIBUTE *attr, CK_ULONG mode)
4860 {
4861 switch (attr->type) {
4862 case CKA_VALUE:
4863 if (mode != MODE_CREATE) {
4864 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
4865 return CKR_ATTRIBUTE_READ_ONLY;
4866 }
4867 if (attr->ulValueLen != 16) {
4868 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
4869 return CKR_ATTRIBUTE_VALUE_INVALID;
4870 }
4871 return CKR_OK;
4872 default:
4873 return secret_key_validate_attribute(tokdata, tmpl, attr, mode);
4874 }
4875 }
4876
4877
4878 // cdmf_check_required_attributes()
4879 //
cdmf_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)4880 CK_RV cdmf_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
4881 {
4882 CK_ATTRIBUTE *attr = NULL;
4883 CK_BBOOL found;
4884
4885 found = template_attribute_find(tmpl, CKA_VALUE, &attr);
4886 if (!found) {
4887 if (mode == MODE_CREATE) {
4888 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
4889 return CKR_TEMPLATE_INCOMPLETE;
4890 }
4891 }
4892
4893 return secret_key_check_required_attributes(tmpl, mode);
4894 }
4895
4896
4897 #if !(NOCDMF)
4898 // cdmf_set_default_attributes()
4899 //
cdmf_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)4900 CK_RV cdmf_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
4901 {
4902 CK_ATTRIBUTE *value_attr = NULL;
4903 CK_ATTRIBUTE *type_attr = NULL;
4904
4905 if (mode)
4906 value_attr = NULL;
4907
4908 secret_key_set_default_attributes(tmpl, mode);
4909
4910 type_attr =
4911 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
4912 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
4913
4914 if (!type_attr || !value_attr) {
4915 if (type_attr)
4916 free(type_attr);
4917 if (value_attr)
4918 free(value_attr);
4919
4920 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
4921 return CKR_HOST_MEMORY;
4922 }
4923
4924 value_attr->type = CKA_VALUE;
4925 value_attr->ulValueLen = 0;
4926 value_attr->pValue = NULL;
4927
4928 type_attr->type = CKA_KEY_TYPE;
4929 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
4930 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
4931 *(CK_KEY_TYPE *) type_attr->pValue = CKK_CDMF;
4932
4933 template_update_attribute(tmpl, type_attr);
4934 template_update_attribute(tmpl, value_attr);
4935
4936 return CKR_OK;
4937 }
4938
4939
4940 // cdmf_validate_attribute()
4941 //
cdmf_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)4942 CK_RV cdmf_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
4943 CK_ATTRIBUTE *attr, CK_ULONG mode)
4944 {
4945 CK_ULONG len;
4946
4947 switch (attr->type) {
4948 case CKA_VALUE:
4949 #if 0
4950 CDMF_Transform_Args args;
4951 #endif
4952 CK_ULONG req_len, repl_len;
4953 CK_BYTE cdmf_key[DES_KEY_SIZE];
4954 CK_RV rc;
4955
4956 if (mode != MODE_CREATE) {
4957 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
4958 return CKR_ATTRIBUTE_READ_ONLY;
4959 }
4960 if (attr->ulValueLen != DES_KEY_SIZE) {
4961 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
4962 return CKR_ATTRIBUTE_VALUE_INVALID;
4963 }
4964 #if 0
4965 req_len = sizeof(args);
4966 repl_len = DES_KEY_SIZE;
4967
4968 memcpy(args.des_key, attr->pValue, DES_KEY_SIZE);
4969
4970 rc = communicate(PK_CDMF_TRANSFORM_KEY,
4971 &args, req_len, cdmf_key, &repl_len, NULL, 0, NULL, 0);
4972
4973 if (rc != CKR_OK)
4974 return rc;
4975
4976 if (rc == CKR_OK) {
4977 if (repl_len != DES_KEY_SIZE)
4978 return CKR_GENERAL_ERROR;
4979
4980 memcpy(attr->pValue, cdmf_key, DES_KEY_SIZE);
4981 }
4982
4983 return CKR_OK;
4984 #else
4985 return tok_cdmf_transform(attr->pValue, DES_KEY_SIZE);
4986 #endif
4987 case CKA_VALUE_LEN:
4988 if (tokdata->nv_token_data->tweak_vector.netscape_mods == TRUE) {
4989 if (mode == MODE_CREATE || mode == MODE_KEYGEN) {
4990 len = *(CK_ULONG *) attr->pValue;
4991 if (len != DES_KEY_SIZE) {
4992 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
4993 return CKR_ATTRIBUTE_VALUE_INVALID;
4994 }
4995 return CKR_OK;
4996 }
4997 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
4998 return CKR_ATTRIBUTE_READ_ONLY;
4999 }
5000 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT));
5001 return CKR_TEMPLATE_INCONSISTENT;
5002 default:
5003 return secret_key_validate_attribute(tokdata, tmpl, attr, mode);
5004 }
5005 }
5006
5007 #endif
5008
5009 // skipjack_check_required_attributes()
5010 //
skipjack_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)5011 CK_RV skipjack_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
5012 {
5013 CK_ATTRIBUTE *attr = NULL;
5014 CK_BBOOL found;
5015
5016 found = template_attribute_find(tmpl, CKA_VALUE, &attr);
5017 if (!found) {
5018 if (mode == MODE_CREATE) {
5019 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
5020 return CKR_TEMPLATE_INCOMPLETE;
5021 }
5022 }
5023
5024 return secret_key_check_required_attributes(tmpl, mode);
5025 }
5026
5027
5028 // skipjack_set_default_attributes()
5029 //
skipjack_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)5030 CK_RV skipjack_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
5031 {
5032 CK_ATTRIBUTE *value_attr = NULL;
5033 CK_ATTRIBUTE *type_attr = NULL;
5034
5035 if (mode)
5036 value_attr = NULL;
5037
5038 secret_key_set_default_attributes(tmpl, mode);
5039
5040 type_attr =
5041 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
5042 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
5043
5044 if (!type_attr || !value_attr) {
5045 if (type_attr)
5046 free(type_attr);
5047 if (value_attr)
5048 free(value_attr);
5049
5050 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
5051 return CKR_HOST_MEMORY;
5052 }
5053
5054 value_attr->type = CKA_VALUE;
5055 value_attr->ulValueLen = 0;
5056 value_attr->pValue = NULL;
5057
5058 type_attr->type = CKA_KEY_TYPE;
5059 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
5060 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
5061 *(CK_KEY_TYPE *) type_attr->pValue = CKK_SKIPJACK;
5062
5063 template_update_attribute(tmpl, type_attr);
5064 template_update_attribute(tmpl, value_attr);
5065
5066 return CKR_OK;
5067 }
5068
5069
5070 // skipjack_validate_attribute()
5071 //
skipjack_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)5072 CK_RV skipjack_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
5073 CK_ATTRIBUTE *attr, CK_ULONG mode)
5074 {
5075 switch (attr->type) {
5076 case CKA_VALUE:
5077 if (mode != MODE_CREATE) {
5078 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
5079 return CKR_ATTRIBUTE_READ_ONLY;
5080 }
5081 if (attr->ulValueLen != 20) {
5082 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
5083 return CKR_ATTRIBUTE_VALUE_INVALID;
5084 }
5085 return CKR_OK;
5086 default:
5087 return secret_key_validate_attribute(tokdata, tmpl, attr, mode);
5088 }
5089 }
5090
5091
5092 // baton_check_required_attributes()
5093 //
baton_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)5094 CK_RV baton_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
5095 {
5096 CK_ATTRIBUTE *attr = NULL;
5097 CK_BBOOL found;
5098
5099 found = template_attribute_find(tmpl, CKA_VALUE, &attr);
5100 if (!found) {
5101 if (mode == MODE_CREATE) {
5102 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
5103 return CKR_TEMPLATE_INCOMPLETE;
5104 }
5105 }
5106
5107 return secret_key_check_required_attributes(tmpl, mode);
5108 }
5109
5110
5111 // baton_set_default_attributes()
5112 //
baton_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)5113 CK_RV baton_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
5114 {
5115 CK_ATTRIBUTE *value_attr = NULL;
5116 CK_ATTRIBUTE *type_attr = NULL;
5117
5118 if (mode)
5119 value_attr = NULL;
5120
5121 secret_key_set_default_attributes(tmpl, mode);
5122
5123 type_attr =
5124 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
5125 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
5126
5127 if (!type_attr || !value_attr) {
5128 if (type_attr)
5129 free(type_attr);
5130 if (value_attr)
5131 free(value_attr);
5132
5133 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
5134 return CKR_HOST_MEMORY;
5135 }
5136
5137 value_attr->type = CKA_VALUE;
5138 value_attr->ulValueLen = 0;
5139 value_attr->pValue = NULL;
5140
5141 type_attr->type = CKA_KEY_TYPE;
5142 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
5143 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
5144 *(CK_KEY_TYPE *) type_attr->pValue = CKK_BATON;
5145
5146 template_update_attribute(tmpl, type_attr);
5147 template_update_attribute(tmpl, value_attr);
5148
5149 return CKR_OK;
5150 }
5151
5152
5153 // baton_validate_attribute()
5154 //
baton_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)5155 CK_RV baton_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
5156 CK_ATTRIBUTE *attr, CK_ULONG mode)
5157 {
5158 switch (attr->type) {
5159 case CKA_VALUE:
5160 if (mode != MODE_CREATE) {
5161 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
5162 return CKR_ATTRIBUTE_READ_ONLY;
5163 }
5164 if (attr->ulValueLen != 40) {
5165 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
5166 return CKR_ATTRIBUTE_VALUE_INVALID;
5167 }
5168 return CKR_OK;
5169 default:
5170 return secret_key_validate_attribute(tokdata, tmpl, attr, mode);
5171 }
5172 }
5173
5174
5175 // juniper_check_required_attributes()
5176 //
juniper_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)5177 CK_RV juniper_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
5178 {
5179 CK_ATTRIBUTE *attr = NULL;
5180 CK_BBOOL found;
5181
5182 found = template_attribute_find(tmpl, CKA_VALUE, &attr);
5183 if (!found) {
5184 if (mode == MODE_CREATE) {
5185 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
5186 return CKR_TEMPLATE_INCOMPLETE;
5187 }
5188 }
5189
5190 return secret_key_check_required_attributes(tmpl, mode);
5191 }
5192
5193
5194 // juniper_set_default_attributes()
5195 //
juniper_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)5196 CK_RV juniper_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
5197 {
5198 CK_ATTRIBUTE *value_attr = NULL;
5199 CK_ATTRIBUTE *type_attr = NULL;
5200
5201 if (mode)
5202 value_attr = NULL;
5203
5204 secret_key_set_default_attributes(tmpl, mode);
5205
5206 type_attr =
5207 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
5208 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
5209
5210 if (!type_attr || !value_attr) {
5211 if (type_attr)
5212 free(type_attr);
5213 if (value_attr)
5214 free(value_attr);
5215
5216 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
5217 return CKR_HOST_MEMORY;
5218 }
5219
5220 value_attr->type = CKA_VALUE;
5221 value_attr->ulValueLen = 0;
5222 value_attr->pValue = NULL;
5223
5224 type_attr->type = CKA_KEY_TYPE;
5225 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
5226 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
5227 *(CK_KEY_TYPE *) type_attr->pValue = CKK_JUNIPER;
5228
5229 template_update_attribute(tmpl, type_attr);
5230 template_update_attribute(tmpl, value_attr);
5231
5232 return CKR_OK;
5233 }
5234
5235
5236 // juniper_validate_attribute()
5237 //
juniper_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)5238 CK_RV juniper_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
5239 CK_ATTRIBUTE *attr, CK_ULONG mode)
5240 {
5241 switch (attr->type) {
5242 case CKA_VALUE:
5243 if (mode != MODE_CREATE) {
5244 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
5245 return CKR_ATTRIBUTE_READ_ONLY;
5246 }
5247 if (attr->ulValueLen != 40) {
5248 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
5249 return CKR_ATTRIBUTE_VALUE_INVALID;
5250 }
5251 return CKR_OK;
5252 default:
5253 return secret_key_validate_attribute(tokdata, tmpl, attr, mode);
5254 }
5255 }
5256
5257
5258 // aes_set_default_attributes()
5259 //
aes_set_default_attributes(TEMPLATE * tmpl,CK_ULONG mode)5260 CK_RV aes_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
5261 {
5262 CK_ATTRIBUTE *value_attr = NULL;
5263 CK_ATTRIBUTE *type_attr = NULL;
5264
5265 if (mode)
5266 value_attr = NULL;
5267
5268 secret_key_set_default_attributes(tmpl, mode);
5269
5270 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
5271 type_attr =
5272 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
5273
5274 if (!value_attr || !type_attr) {
5275 if (value_attr)
5276 free(value_attr);
5277 if (type_attr)
5278 free(type_attr);
5279
5280 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
5281 return CKR_HOST_MEMORY;
5282 }
5283
5284 value_attr->type = CKA_VALUE;
5285 value_attr->ulValueLen = 0;
5286 value_attr->pValue = NULL;
5287
5288 type_attr->type = CKA_KEY_TYPE;
5289 type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
5290 type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
5291 *(CK_KEY_TYPE *) type_attr->pValue = CKK_AES;
5292
5293 template_update_attribute(tmpl, type_attr);
5294 template_update_attribute(tmpl, value_attr);
5295
5296 return CKR_OK;
5297 }
5298
5299 // aes_check_required_attributes()
5300 //
aes_check_required_attributes(TEMPLATE * tmpl,CK_ULONG mode)5301 CK_RV aes_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
5302 {
5303 CK_ATTRIBUTE *attr = NULL;
5304 CK_BBOOL found;
5305
5306 found = template_attribute_find(tmpl, CKA_VALUE, &attr);
5307 if (!found) {
5308 if (mode == MODE_CREATE) {
5309 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
5310 return CKR_TEMPLATE_INCOMPLETE;
5311 }
5312 }
5313
5314 return secret_key_check_required_attributes(tmpl, mode);
5315 }
5316
5317 //
5318 //
aes_validate_attribute(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_ATTRIBUTE * attr,CK_ULONG mode)5319 CK_RV aes_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *tmpl,
5320 CK_ATTRIBUTE *attr, CK_ULONG mode)
5321 {
5322 CK_ULONG val;
5323
5324 switch (attr->type) {
5325 case CKA_VALUE:
5326 // key length is either 16, 24 or 32 bytes
5327 //
5328 if (mode == MODE_CREATE) {
5329 if (attr->ulValueLen != AES_KEY_SIZE_128 &&
5330 attr->ulValueLen != AES_KEY_SIZE_192 &&
5331 attr->ulValueLen != AES_KEY_SIZE_256) {
5332 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
5333 return CKR_ATTRIBUTE_VALUE_INVALID;
5334 }
5335 return CKR_OK;
5336 }
5337 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
5338 return CKR_ATTRIBUTE_READ_ONLY;
5339 case CKA_VALUE_LEN:
5340 if (mode == MODE_CREATE || mode == MODE_DERIVE ||
5341 mode == MODE_KEYGEN || mode == MODE_UNWRAP) {
5342 val = *(CK_ULONG *) attr->pValue;
5343 if (val != AES_KEY_SIZE_128 &&
5344 val != AES_KEY_SIZE_192 && val != AES_KEY_SIZE_256) {
5345 TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
5346 return CKR_TEMPLATE_INCONSISTENT;
5347 }
5348 return CKR_OK;
5349 }
5350 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT));
5351 return CKR_TEMPLATE_INCONSISTENT;
5352 default:
5353 return secret_key_validate_attribute(tokdata, tmpl, attr, mode);
5354 }
5355 }
5356
5357
5358 //
5359 //
aes_wrap_get_data(TEMPLATE * tmpl,CK_BBOOL length_only,CK_BYTE ** data,CK_ULONG * data_len)5360 CK_RV aes_wrap_get_data(TEMPLATE *tmpl,
5361 CK_BBOOL length_only,
5362 CK_BYTE **data, CK_ULONG *data_len)
5363 {
5364 CK_ATTRIBUTE *attr = NULL;
5365 CK_BYTE *ptr = NULL;
5366 CK_RV rc;
5367
5368
5369 if (!tmpl || !data_len) {
5370 TRACE_ERROR("Invalid function arguments.\n");
5371 return CKR_FUNCTION_FAILED;
5372 }
5373
5374 rc = template_attribute_find(tmpl, CKA_IBM_OPAQUE, &attr);
5375 if (rc == FALSE) {
5376 rc = template_attribute_find(tmpl, CKA_VALUE, &attr);
5377 if (rc == FALSE) {
5378 TRACE_ERROR("%s\n", ock_err(ERR_KEY_NOT_WRAPPABLE));
5379 return CKR_KEY_NOT_WRAPPABLE;
5380 }
5381 }
5382 *data_len = attr->ulValueLen;
5383
5384 if (length_only == FALSE) {
5385 ptr = (CK_BYTE *) malloc(attr->ulValueLen);
5386 if (!ptr) {
5387 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
5388 return CKR_HOST_MEMORY;
5389 }
5390 memcpy(ptr, attr->pValue, attr->ulValueLen);
5391
5392 *data = ptr;
5393 }
5394
5395 return CKR_OK;
5396 }
5397
5398 //
5399 //
aes_unwrap(STDLL_TokData_t * tokdata,TEMPLATE * tmpl,CK_BYTE * data,CK_ULONG data_len,CK_BBOOL fromend,CK_BBOOL isopaque)5400 CK_RV aes_unwrap(STDLL_TokData_t *tokdata,
5401 TEMPLATE *tmpl,
5402 CK_BYTE *data,
5403 CK_ULONG data_len, CK_BBOOL fromend, CK_BBOOL isopaque)
5404 {
5405 CK_ATTRIBUTE *value_attr = NULL;
5406 CK_ATTRIBUTE *val_len_attr = NULL;
5407 CK_BYTE *ptr = NULL;
5408 CK_ULONG key_size;
5409 CK_BBOOL found = FALSE;
5410
5411 UNUSED(tokdata);
5412
5413 /* accept CKA_VALUE_LEN. pkcs11v2.20 doesn't want this attribute when
5414 * unwrapping an AES key, but we need it for several reasons:
5415 * - because some mechanisms may have added padding
5416 * - AES keys come in several sizes
5417 * - secure key size depends on token specifics
5418 * If not a secure key, try datalen and see if matches an aes key size.
5419 * Otherwise, fail because we need to return CKA_VALUE_LEN and we cannot
5420 * unless user tells us what it is for secure key.
5421 *
5422 * Note: since cca token has secure key size of 64, which is a multiple of
5423 * aes blocksize, can assume datalen will always be 64.
5424 * However, a better solution is to create a token specific wrap and
5425 * unwrap and do this kind of stuff in the token.
5426 */
5427 found = template_attribute_find(tmpl, CKA_VALUE_LEN, &val_len_attr);
5428 if (found) {
5429 key_size = *(CK_ULONG *) val_len_attr->pValue;
5430 } else {
5431 if (isopaque) {
5432 TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
5433 return CKR_TEMPLATE_INCOMPLETE;
5434 } else {
5435 key_size = data_len;
5436 }
5437 }
5438
5439 /* key_size should be one of AES's possible sizes */
5440 if (key_size != AES_KEY_SIZE_128 &&
5441 key_size != AES_KEY_SIZE_192 && key_size != AES_KEY_SIZE_256) {
5442 TRACE_ERROR("%s\n", ock_err(ERR_WRAPPED_KEY_LEN_RANGE));
5443 return CKR_WRAPPED_KEY_LEN_RANGE;
5444 }
5445
5446 if (fromend == TRUE) {
5447 if (isopaque)
5448 ptr = data + data_len;
5449 else
5450 ptr = data + data_len - key_size;
5451 } else {
5452 ptr = data;
5453 }
5454
5455 /* reset key_size for secure key, assuming datalen is the token's secure key
5456 * size */
5457 if (isopaque)
5458 key_size = data_len;
5459
5460 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + key_size);
5461
5462 if (!value_attr) {
5463 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
5464 return CKR_HOST_MEMORY;
5465 }
5466
5467 if (isopaque)
5468 value_attr->type = CKA_IBM_OPAQUE;
5469 else
5470 value_attr->type = CKA_VALUE;
5471
5472 value_attr->ulValueLen = key_size;
5473 value_attr->pValue = (CK_BYTE *) value_attr + sizeof(CK_ATTRIBUTE);
5474 memcpy(value_attr->pValue, ptr, key_size);
5475
5476 template_update_attribute(tmpl, value_attr);
5477
5478
5479 /* pkcs11v2-20: CKA_VALUE and CKA_VALUE_LEN given for aes key object. */
5480 if (!found) {
5481 val_len_attr =
5482 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG));
5483 if (!val_len_attr) {
5484 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
5485 return CKR_HOST_MEMORY;
5486 }
5487
5488 val_len_attr->type = CKA_VALUE_LEN;
5489 val_len_attr->ulValueLen = sizeof(CK_ULONG);
5490 val_len_attr->pValue = (CK_BYTE *) val_len_attr + sizeof(CK_ATTRIBUTE);
5491 *((CK_ULONG *) val_len_attr->pValue) = key_size;
5492
5493 template_update_attribute(tmpl, val_len_attr);
5494 }
5495
5496 return CKR_OK;
5497 }
5498