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.
25 * Copyright (c) 2018, Joyent, Inc.
32 #include <sys/crypto/ioctl.h>
33 #include <security/cryptoki.h>
34 #include <security/pkcs11t.h>
35 #include "softSession.h"
36 #include "softObject.h"
39 #include "kernelSoftCommon.h"
42 * Do the operation(s) specified by opflag.
45 do_soft_digest(void **s
, CK_MECHANISM_PTR pMechanism
, CK_BYTE_PTR pData
,
46 CK_ULONG ulDataLen
, CK_BYTE_PTR pDigest
, CK_ULONG_PTR pulDigestLen
,
49 soft_session_t
*session_p
;
50 CK_RV rv
= CKR_ARGUMENTS_BAD
;
52 session_p
= *((soft_session_t
**)s
);
53 if (session_p
== NULL
) {
54 if (!(opflag
& OP_INIT
)) {
55 return (CKR_ARGUMENTS_BAD
);
58 session_p
= calloc(1, sizeof (soft_session_t
));
60 * Initialize the lock for the newly created session.
61 * We do only the minimum needed setup for the
62 * soft_digest* routines to succeed.
64 if (pthread_mutex_init(&session_p
->session_mutex
, NULL
) != 0) {
66 return (CKR_CANT_LOCK
);
70 } else if (opflag
& OP_INIT
) {
71 free_soft_ctx(session_p
, OP_DIGEST
);
74 if (opflag
& OP_INIT
) {
75 rv
= soft_digest_init(session_p
, pMechanism
);
80 if (opflag
& OP_SINGLE
) {
81 rv
= soft_digest(session_p
, pData
, ulDataLen
,
82 pDigest
, pulDigestLen
);
84 if (opflag
& OP_UPDATE
) {
85 rv
= soft_digest_update(session_p
, pData
, ulDataLen
);
90 if (opflag
& OP_FINAL
) {
91 rv
= soft_digest_final(session_p
,
92 pDigest
, pulDigestLen
);
100 * opflag specifies whether this is a sign or verify.
103 do_soft_hmac_init(void **s
, CK_MECHANISM_PTR pMechanism
,
104 CK_BYTE_PTR kval
, CK_ULONG klen
, int opflag
)
107 soft_object_t keyobj
;
108 secret_key_obj_t skeyobj
;
109 soft_object_t
*key_p
;
110 soft_session_t
*session_p
;
112 session_p
= *((soft_session_t
**)s
);
113 if (session_p
== NULL
) {
114 session_p
= calloc(1, sizeof (soft_session_t
));
115 /* See comments in do_soft_digest() above */
116 if (pthread_mutex_init(&session_p
->session_mutex
, NULL
) != 0) {
118 return (CKR_CANT_LOCK
);
122 } else if (opflag
& OP_INIT
) {
123 free_soft_ctx(session_p
, opflag
);
126 /* Do the minimum needed setup for the call to succeed */
128 bzero(key_p
, sizeof (soft_object_t
));
129 key_p
->class = CKO_SECRET_KEY
;
130 key_p
->key_type
= CKK_GENERIC_SECRET
;
132 bzero(&skeyobj
, sizeof (secret_key_obj_t
));
133 OBJ_SEC(key_p
) = &skeyobj
;
134 OBJ_SEC_VALUE(key_p
) = kval
;
135 OBJ_SEC_VALUE_LEN(key_p
) = klen
;
137 rv
= soft_hmac_sign_verify_init_common(session_p
, pMechanism
,
138 key_p
, opflag
& OP_SIGN
);
144 * opflag specifies whether this is a sign or verify.
147 do_soft_hmac_update(void **s
, CK_BYTE_PTR pData
, CK_ULONG ulDataLen
, int opflag
)
149 soft_session_t
*session_p
;
151 session_p
= *((soft_session_t
**)s
);
152 if (session_p
== NULL
) {
153 return (CKR_ARGUMENTS_BAD
);
156 return (soft_hmac_sign_verify_update(session_p
,
157 pData
, ulDataLen
, opflag
& OP_SIGN
));
161 * opflag specifies whether this is a final or single.
164 do_soft_hmac_sign(void **s
, CK_BYTE_PTR pData
, CK_ULONG ulDataLen
,
165 CK_BYTE_PTR pSignature
, CK_ULONG_PTR pulSignatureLen
, int opflag
)
168 soft_session_t
*session_p
;
169 CK_BYTE hmac
[SHA512_DIGEST_LENGTH
]; /* use the maximum size */
171 session_p
= *((soft_session_t
**)s
);
172 if (session_p
== NULL
|| !(opflag
& OP_SINGLE
|| opflag
& OP_FINAL
)) {
173 return (CKR_ARGUMENTS_BAD
);
176 rv
= soft_hmac_sign_verify_common(session_p
, pData
, ulDataLen
,
177 (pSignature
!= NULL
? hmac
: NULL
), pulSignatureLen
, B_TRUE
);
179 if ((rv
== CKR_OK
) && (pSignature
!= NULL
)) {
180 (void) memcpy(pSignature
, hmac
, *pulSignatureLen
);
187 * opflag specifies whether this is a final or single.
190 do_soft_hmac_verify(void **s
, CK_BYTE_PTR pData
, CK_ULONG ulDataLen
,
191 CK_BYTE_PTR pSignature
, CK_ULONG ulSignatureLen
, int opflag
)
195 soft_session_t
*session_p
;
196 soft_hmac_ctx_t
*hmac_ctx
;
197 CK_BYTE hmac
[SHA512_DIGEST_LENGTH
]; /* use the maximum size */
199 session_p
= *((soft_session_t
**)s
);
200 if (session_p
== NULL
|| !(opflag
& OP_SINGLE
|| opflag
& OP_FINAL
)) {
201 return (CKR_ARGUMENTS_BAD
);
204 hmac_ctx
= (soft_hmac_ctx_t
*)session_p
->verify
.context
;
205 len
= hmac_ctx
->hmac_len
;
207 rv
= soft_hmac_sign_verify_common(session_p
, pData
,
208 ulDataLen
, hmac
, &len
, B_FALSE
);
211 if (len
!= ulSignatureLen
) {
212 rv
= CKR_SIGNATURE_LEN_RANGE
;
215 if (memcmp(hmac
, pSignature
, len
) != 0) {
216 rv
= CKR_SIGNATURE_INVALID
;
224 * Helper routine to handle the case when the ctx is abandoned.
227 free_soft_ctx(void *s
, int opflag
)
229 soft_session_t
*session_p
;
231 session_p
= (soft_session_t
*)s
;
232 if (session_p
== NULL
)
235 if (opflag
& OP_SIGN
) {
236 freezero(session_p
->sign
.context
,
237 sizeof (soft_hmac_ctx_t
));
238 session_p
->sign
.context
= NULL
;
239 session_p
->sign
.flags
= 0;
240 } else if (opflag
& OP_VERIFY
) {
241 freezero(session_p
->verify
.context
,
242 sizeof (soft_hmac_ctx_t
));
243 session_p
->verify
.context
= NULL
;
244 session_p
->verify
.flags
= 0;
246 free(session_p
->digest
.context
);
247 session_p
->digest
.context
= NULL
;
248 session_p
->digest
.flags
= 0;