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, &params) == 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