4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
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.
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]
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
33 #include <sys/crypto/ioctl.h>
34 #include <security/cryptoki.h>
35 #include <security/pkcs11t.h>
36 #include "softSession.h"
37 #include "softObject.h"
40 #include "kernelSoftCommon.h"
43 * Do the operation(s) specified by opflag.
46 do_soft_digest(void **s
, CK_MECHANISM_PTR pMechanism
, CK_BYTE_PTR pData
,
47 CK_ULONG ulDataLen
, CK_BYTE_PTR pDigest
, CK_ULONG_PTR pulDigestLen
,
50 soft_session_t
*session_p
;
51 CK_RV rv
= CKR_ARGUMENTS_BAD
;
53 session_p
= *((soft_session_t
**)s
);
54 if (session_p
== NULL
) {
55 if (!(opflag
& OP_INIT
)) {
56 return (CKR_ARGUMENTS_BAD
);
59 session_p
= calloc(1, sizeof (soft_session_t
));
61 * Initialize the lock for the newly created session.
62 * We do only the minimum needed setup for the
63 * soft_digest* routines to succeed.
65 if (pthread_mutex_init(&session_p
->session_mutex
, NULL
) != 0) {
67 return (CKR_CANT_LOCK
);
71 } else if (opflag
& OP_INIT
) {
72 free_soft_ctx(session_p
, OP_DIGEST
);
75 if (opflag
& OP_INIT
) {
76 rv
= soft_digest_init(session_p
, pMechanism
);
81 if (opflag
& OP_SINGLE
) {
82 rv
= soft_digest(session_p
, pData
, ulDataLen
,
83 pDigest
, pulDigestLen
);
85 if (opflag
& OP_UPDATE
) {
86 rv
= soft_digest_update(session_p
, pData
, ulDataLen
);
91 if (opflag
& OP_FINAL
) {
92 rv
= soft_digest_final(session_p
,
93 pDigest
, pulDigestLen
);
101 * opflag specifies whether this is a sign or verify.
104 do_soft_hmac_init(void **s
, CK_MECHANISM_PTR pMechanism
,
105 CK_BYTE_PTR kval
, CK_ULONG klen
, int opflag
)
108 soft_object_t keyobj
;
109 secret_key_obj_t skeyobj
;
110 soft_object_t
*key_p
;
111 soft_session_t
*session_p
;
113 session_p
= *((soft_session_t
**)s
);
114 if (session_p
== NULL
) {
115 session_p
= calloc(1, sizeof (soft_session_t
));
116 /* See comments in do_soft_digest() above */
117 if (pthread_mutex_init(&session_p
->session_mutex
, NULL
) != 0) {
119 return (CKR_CANT_LOCK
);
123 } else if (opflag
& OP_INIT
) {
124 free_soft_ctx(session_p
, opflag
);
127 /* Do the minimum needed setup for the call to succeed */
129 bzero(key_p
, sizeof (soft_object_t
));
130 key_p
->class = CKO_SECRET_KEY
;
131 key_p
->key_type
= CKK_GENERIC_SECRET
;
133 bzero(&skeyobj
, sizeof (secret_key_obj_t
));
134 OBJ_SEC(key_p
) = &skeyobj
;
135 OBJ_SEC_VALUE(key_p
) = kval
;
136 OBJ_SEC_VALUE_LEN(key_p
) = klen
;
138 rv
= soft_hmac_sign_verify_init_common(session_p
, pMechanism
,
139 key_p
, opflag
& OP_SIGN
);
145 * opflag specifies whether this is a sign or verify.
148 do_soft_hmac_update(void **s
, CK_BYTE_PTR pData
, CK_ULONG ulDataLen
, int opflag
)
150 soft_session_t
*session_p
;
152 session_p
= *((soft_session_t
**)s
);
153 if (session_p
== NULL
) {
154 return (CKR_ARGUMENTS_BAD
);
157 return (soft_hmac_sign_verify_update(session_p
,
158 pData
, ulDataLen
, opflag
& OP_SIGN
));
162 * opflag specifies whether this is a final or single.
165 do_soft_hmac_sign(void **s
, CK_BYTE_PTR pData
, CK_ULONG ulDataLen
,
166 CK_BYTE_PTR pSignature
, CK_ULONG_PTR pulSignatureLen
, int opflag
)
169 soft_session_t
*session_p
;
170 CK_BYTE hmac
[SHA512_DIGEST_LENGTH
]; /* use the maximum size */
172 session_p
= *((soft_session_t
**)s
);
173 if (session_p
== NULL
|| !(opflag
& OP_SINGLE
|| opflag
& OP_FINAL
)) {
174 return (CKR_ARGUMENTS_BAD
);
177 rv
= soft_hmac_sign_verify_common(session_p
, pData
, ulDataLen
,
178 (pSignature
!= NULL
? hmac
: NULL
), pulSignatureLen
, B_TRUE
);
180 if ((rv
== CKR_OK
) && (pSignature
!= NULL
)) {
181 (void) memcpy(pSignature
, hmac
, *pulSignatureLen
);
188 * opflag specifies whether this is a final or single.
191 do_soft_hmac_verify(void **s
, CK_BYTE_PTR pData
, CK_ULONG ulDataLen
,
192 CK_BYTE_PTR pSignature
, CK_ULONG ulSignatureLen
, int opflag
)
196 soft_session_t
*session_p
;
197 soft_hmac_ctx_t
*hmac_ctx
;
198 CK_BYTE hmac
[SHA512_DIGEST_LENGTH
]; /* use the maximum size */
200 session_p
= *((soft_session_t
**)s
);
201 if (session_p
== NULL
|| !(opflag
& OP_SINGLE
|| opflag
& OP_FINAL
)) {
202 return (CKR_ARGUMENTS_BAD
);
205 hmac_ctx
= (soft_hmac_ctx_t
*)session_p
->verify
.context
;
206 len
= hmac_ctx
->hmac_len
;
208 rv
= soft_hmac_sign_verify_common(session_p
, pData
,
209 ulDataLen
, hmac
, &len
, B_FALSE
);
212 if (len
!= ulSignatureLen
) {
213 rv
= CKR_SIGNATURE_LEN_RANGE
;
216 if (memcmp(hmac
, pSignature
, len
) != 0) {
217 rv
= CKR_SIGNATURE_INVALID
;
225 * Helper routine to handle the case when the ctx is abandoned.
228 free_soft_ctx(void *s
, int opflag
)
230 soft_session_t
*session_p
;
232 session_p
= (soft_session_t
*)s
;
233 if (session_p
== NULL
)
236 if (opflag
& OP_SIGN
) {
237 if (session_p
->sign
.context
== NULL
)
239 bzero(session_p
->sign
.context
, sizeof (soft_hmac_ctx_t
));
240 free(session_p
->sign
.context
);
241 session_p
->sign
.context
= NULL
;
242 session_p
->sign
.flags
= 0;
243 } else if (opflag
& OP_VERIFY
) {
244 if (session_p
->verify
.context
== NULL
)
246 bzero(session_p
->verify
.context
, sizeof (soft_hmac_ctx_t
));
247 free(session_p
->verify
.context
);
248 session_p
->verify
.context
= NULL
;
249 session_p
->verify
.flags
= 0;
251 if (session_p
->digest
.context
== NULL
)
253 free(session_p
->digest
.context
);
254 session_p
->digest
.context
= NULL
;
255 session_p
->digest
.flags
= 0;