5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 * Copyright 2012 Milan Jurik. All rights reserved.
25 */
26
27 #include <stdlib.h>
28 #include <string.h>
29 #include <security/cryptoki.h>
30 #include <sys/crypto/common.h>
31 #include <arcfour.h>
32 #include <aes_impl.h>
33 #include <blowfish_impl.h>
34 #include <bignum.h>
35 #include <des_impl.h>
36 #include <rsa_impl.h>
37 #include "softGlobal.h"
38 #include "softObject.h"
39 #include "softSession.h"
40 #include "softKeystore.h"
41 #include "softKeystoreUtil.h"
42 #include "softCrypt.h"
43
44
305 case CKA_VERIFY_RECOVER:
306 break;
307 case CKA_DERIVE:
308 break;
309 default:
310 /* Third tier search */
311 rv = soft_lookup_attr(template[i].type);
312 if (rv != CKR_OK)
313 return (rv);
314 break;
315 }
316 break;
317 }
318 }
319 return (rv);
320 }
321
322 static void
323 cleanup_cert_attr(cert_attr_t *attr)
324 {
325 if (attr) {
326 if (attr->value) {
327 (void) memset(attr->value, 0, attr->length);
328 free(attr->value);
329 }
330 attr->value = NULL;
331 attr->length = 0;
332 }
333 }
334
335 static CK_RV
336 copy_cert_attr(cert_attr_t *src_attr, cert_attr_t **dest_attr)
337 {
338 CK_RV rv = CKR_OK;
339
340 if (src_attr == NULL || dest_attr == NULL)
341 return (CKR_HOST_MEMORY);
342
343 if (src_attr->value == NULL)
344 return (CKR_HOST_MEMORY);
345
346 /* free memory if its already allocated */
347 if (*dest_attr != NULL) {
348 if ((*dest_attr)->value != (CK_BYTE *)NULL)
349 free((*dest_attr)->value);
350 } else {
351 *dest_attr = malloc(sizeof (cert_attr_t));
352 if (*dest_attr == NULL)
353 return (CKR_HOST_MEMORY);
354 }
355
356 (*dest_attr)->value = NULL;
357 (*dest_attr)->length = 0;
358
359 if (src_attr->length) {
360 (*dest_attr)->value = malloc(src_attr->length);
361 if ((*dest_attr)->value == NULL) {
362 free(*dest_attr);
363 return (CKR_HOST_MEMORY);
364 }
365
366 (void) memcpy((*dest_attr)->value, src_attr->value,
367 src_attr->length);
368 (*dest_attr)->length = src_attr->length;
369 }
404 X509_ATTR_CERT_OWNER(object_p) = NULL;
405 }
406 free(OBJ_CERT(object_p));
407 }
408 }
409
410 /*
411 * Clean up and release all the storage in the extra attribute list
412 * of an object.
413 */
414 void
415 soft_cleanup_extra_attr(soft_object_t *object_p)
416 {
417
418 CK_ATTRIBUTE_INFO_PTR extra_attr;
419 CK_ATTRIBUTE_INFO_PTR tmp;
420
421 extra_attr = object_p->extra_attrlistp;
422 while (extra_attr) {
423 tmp = extra_attr->next;
424 if (extra_attr->attr.pValue)
425 /*
426 * All extra attributes in the extra attribute
427 * list have pValue points to the value of the
428 * attribute (with simple byte array type).
429 * Free the storage for the value of the attribute.
430 */
431 free(extra_attr->attr.pValue);
432
433 /* Free the storage for the attribute_info struct. */
434 free(extra_attr);
435 extra_attr = tmp;
436 }
437
438 object_p->extra_attrlistp = NULL;
439 }
440
441
442 /*
443 * Create the attribute_info struct to hold the object's attribute,
444 * and add it to the extra attribute list of an object.
445 */
446 CK_RV
447 soft_add_extra_attr(CK_ATTRIBUTE_PTR template, soft_object_t *object_p)
448 {
449
450 CK_ATTRIBUTE_INFO_PTR attrp;
451
655 break;
656 } else {
657 /* Does not match, try next one. */
658 extra_attr = extra_attr->next;
659 }
660 }
661
662 if (extra_attr == NULL) {
663 /*
664 * This attribute is a new one, go ahead adding it to
665 * the extra attribute list.
666 */
667 return (soft_add_extra_attr(template, object_p));
668 }
669
670 /* We found the attribute in the extra attribute list. */
671 if ((template->pValue != NULL) &&
672 (template->ulValueLen > 0)) {
673 if (template->ulValueLen > extra_attr->attr.ulValueLen) {
674 /* The old buffer is too small to hold the new value. */
675 if (extra_attr->attr.pValue != NULL)
676 /* Free storage for the old attribute value. */
677 free(extra_attr->attr.pValue);
678
679 /* Allocate storage for the new attribute value. */
680 extra_attr->attr.pValue = malloc(template->ulValueLen);
681 if (extra_attr->attr.pValue == NULL) {
682 return (CKR_HOST_MEMORY);
683 }
684 }
685
686 /* Replace the attribute with new value. */
687 extra_attr->attr.ulValueLen = template->ulValueLen;
688 (void) memcpy(extra_attr->attr.pValue, template->pValue,
689 template->ulValueLen);
690 } else {
691 extra_attr->attr.pValue = NULL;
692 }
693
694 return (CKR_OK);
695 }
696
697
913 dest->type = src->type;
914 } else {
915 dest->pValue = NULL;
916 dest->ulValueLen = 0;
917 dest->type = src->type;
918 }
919
920 return (CKR_OK);
921
922 }
923
924 CK_RV
925 get_cert_attr_from_template(cert_attr_t **dest, CK_ATTRIBUTE_PTR src)
926 {
927 if (src->pValue != NULL && src->ulValueLen > 0) {
928 /*
929 * If the attribute was already set, clear out the
930 * existing value and release the memory.
931 */
932 if (*dest != NULL) {
933 if ((*dest)->value != NULL) {
934 (void) memset((*dest)->value, 0,
935 (*dest)->length);
936 free((*dest)->value);
937 }
938 } else {
939 *dest = malloc(sizeof (cert_attr_t));
940 if (*dest == NULL) {
941 return (CKR_HOST_MEMORY);
942 }
943 (void) memset(*dest, 0, sizeof (cert_attr_t));
944 }
945 (*dest)->value = malloc(src->ulValueLen);
946 if ((*dest)->value == NULL) {
947 free(*dest);
948 *dest = NULL;
949 return (CKR_HOST_MEMORY);
950 }
951 (void) memcpy((*dest)->value, src->pValue, src->ulValueLen);
952 (*dest)->length = src->ulValueLen;
953 }
954
955 return (CKR_OK);
956 }
957
970 /*
971 * The buffer provided by the application is large
972 * enough to hold the value of the attribute.
973 */
974 (void) memcpy(template->pValue, src->value, src->length);
975 template->ulValueLen = src->length;
976 return (CKR_OK);
977 } else {
978 /*
979 * The buffer provided by the application does
980 * not have enough space to hold the value.
981 */
982 template->ulValueLen = (CK_ULONG)-1;
983 return (CKR_BUFFER_TOO_SMALL);
984 }
985 }
986
987 void
988 string_attr_cleanup(CK_ATTRIBUTE_PTR template)
989 {
990
991 if (template->pValue) {
992 free(template->pValue);
993 template->pValue = NULL;
994 template->ulValueLen = 0;
995 }
996 }
997
998 /*
999 * Release the storage allocated for object attribute with big integer
1000 * value.
1001 */
1002 void
1003 bigint_attr_cleanup(biginteger_t *big)
1004 {
1005
1006 if (big == NULL)
1007 return;
1008
1009 if (big->big_value) {
1010 (void) memset(big->big_value, 0, big->big_value_len);
1011 free(big->big_value);
1012 big->big_value = NULL;
1013 big->big_value_len = 0;
1014 }
1015 }
1016
1017
1018 /*
1019 * Clean up and release all the storage allocated to hold the big integer
1020 * attributes associated with the type (i.e. class) of the object. Also,
1021 * release the storage allocated to the type of the object.
1022 */
1023 void
1024 soft_cleanup_object_bigint_attrs(soft_object_t *object_p)
1025 {
1026
1027 CK_OBJECT_CLASS class = object_p->class;
1028 CK_KEY_TYPE keytype = object_p->key_type;
1029
1030
1031 switch (class) {
1032 case CKO_PUBLIC_KEY:
1033 if (OBJ_PUB(object_p)) {
1034 switch (keytype) {
1134 object_p));
1135 break;
1136
1137 case CKK_EC:
1138 bigint_attr_cleanup(OBJ_PRI_EC_VALUE(
1139 object_p));
1140 break;
1141 }
1142
1143 /* Release Private Key Object struct. */
1144 free(OBJ_PRI(object_p));
1145 OBJ_PRI(object_p) = NULL;
1146 }
1147 break;
1148
1149 case CKO_SECRET_KEY:
1150 if (OBJ_SEC(object_p)) {
1151 /* cleanup key data area */
1152 if (OBJ_SEC_VALUE(object_p) != NULL &&
1153 OBJ_SEC_VALUE_LEN(object_p) > 0) {
1154 (void) memset(OBJ_SEC_VALUE(object_p), 0,
1155 OBJ_SEC_VALUE_LEN(object_p));
1156 free(OBJ_SEC_VALUE(object_p));
1157 }
1158 /* cleanup key schedule data area */
1159 if (OBJ_KEY_SCHED(object_p) != NULL &&
1160 OBJ_KEY_SCHED_LEN(object_p) > 0) {
1161 (void) memset(OBJ_KEY_SCHED(object_p), 0,
1162 OBJ_KEY_SCHED_LEN(object_p));
1163 free(OBJ_KEY_SCHED(object_p));
1164 }
1165
1166 /* Release Secret Key Object struct. */
1167 free(OBJ_SEC(object_p));
1168 OBJ_SEC(object_p) = NULL;
1169 }
1170 break;
1171
1172 case CKO_DOMAIN_PARAMETERS:
1173 if (OBJ_DOM(object_p)) {
1174 switch (keytype) {
1175 case CKK_DSA:
1176 bigint_attr_cleanup(OBJ_DOM_DSA_PRIME(
1177 object_p));
1178 bigint_attr_cleanup(OBJ_DOM_DSA_SUBPRIME(
1179 object_p));
1180 bigint_attr_cleanup(OBJ_DOM_DSA_BASE(
1181 object_p));
1182 break;
1183
6302 default:
6303 break;
6304 }
6305 *new_domain_obj_p = domain;
6306 return (rv);
6307 }
6308
6309 CK_RV
6310 soft_copy_secret_key_attr(secret_key_obj_t *old_secret_key_obj_p,
6311 secret_key_obj_t **new_secret_key_obj_p)
6312 {
6313 secret_key_obj_t *sk;
6314
6315 sk = malloc(sizeof (secret_key_obj_t));
6316 if (sk == NULL) {
6317 return (CKR_HOST_MEMORY);
6318 }
6319 (void) memcpy(sk, old_secret_key_obj_p, sizeof (secret_key_obj_t));
6320
6321 /* copy the secret key value */
6322 sk->sk_value = malloc((sizeof (CK_BYTE) * sk->sk_value_len));
6323 if (sk->sk_value == NULL) {
6324 free(sk);
6325 return (CKR_HOST_MEMORY);
6326 }
6327 (void) memcpy(sk->sk_value, old_secret_key_obj_p->sk_value,
6328 (sizeof (CK_BYTE) * sk->sk_value_len));
6329
6330 /*
6331 * Copy the pre-expanded key schedule.
6332 */
6333 if (old_secret_key_obj_p->key_sched != NULL &&
6334 old_secret_key_obj_p->keysched_len > 0) {
6335 sk->key_sched = malloc(old_secret_key_obj_p->keysched_len);
6336 if (sk->key_sched == NULL) {
6337 free(sk);
6338 return (CKR_HOST_MEMORY);
6339 }
6340 sk->keysched_len = old_secret_key_obj_p->keysched_len;
6341 (void) memcpy(sk->key_sched, old_secret_key_obj_p->key_sched,
6342 sk->keysched_len);
6343 }
6344
6345 *new_secret_key_obj_p = sk;
6346
6347 return (CKR_OK);
6348 }
6349
6350 /*
6351 * If CKA_CLASS not given, guess CKA_CLASS using
6352 * attributes on template .
6353 *
6354 * Some attributes are specific to an object class. If one or more
6355 * of these attributes are in the template, make a list of classes
6356 * that can have these attributes. This would speed up the search later,
|
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 * Copyright 2012 Milan Jurik. All rights reserved.
25 * Copyright (c) 2018, Joyent, Inc.
26 */
27
28 #include <stdlib.h>
29 #include <string.h>
30 #include <security/cryptoki.h>
31 #include <sys/crypto/common.h>
32 #include <arcfour.h>
33 #include <aes_impl.h>
34 #include <blowfish_impl.h>
35 #include <bignum.h>
36 #include <des_impl.h>
37 #include <rsa_impl.h>
38 #include "softGlobal.h"
39 #include "softObject.h"
40 #include "softSession.h"
41 #include "softKeystore.h"
42 #include "softKeystoreUtil.h"
43 #include "softCrypt.h"
44
45
306 case CKA_VERIFY_RECOVER:
307 break;
308 case CKA_DERIVE:
309 break;
310 default:
311 /* Third tier search */
312 rv = soft_lookup_attr(template[i].type);
313 if (rv != CKR_OK)
314 return (rv);
315 break;
316 }
317 break;
318 }
319 }
320 return (rv);
321 }
322
323 static void
324 cleanup_cert_attr(cert_attr_t *attr)
325 {
326 if (attr != NULL) {
327 freezero(attr->value, attr->length);
328 attr->value = NULL;
329 attr->length = 0;
330 }
331 }
332
333 static CK_RV
334 copy_cert_attr(cert_attr_t *src_attr, cert_attr_t **dest_attr)
335 {
336 CK_RV rv = CKR_OK;
337
338 if (src_attr == NULL || dest_attr == NULL)
339 return (CKR_HOST_MEMORY);
340
341 if (src_attr->value == NULL)
342 return (CKR_HOST_MEMORY);
343
344 /* free memory if its already allocated */
345 if (*dest_attr != NULL) {
346 cleanup_cert_attr(*dest_attr);
347 } else {
348 *dest_attr = malloc(sizeof (cert_attr_t));
349 if (*dest_attr == NULL)
350 return (CKR_HOST_MEMORY);
351 }
352
353 (*dest_attr)->value = NULL;
354 (*dest_attr)->length = 0;
355
356 if (src_attr->length) {
357 (*dest_attr)->value = malloc(src_attr->length);
358 if ((*dest_attr)->value == NULL) {
359 free(*dest_attr);
360 return (CKR_HOST_MEMORY);
361 }
362
363 (void) memcpy((*dest_attr)->value, src_attr->value,
364 src_attr->length);
365 (*dest_attr)->length = src_attr->length;
366 }
401 X509_ATTR_CERT_OWNER(object_p) = NULL;
402 }
403 free(OBJ_CERT(object_p));
404 }
405 }
406
407 /*
408 * Clean up and release all the storage in the extra attribute list
409 * of an object.
410 */
411 void
412 soft_cleanup_extra_attr(soft_object_t *object_p)
413 {
414
415 CK_ATTRIBUTE_INFO_PTR extra_attr;
416 CK_ATTRIBUTE_INFO_PTR tmp;
417
418 extra_attr = object_p->extra_attrlistp;
419 while (extra_attr) {
420 tmp = extra_attr->next;
421 if (extra_attr->attr.pValue != NULL) {
422 /*
423 * All extra attributes in the extra attribute
424 * list have pValue points to the value of the
425 * attribute (with simple byte array type).
426 * Free the storage for the value of the attribute.
427 */
428 freezero(extra_attr->attr.pValue,
429 extra_attr->attr.ulValueLen);
430 }
431
432 /* Free the storage for the attribute_info struct. */
433 free(extra_attr);
434 extra_attr = tmp;
435 }
436
437 object_p->extra_attrlistp = NULL;
438 }
439
440
441 /*
442 * Create the attribute_info struct to hold the object's attribute,
443 * and add it to the extra attribute list of an object.
444 */
445 CK_RV
446 soft_add_extra_attr(CK_ATTRIBUTE_PTR template, soft_object_t *object_p)
447 {
448
449 CK_ATTRIBUTE_INFO_PTR attrp;
450
654 break;
655 } else {
656 /* Does not match, try next one. */
657 extra_attr = extra_attr->next;
658 }
659 }
660
661 if (extra_attr == NULL) {
662 /*
663 * This attribute is a new one, go ahead adding it to
664 * the extra attribute list.
665 */
666 return (soft_add_extra_attr(template, object_p));
667 }
668
669 /* We found the attribute in the extra attribute list. */
670 if ((template->pValue != NULL) &&
671 (template->ulValueLen > 0)) {
672 if (template->ulValueLen > extra_attr->attr.ulValueLen) {
673 /* The old buffer is too small to hold the new value. */
674 if (extra_attr->attr.pValue != NULL) {
675 /* Free storage for the old attribute value. */
676 freezero(extra_attr->attr.pValue,
677 extra_attr->attr.ulValueLen);
678 }
679
680 /* Allocate storage for the new attribute value. */
681 extra_attr->attr.pValue = malloc(template->ulValueLen);
682 if (extra_attr->attr.pValue == NULL) {
683 return (CKR_HOST_MEMORY);
684 }
685 }
686
687 /* Replace the attribute with new value. */
688 extra_attr->attr.ulValueLen = template->ulValueLen;
689 (void) memcpy(extra_attr->attr.pValue, template->pValue,
690 template->ulValueLen);
691 } else {
692 extra_attr->attr.pValue = NULL;
693 }
694
695 return (CKR_OK);
696 }
697
698
914 dest->type = src->type;
915 } else {
916 dest->pValue = NULL;
917 dest->ulValueLen = 0;
918 dest->type = src->type;
919 }
920
921 return (CKR_OK);
922
923 }
924
925 CK_RV
926 get_cert_attr_from_template(cert_attr_t **dest, CK_ATTRIBUTE_PTR src)
927 {
928 if (src->pValue != NULL && src->ulValueLen > 0) {
929 /*
930 * If the attribute was already set, clear out the
931 * existing value and release the memory.
932 */
933 if (*dest != NULL) {
934 cleanup_cert_attr(*dest);
935 } else {
936 *dest = malloc(sizeof (cert_attr_t));
937 if (*dest == NULL) {
938 return (CKR_HOST_MEMORY);
939 }
940 (void) memset(*dest, 0, sizeof (cert_attr_t));
941 }
942 (*dest)->value = malloc(src->ulValueLen);
943 if ((*dest)->value == NULL) {
944 free(*dest);
945 *dest = NULL;
946 return (CKR_HOST_MEMORY);
947 }
948 (void) memcpy((*dest)->value, src->pValue, src->ulValueLen);
949 (*dest)->length = src->ulValueLen;
950 }
951
952 return (CKR_OK);
953 }
954
967 /*
968 * The buffer provided by the application is large
969 * enough to hold the value of the attribute.
970 */
971 (void) memcpy(template->pValue, src->value, src->length);
972 template->ulValueLen = src->length;
973 return (CKR_OK);
974 } else {
975 /*
976 * The buffer provided by the application does
977 * not have enough space to hold the value.
978 */
979 template->ulValueLen = (CK_ULONG)-1;
980 return (CKR_BUFFER_TOO_SMALL);
981 }
982 }
983
984 void
985 string_attr_cleanup(CK_ATTRIBUTE_PTR template)
986 {
987 freezero(template->pValue, template->ulValueLen);
988 template->pValue = NULL;
989 template->ulValueLen = 0;
990 }
991
992 /*
993 * Release the storage allocated for object attribute with big integer
994 * value.
995 */
996 void
997 bigint_attr_cleanup(biginteger_t *big)
998 {
999
1000 if (big == NULL)
1001 return;
1002
1003 freezero(big->big_value, big->big_value_len);
1004 big->big_value = NULL;
1005 big->big_value_len = 0;
1006 }
1007
1008
1009 /*
1010 * Clean up and release all the storage allocated to hold the big integer
1011 * attributes associated with the type (i.e. class) of the object. Also,
1012 * release the storage allocated to the type of the object.
1013 */
1014 void
1015 soft_cleanup_object_bigint_attrs(soft_object_t *object_p)
1016 {
1017
1018 CK_OBJECT_CLASS class = object_p->class;
1019 CK_KEY_TYPE keytype = object_p->key_type;
1020
1021
1022 switch (class) {
1023 case CKO_PUBLIC_KEY:
1024 if (OBJ_PUB(object_p)) {
1025 switch (keytype) {
1125 object_p));
1126 break;
1127
1128 case CKK_EC:
1129 bigint_attr_cleanup(OBJ_PRI_EC_VALUE(
1130 object_p));
1131 break;
1132 }
1133
1134 /* Release Private Key Object struct. */
1135 free(OBJ_PRI(object_p));
1136 OBJ_PRI(object_p) = NULL;
1137 }
1138 break;
1139
1140 case CKO_SECRET_KEY:
1141 if (OBJ_SEC(object_p)) {
1142 /* cleanup key data area */
1143 if (OBJ_SEC_VALUE(object_p) != NULL &&
1144 OBJ_SEC_VALUE_LEN(object_p) > 0) {
1145 freezero(OBJ_SEC_VALUE(object_p),
1146 OBJ_SEC_VALUE_LEN(object_p));
1147 }
1148 /* cleanup key schedule data area */
1149 if (OBJ_KEY_SCHED(object_p) != NULL &&
1150 OBJ_KEY_SCHED_LEN(object_p) > 0) {
1151 freezero(OBJ_KEY_SCHED(object_p),
1152 OBJ_KEY_SCHED_LEN(object_p));
1153 }
1154
1155 /* Release Secret Key Object struct. */
1156 free(OBJ_SEC(object_p));
1157 OBJ_SEC(object_p) = NULL;
1158 }
1159 break;
1160
1161 case CKO_DOMAIN_PARAMETERS:
1162 if (OBJ_DOM(object_p)) {
1163 switch (keytype) {
1164 case CKK_DSA:
1165 bigint_attr_cleanup(OBJ_DOM_DSA_PRIME(
1166 object_p));
1167 bigint_attr_cleanup(OBJ_DOM_DSA_SUBPRIME(
1168 object_p));
1169 bigint_attr_cleanup(OBJ_DOM_DSA_BASE(
1170 object_p));
1171 break;
1172
6291 default:
6292 break;
6293 }
6294 *new_domain_obj_p = domain;
6295 return (rv);
6296 }
6297
6298 CK_RV
6299 soft_copy_secret_key_attr(secret_key_obj_t *old_secret_key_obj_p,
6300 secret_key_obj_t **new_secret_key_obj_p)
6301 {
6302 secret_key_obj_t *sk;
6303
6304 sk = malloc(sizeof (secret_key_obj_t));
6305 if (sk == NULL) {
6306 return (CKR_HOST_MEMORY);
6307 }
6308 (void) memcpy(sk, old_secret_key_obj_p, sizeof (secret_key_obj_t));
6309
6310 /* copy the secret key value */
6311 sk->sk_value = malloc(sk->sk_value_len);
6312 if (sk->sk_value == NULL) {
6313 free(sk);
6314 return (CKR_HOST_MEMORY);
6315 }
6316 (void) memcpy(sk->sk_value, old_secret_key_obj_p->sk_value,
6317 (sizeof (CK_BYTE) * sk->sk_value_len));
6318
6319 /*
6320 * Copy the pre-expanded key schedule.
6321 */
6322 if (old_secret_key_obj_p->key_sched != NULL &&
6323 old_secret_key_obj_p->keysched_len > 0) {
6324 sk->key_sched = malloc(old_secret_key_obj_p->keysched_len);
6325 if (sk->key_sched == NULL) {
6326 freezero(sk->sk_value, sk->sk_value_len);
6327 free(sk);
6328 return (CKR_HOST_MEMORY);
6329 }
6330 sk->keysched_len = old_secret_key_obj_p->keysched_len;
6331 (void) memcpy(sk->key_sched, old_secret_key_obj_p->key_sched,
6332 sk->keysched_len);
6333 }
6334
6335 *new_secret_key_obj_p = sk;
6336
6337 return (CKR_OK);
6338 }
6339
6340 /*
6341 * If CKA_CLASS not given, guess CKA_CLASS using
6342 * attributes on template .
6343 *
6344 * Some attributes are specific to an object class. If one or more
6345 * of these attributes are in the template, make a list of classes
6346 * that can have these attributes. This would speed up the search later,
|