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 /***************************************************************************
12                           Change Log
13                           ==========
14        4/25/03    Kapil Sood (kapil@corrent.com)
15                   Added DH key pair generation and DH shared key derivation
16                   functions.
17 
18 
19 
20 ****************************************************************************/
21 
22 #define _GNU_SOURCE
23 #include <pthread.h>
24 #include <stdio.h>
25 #include <time.h>
26 #include <string.h>
27 #include <strings.h>
28 #include <errno.h>
29 #include <syslog.h>
30 
31 #include <stdlib.h>
32 #include <unistd.h>
33 #include <sys/types.h>
34 #include <grp.h>
35 #include <pwd.h>
36 
37 #include "pkcs11types.h"
38 #include "stdll.h"
39 
40 #include "defs.h"
41 #include "host_defs.h"
42 #include "h_extern.h"
43 #include "tok_spec_struct.h"
44 #include "pkcs32.h"
45 #include "trace.h"
46 #include "slotmgr.h"
47 
48 #include "../api/apiproto.h"
49 
50 void SC_SetFunctionList(void);
51 
52 CK_ULONG usage_count = 0;       /* track DLL usage */
53 
Fork_Initializer(void)54 void Fork_Initializer(void)
55 {
56     /* Force logout.  This cleans out the private session and list
57      * and cleans out the private object map
58      */
59     session_mgr_logout_all(NULL);
60 
61     /* Clean out the public object map
62      * First parm is no longer used..
63      */
64     object_mgr_purge_map(NULL, (SESSION *) 0xFFFF, PUBLIC);
65     object_mgr_purge_map(NULL, (SESSION *) 0xFFFF, PRIVATE);
66 
67     /* This should clear the entire session list out */
68     session_mgr_close_all_sessions();
69 
70     /* Clean out the global login state variable
71      * When implemented...  Although logout_all should clear this up.
72      */
73 
74     bt_destroy(&priv_token_obj_btree, call_free);
75     bt_destroy(&publ_token_obj_btree, call_free);
76 
77     /* Need to do something to prevent the shared memory from
78      * having the objects loaded again.... The most likely place
79      * is in the obj_mgr file where the object is added to shared
80      * memory (object_mgr_add_to_shm) a query should be done to
81      * the appropriate object list....
82      */
83 }
84 
85 /* verify that the mech specified is in the
86  * mech list for this token...
87  */
valid_mech(STDLL_TokData_t * tokdata,CK_MECHANISM_PTR m,CK_FLAGS f)88 CK_RV valid_mech(STDLL_TokData_t *tokdata, CK_MECHANISM_PTR m, CK_FLAGS f)
89 {
90     CK_RV rc;
91     CK_MECHANISM_INFO info;
92 
93     if (m && token_specific.t_get_mechanism_info) {
94         memset(&info, 0, sizeof(info));
95         rc = token_specific.t_get_mechanism_info(tokdata, m->mechanism, &info);
96         if (rc != CKR_OK || !(info.flags & (f)))
97             return CKR_MECHANISM_INVALID;
98     }
99 
100     return CKR_OK;
101 }
102 
103 
104 /* In an STDLL this is called once for each card in the system
105  * therefore the initialized only flags certain one time things.
106  */
ST_Initialize(API_Slot_t * sltp,CK_SLOT_ID SlotNumber,SLOT_INFO * sinfp,struct trace_handle_t t)107 CK_RV ST_Initialize(API_Slot_t *sltp, CK_SLOT_ID SlotNumber,
108                     SLOT_INFO *sinfp, struct trace_handle_t t)
109 {
110     CK_RV rc = CKR_OK;
111     char abs_tokdir_name[PATH_MAX];
112 
113     if ((rc = check_user_and_group()) != CKR_OK)
114         return rc;
115 
116     /* assume that the upper API prevents multiple calls of initialize
117      * since that only happens on C_Initialize and that is the
118      * resonsibility of the upper layer..
119      */
120 
121     /* If we're not already initialized, grab the mutex and do the
122      * initialization.  Check to see if another thread did so while we
123      * were waiting...
124      *
125      * One of the things we do during initialization is create the mutex
126      * for PKCS#11 operations; until we do so, we have to use the native
127      * mutex...
128      */
129     if (pthread_mutex_lock(&native_mutex)) {
130         rc = CKR_FUNCTION_FAILED;
131         TRACE_ERROR("Failed to lock mutex.\n");
132     }
133 
134     /* SAB need to call Fork_Initializer here
135      * instead of at the end of the loop...
136      * it may also need to call destroy of the following 3 mutexes..
137      * it may not matter...
138      */
139     Fork_Initializer();
140 
141     /* set trace info */
142     set_trace(t);
143 
144     MY_CreateMutex(&pkcs_mutex);
145     MY_CreateMutex(&obj_list_mutex);
146     MY_CreateMutex(&sess_list_mutex);
147     MY_CreateMutex(&login_mutex);
148 
149     /*
150      * Create separate memory area for each token specific data
151      */
152     sltp->TokData = (STDLL_TokData_t *) calloc(1, sizeof(STDLL_TokData_t));
153     if (!sltp->TokData) {
154         TRACE_ERROR("Allocating host memory failed.\n");
155         goto done;
156     }
157 
158     if (strlen(sinfp->tokname)) {
159         sprintf(abs_tokdir_name, "%s/%s", CONFIG_PATH, sinfp->tokname);
160         TRACE_DEVEL("Token directory: %s\n", abs_tokdir_name);
161         init_data_store((char *) abs_tokdir_name, sltp->TokData->data_store);
162     } else {
163         init_data_store((char *) PK_DIR, sltp->TokData->data_store);
164     }
165 
166     /* Initialize Lock */
167     XProcLock_Init(sltp->TokData);
168 
169     /* Create lockfile */
170     if (CreateXProcLock(sinfp->tokname, sltp->TokData) != CKR_OK) {
171         TRACE_ERROR("Process lock failed.\n");
172         rc = CKR_FUNCTION_FAILED;
173         goto done;
174     }
175 
176     /* Handle global initialization issues first if we have not
177      * been initialized.
178      */
179     if (sltp->TokData->initialized == FALSE) {
180         rc = attach_shm(sltp->TokData, SlotNumber);
181         if (rc != CKR_OK) {
182             TRACE_ERROR("Could not attach to shared memory.\n");
183             goto done;
184         }
185 
186         sltp->TokData->nv_token_data =
187             &(sltp->TokData->global_shm->nv_token_data);
188         SC_SetFunctionList();
189 
190         /* Always call the token_specific_init function.... */
191         rc = token_specific.t_init(sltp->TokData, SlotNumber, sinfp->confname);
192         if (rc != 0) {
193             sltp->FcnList = NULL;
194             if (sltp->TokData)
195                 free(sltp->TokData);
196             sltp->TokData = NULL;
197             TRACE_DEVEL("Token Specific Init failed.\n");
198             goto done;
199         }
200         sltp->TokData->initialized = TRUE;
201     }
202 
203     rc = load_token_data(sltp->TokData, SlotNumber);
204     if (rc != CKR_OK) {
205         sltp->FcnList = NULL;
206         if (sltp->TokData)
207             free(sltp->TokData);
208         sltp->TokData = NULL;
209         TRACE_DEVEL("Failed to load token data.\n");
210         goto done;
211     }
212 
213     rc = XProcLock(sltp->TokData);
214     if (rc != CKR_OK)
215         goto done;
216 
217     /* no need to return error here, we load the token data we can
218      * and syslog the rest
219      */
220     load_public_token_objects(sltp->TokData);
221 
222     sltp->TokData->global_shm->publ_loaded = TRUE;
223 
224     rc = XProcUnLock(sltp->TokData);
225     if (rc != CKR_OK)
226         goto done;
227 
228     init_slotInfo(&(sltp->TokData->slot_info));
229 
230     usage_count++;
231     (sltp->FcnList) = &function_list;
232 
233 done:
234     if (pthread_mutex_unlock(&native_mutex)) {
235         TRACE_ERROR("Failed to unlock mutex.\n");
236         rc = CKR_FUNCTION_FAILED;
237     }
238 
239     return rc;
240 }
241 
242 /* What does this really have to do in this new token...  probably
243  * need to close the adapters that are opened, and clear the other
244  * stuff
245  */
SC_Finalize(STDLL_TokData_t * tokdata,CK_SLOT_ID sid,SLOT_INFO * sinfp)246 CK_RV SC_Finalize(STDLL_TokData_t *tokdata, CK_SLOT_ID sid, SLOT_INFO *sinfp)
247 {
248     CK_RV rc = CKR_OK;
249 
250     UNUSED(sid);
251     UNUSED(sinfp);
252 
253     /* If somebody else has taken care of things, leave... */
254     if (tokdata->initialized == FALSE) {
255         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
256         return CKR_CRYPTOKI_NOT_INITIALIZED;
257     }
258 #ifdef ENABLE_LOCKS
259     MY_LockMutex(&pkcs_mutex);
260 #else
261     __transaction_atomic {      /* start transaction */
262 #endif
263         usage_count--;
264         if (usage_count == 0) {
265             initialized = FALSE;
266         }
267 #ifdef ENABLE_LOCKS
268         MY_UnlockMutex(&pkcs_mutex);
269 #else
270     }                           /* end transaction */
271 #endif
272 
273     session_mgr_close_all_sessions();
274     object_mgr_purge_token_objects(tokdata);
275 
276     /* Finally free the nodes on free list. */
277     bt_destroy(&sess_btree, NULL);
278     bt_destroy(&sess_obj_btree, NULL);
279     bt_destroy(&object_map_btree, NULL);
280     bt_destroy(&priv_token_obj_btree, NULL);
281     bt_destroy(&publ_token_obj_btree, NULL);
282 
283     detach_shm(tokdata);
284     /* close spin lock file */
285     CloseXProcLock(tokdata);
286     if (token_specific.t_final != NULL) {
287         rc = token_specific.t_final(tokdata);
288         if (rc != CKR_OK) {
289             TRACE_ERROR("Token specific final call failed.\n");
290             return rc;
291         }
292     }
293 
294     if (tokdata)
295         free(tokdata);
296 
297     final_data_store();
298     return rc;
299 }
300 
SC_GetTokenInfo(STDLL_TokData_t * tokdata,CK_SLOT_ID sid,CK_TOKEN_INFO_PTR pInfo)301 CK_RV SC_GetTokenInfo(STDLL_TokData_t *tokdata, CK_SLOT_ID sid,
302                       CK_TOKEN_INFO_PTR pInfo)
303 {
304     CK_RV rc = CKR_OK;
305     time_t now;
306 
307     if (tokdata->initialized == FALSE) {
308         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
309         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
310         goto done;
311     }
312     if (!pInfo) {
313         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
314         rc = CKR_ARGUMENTS_BAD;
315         goto done;
316     }
317     if (sid >= NUMBER_SLOTS_MANAGED) {
318         TRACE_ERROR("%s\n", ock_err(ERR_SLOT_ID_INVALID));
319         rc = CKR_SLOT_ID_INVALID;
320         goto done;
321     }
322     copy_token_contents_sensibly(pInfo, tokdata->nv_token_data);
323 
324     /* Set the time */
325     now = time((time_t *) NULL);
326     strftime((char *) pInfo->utcTime, 16, "%Y%m%d%H%M%S", localtime(&now));
327     pInfo->utcTime[14] = '0';
328     pInfo->utcTime[15] = '0';
329 
330 done:
331     TRACE_INFO("C_GetTokenInfo: rc = 0x%08lx\n", rc);
332 
333     return rc;
334 }
335 
SC_WaitForSlotEvent(STDLL_TokData_t * tokdata,CK_FLAGS flags,CK_SLOT_ID_PTR pSlot,CK_VOID_PTR pReserved)336 CK_RV SC_WaitForSlotEvent(STDLL_TokData_t *tokdata, CK_FLAGS flags,
337                           CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved)
338 {
339     UNUSED(flags);
340     UNUSED(pSlot);
341     UNUSED(pReserved);
342 
343     if (tokdata->initialized == FALSE) {
344         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
345         return CKR_CRYPTOKI_NOT_INITIALIZED;
346     }
347 
348     TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED));
349 
350     return CKR_FUNCTION_NOT_SUPPORTED;
351 }
352 
353 /*
354  * Get the mechanism type list for the current token.
355  */
SC_GetMechanismList(STDLL_TokData_t * tokdata,CK_SLOT_ID sid,CK_MECHANISM_TYPE_PTR pMechList,CK_ULONG_PTR count)356 CK_RV SC_GetMechanismList(STDLL_TokData_t *tokdata, CK_SLOT_ID sid,
357                           CK_MECHANISM_TYPE_PTR pMechList, CK_ULONG_PTR count)
358 {
359     CK_RV rc = CKR_OK;
360 
361     if (tokdata->initialized == FALSE) {
362         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
363         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
364         goto out;
365     }
366     if (count == NULL) {
367         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
368         rc = CKR_ARGUMENTS_BAD;
369         goto out;
370     }
371     if (sid >= NUMBER_SLOTS_MANAGED) {
372         TRACE_ERROR("%s\n", ock_err(ERR_SLOT_ID_INVALID));
373         rc = CKR_SLOT_ID_INVALID;
374         goto out;
375     }
376     if (!token_specific.t_get_mechanism_list) {
377         TRACE_ERROR("token specific GetMechanismList doesn't exist.\n");
378         rc = CKR_GENERAL_ERROR;
379         goto out;
380     }
381     rc = token_specific.t_get_mechanism_list(tokdata, pMechList, count);
382     if (rc == CKR_OK) {
383         /* To accomodate certain special cases, we may need to
384          * make adjustments to the token's mechanism list.
385          */
386         mechanism_list_transformations(pMechList, count);
387     }
388 
389 out:
390     TRACE_INFO("C_GetMechanismList:  rc = 0x%08lx, # mechanisms: %lu\n",
391                rc, (count ? *count : 0));
392 
393     return rc;
394 }
395 
396 /*
397  * Get the mechanism info for the current type and token.
398  */
SC_GetMechanismInfo(STDLL_TokData_t * tokdata,CK_SLOT_ID sid,CK_MECHANISM_TYPE type,CK_MECHANISM_INFO_PTR pInfo)399 CK_RV SC_GetMechanismInfo(STDLL_TokData_t *tokdata, CK_SLOT_ID sid,
400                           CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo)
401 {
402     CK_RV rc = CKR_OK;
403 
404     if (tokdata->initialized == FALSE) {
405         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
406         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
407         goto out;
408     }
409     if (pInfo == NULL) {
410         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
411         rc = CKR_ARGUMENTS_BAD;
412         goto out;
413     }
414     if (sid >= NUMBER_SLOTS_MANAGED) {
415         TRACE_ERROR("%s\n", ock_err(ERR_SLOT_ID_INVALID));
416         rc = CKR_SLOT_ID_INVALID;
417         goto out;
418     }
419     if (!token_specific.t_get_mechanism_info) {
420         TRACE_ERROR("token specific GetMechanismInfo doesn't exist.\n");
421         rc = CKR_GENERAL_ERROR;
422         goto out;
423     }
424     rc = token_specific.t_get_mechanism_info(tokdata, type, pInfo);
425 
426 out:
427     TRACE_INFO("C_GetMechanismInfo: rc = 0x%08lx, mech type = 0x%08lx\n",
428                rc, type);
429 
430     return rc;
431 }
432 
433 /*
434  * This routine should only be called if no other processes are
435  * attached to the token.  we need to somehow check that this is the
436  * only process Meta API should prevent this since it knows session
437  * states in the shared memory.
438 */
SC_InitToken(STDLL_TokData_t * tokdata,CK_SLOT_ID sid,CK_CHAR_PTR pPin,CK_ULONG ulPinLen,CK_CHAR_PTR pLabel)439 CK_RV SC_InitToken(STDLL_TokData_t *tokdata, CK_SLOT_ID sid, CK_CHAR_PTR pPin,
440                    CK_ULONG ulPinLen, CK_CHAR_PTR pLabel)
441 {
442     CK_RV rc = CKR_OK;
443     CK_BYTE hash_sha[SHA1_HASH_SIZE];
444 
445     if (tokdata->initialized == FALSE) {
446         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
447         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
448         goto done;
449     }
450     if (!pPin || !pLabel) {
451         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
452         rc = CKR_ARGUMENTS_BAD;
453         goto done;
454     }
455     if (tokdata->nv_token_data->token_info.flags & CKF_SO_PIN_LOCKED) {
456         TRACE_ERROR("%s\n", ock_err(ERR_PIN_LOCKED));
457         rc = CKR_PIN_LOCKED;
458         goto done;
459     }
460 
461     /* Check if token has a specific handler for this, otherwise fall back
462      * to default behaviour.
463      */
464     if (token_specific.t_init_token) {
465         rc = token_specific.t_init_token(tokdata, sid, pPin, ulPinLen, pLabel);
466         if (rc != CKR_OK) {
467             TRACE_ERROR("%s\n", ock_err(ERR_PIN_INCORRECT));
468             rc = CKR_PIN_INCORRECT;
469         }
470         goto done;
471     }
472 
473     rc = compute_sha1(tokdata, pPin, ulPinLen, hash_sha);
474     if (memcmp(tokdata->nv_token_data->so_pin_sha, hash_sha, SHA1_HASH_SIZE) !=
475         0) {
476         TRACE_ERROR("%s\n", ock_err(ERR_PIN_INCORRECT));
477         rc = CKR_PIN_INCORRECT;
478         goto done;
479     }
480 
481     /* Before we reconstruct all the data, we should delete the
482      * token objects from the filesystem.
483      */
484     object_mgr_destroy_token_objects(tokdata);
485     delete_token_data(tokdata);
486 
487     load_token_data(tokdata, sid);
488     init_slotInfo(&(tokdata->slot_info));
489     memcpy(tokdata->nv_token_data->so_pin_sha, hash_sha, SHA1_HASH_SIZE);
490     tokdata->nv_token_data->token_info.flags |= CKF_TOKEN_INITIALIZED;
491     memcpy(tokdata->nv_token_data->token_info.label, pLabel, 32);
492 
493     rc = save_token_data(tokdata, sid);
494     if (rc != CKR_OK) {
495         TRACE_DEVEL("Failed to save token data.\n");
496         goto done;
497     }
498 
499 done:
500     TRACE_INFO("C_InitToken: rc = 0x%08lx\n", rc);
501 
502     return rc;
503 }
504 
505 
SC_InitPIN(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_CHAR_PTR pPin,CK_ULONG ulPinLen)506 CK_RV SC_InitPIN(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
507                  CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
508 {
509     SESSION *sess = NULL;
510     CK_BYTE hash_sha[SHA1_HASH_SIZE];
511     CK_BYTE hash_md5[MD5_HASH_SIZE];
512     CK_RV rc = CKR_OK;
513     CK_FLAGS_32 *flags = NULL;
514 
515     if (tokdata->initialized == FALSE) {
516         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
517         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
518         goto done;
519     }
520     if (!pPin) {
521         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
522         rc = CKR_ARGUMENTS_BAD;
523         goto done;
524     }
525     sess = session_mgr_find(sSession->sessionh);
526     if (!sess) {
527         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
528         rc = CKR_SESSION_HANDLE_INVALID;
529         goto done;
530     }
531     if (pin_locked(&sess->session_info,
532                    tokdata->nv_token_data->token_info.flags) == TRUE) {
533         TRACE_ERROR("%s\n", ock_err(ERR_PIN_LOCKED));
534         rc = CKR_PIN_LOCKED;
535         goto done;
536     }
537     if (sess->session_info.state != CKS_RW_SO_FUNCTIONS) {
538         TRACE_ERROR("%s\n", ock_err(ERR_USER_NOT_LOGGED_IN));
539         rc = CKR_USER_NOT_LOGGED_IN;
540         goto done;
541     }
542 
543     /* Check if token has a specific handler for this, otherwise fall back
544      * to default behaviour.
545      */
546     if (token_specific.t_init_pin) {
547         rc = token_specific.t_init_pin(tokdata, sess, pPin, ulPinLen);
548         if (rc == CKR_OK) {
549             flags = &tokdata->nv_token_data->token_info.flags;
550             *flags &= ~(CKF_USER_PIN_LOCKED |
551                         CKF_USER_PIN_FINAL_TRY | CKF_USER_PIN_COUNT_LOW);
552 
553             rc = save_token_data(tokdata, sess->session_info.slotID);
554             if (rc != CKR_OK)
555                 TRACE_DEVEL("Failed to save token data.\n");
556         }
557         goto done;
558     }
559 
560     if ((ulPinLen < MIN_PIN_LEN) || (ulPinLen > MAX_PIN_LEN)) {
561         TRACE_ERROR("%s\n", ock_err(ERR_PIN_LEN_RANGE));
562         rc = CKR_PIN_LEN_RANGE;
563         goto done;
564     }
565     /* compute the SHA and MD5 hashes of the user pin */
566     rc = compute_sha1(tokdata, pPin, ulPinLen, hash_sha);
567     rc |= compute_md5(tokdata, pPin, ulPinLen, hash_md5);
568     if (rc != CKR_OK) {
569         TRACE_ERROR("Failed to compute sha or md5 for user pin.\n");
570         goto done;
571     }
572 
573     rc = XProcLock(tokdata);
574     if (rc != CKR_OK) {
575         TRACE_ERROR("Failed to get process lock.\n");
576         goto done;
577     }
578 
579     memcpy(tokdata->nv_token_data->user_pin_sha, hash_sha, SHA1_HASH_SIZE);
580     tokdata->nv_token_data->token_info.flags |= CKF_USER_PIN_INITIALIZED;
581     tokdata->nv_token_data->token_info.flags &= ~(CKF_USER_PIN_TO_BE_CHANGED);
582     tokdata->nv_token_data->token_info.flags &= ~(CKF_USER_PIN_LOCKED);
583 
584     rc = XProcUnLock(tokdata);
585     if (rc != CKR_OK) {
586         TRACE_ERROR("Failed to release process lock.\n");
587         goto done;
588     }
589 
590     memcpy(tokdata->user_pin_md5, hash_md5, MD5_HASH_SIZE);
591 
592     rc = save_token_data(tokdata, sess->session_info.slotID);
593     if (rc != CKR_OK) {
594         TRACE_DEVEL("Failed to save token data.\n");
595         goto done;
596     }
597 
598     rc = save_masterkey_user(tokdata);
599     if (rc != CKR_OK)
600         TRACE_DEVEL("Failed to save user's masterkey.\n");
601 
602 done:
603     TRACE_INFO("C_InitPin: rc = 0x%08lx, sess = %lu\n", rc, sSession->sessionh);
604 
605     return rc;
606 }
607 
SC_SetPIN(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_CHAR_PTR pOldPin,CK_ULONG ulOldLen,CK_CHAR_PTR pNewPin,CK_ULONG ulNewLen)608 CK_RV SC_SetPIN(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
609                 CK_CHAR_PTR pOldPin, CK_ULONG ulOldLen, CK_CHAR_PTR pNewPin,
610                 CK_ULONG ulNewLen)
611 {
612     SESSION *sess = NULL;
613     CK_BYTE old_hash_sha[SHA1_HASH_SIZE];
614     CK_BYTE new_hash_sha[SHA1_HASH_SIZE];
615     CK_BYTE hash_md5[MD5_HASH_SIZE];
616     CK_RV rc = CKR_OK;
617 
618     if (tokdata->initialized == FALSE) {
619         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
620         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
621         goto done;
622     }
623     sess = session_mgr_find(sSession->sessionh);
624     if (!sess) {
625         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
626         rc = CKR_SESSION_HANDLE_INVALID;
627         goto done;
628     }
629     if (pin_locked(&sess->session_info,
630                    tokdata->nv_token_data->token_info.flags) == TRUE) {
631         TRACE_ERROR("%s\n", ock_err(ERR_PIN_LOCKED));
632         rc = CKR_PIN_LOCKED;
633         goto done;
634     }
635 
636     /* Check if token has a specific handler for this, otherwise fall back
637      * to default behaviour.
638      */
639     if (token_specific.t_set_pin) {
640         rc = token_specific.t_set_pin(tokdata, sess, pOldPin, ulOldLen,
641                                       pNewPin, ulNewLen);
642         goto done;
643     }
644 
645     if ((ulNewLen < MIN_PIN_LEN) || (ulNewLen > MAX_PIN_LEN)) {
646         TRACE_ERROR("%s\n", ock_err(ERR_PIN_LEN_RANGE));
647         rc = CKR_PIN_LEN_RANGE;
648         goto done;
649     }
650     rc = compute_sha1(tokdata, pOldPin, ulOldLen, old_hash_sha);
651     if (rc != CKR_OK) {
652         TRACE_ERROR("Failed to compute sha for old pin.\n");
653         goto done;
654     }
655     /* From the PKCS#11 2.20 spec: "C_SetPIN modifies the PIN of
656      * the user that is currently logged in, or the CKU_USER PIN
657      * if the session is not logged in."  A non R/W session fails
658      * with CKR_SESSION_READ_ONLY.
659      */
660     if ((sess->session_info.state == CKS_RW_USER_FUNCTIONS) ||
661         (sess->session_info.state == CKS_RW_PUBLIC_SESSION)) {
662         if (memcmp(tokdata->nv_token_data->user_pin_sha, old_hash_sha,
663                    SHA1_HASH_SIZE) != 0) {
664             TRACE_ERROR("%s\n", ock_err(ERR_PIN_INCORRECT));
665             rc = CKR_PIN_INCORRECT;
666             goto done;
667         }
668         rc = compute_sha1(tokdata, pNewPin, ulNewLen, new_hash_sha);
669         rc |= compute_md5(tokdata, pNewPin, ulNewLen, hash_md5);
670         if (rc != CKR_OK) {
671             TRACE_ERROR("Failed to compute hash for new pin.\n");
672             goto done;
673         }
674         /* The old PIN matches, now make sure its different
675          * than the new and is not the default. */
676         if ((memcmp(old_hash_sha, new_hash_sha, SHA1_HASH_SIZE) == 0) ||
677             (memcmp(new_hash_sha, default_user_pin_sha, SHA1_HASH_SIZE)
678              == 0)) {
679             TRACE_ERROR("%s\n", ock_err(ERR_PIN_INVALID));
680             rc = CKR_PIN_INVALID;
681             goto done;
682         }
683 
684         rc = XProcLock(tokdata);
685         if (rc != CKR_OK) {
686             TRACE_DEVEL("Failed to get process lock.\n");
687             goto done;
688         }
689 
690         memcpy(tokdata->nv_token_data->user_pin_sha, new_hash_sha,
691                SHA1_HASH_SIZE);
692         memcpy(tokdata->user_pin_md5, hash_md5, MD5_HASH_SIZE);
693         tokdata->nv_token_data->token_info.flags &=
694             ~(CKF_USER_PIN_TO_BE_CHANGED);
695 
696         rc = XProcUnLock(tokdata);
697         if (rc != CKR_OK) {
698             TRACE_ERROR("Failed to release process lock.\n");
699             goto done;
700         }
701 
702         rc = save_token_data(tokdata, sess->session_info.slotID);
703         if (rc != CKR_OK) {
704             TRACE_DEVEL("Failed to save token data.\n");
705             goto done;
706         }
707         rc = save_masterkey_user(tokdata);
708     } else if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) {
709         if (memcmp(tokdata->nv_token_data->so_pin_sha, old_hash_sha,
710                    SHA1_HASH_SIZE) != 0) {
711             rc = CKR_PIN_INCORRECT;
712             TRACE_ERROR("%s\n", ock_err(ERR_PIN_INCORRECT));
713             goto done;
714         }
715         rc = compute_sha1(tokdata, pNewPin, ulNewLen, new_hash_sha);
716         rc |= compute_md5(tokdata, pNewPin, ulNewLen, hash_md5);
717         if (rc != CKR_OK) {
718             TRACE_ERROR("Failed to compute hash for new pin.\n");
719             goto done;
720         }
721         /* The old PIN matches, now make sure its different
722          * than the new and is not the default.
723          */
724         if ((memcmp(old_hash_sha, new_hash_sha, SHA1_HASH_SIZE) == 0) ||
725             (memcmp(new_hash_sha, default_so_pin_sha, SHA1_HASH_SIZE)
726              == 0)) {
727             TRACE_ERROR("%s\n", ock_err(ERR_PIN_INVALID));
728             rc = CKR_PIN_INVALID;
729             goto done;
730         }
731 
732         rc = XProcLock(tokdata);
733         if (rc != CKR_OK) {
734             TRACE_DEVEL("Failed to get process lock.\n");
735             goto done;
736         }
737 
738         memcpy(tokdata->nv_token_data->so_pin_sha, new_hash_sha,
739                SHA1_HASH_SIZE);
740         memcpy(tokdata->so_pin_md5, hash_md5, MD5_HASH_SIZE);
741         tokdata->nv_token_data->token_info.flags &= ~(CKF_SO_PIN_TO_BE_CHANGED);
742 
743         rc = XProcUnLock(tokdata);
744         if (rc != CKR_OK) {
745             TRACE_ERROR("Failed to release process lock.\n");
746             goto done;
747         }
748 
749         rc = save_token_data(tokdata, sess->session_info.slotID);
750         if (rc != CKR_OK) {
751             TRACE_DEVEL("Failed to save token data.\n");
752             goto done;
753         }
754 
755         rc = save_masterkey_so(tokdata);
756         if (rc != CKR_OK)
757             TRACE_DEVEL("Failed to save SO's masterkey.\n");
758     } else {
759         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_READ_ONLY));
760         rc = CKR_SESSION_READ_ONLY;
761     }
762 
763 done:
764     TRACE_INFO("C_SetPin: rc = 0x%08lx, sess = %lu\n", rc, sSession->sessionh);
765 
766     return rc;
767 }
768 
SC_OpenSession(STDLL_TokData_t * tokdata,CK_SLOT_ID sid,CK_FLAGS flags,CK_SESSION_HANDLE_PTR phSession)769 CK_RV SC_OpenSession(STDLL_TokData_t *tokdata, CK_SLOT_ID sid, CK_FLAGS flags,
770                      CK_SESSION_HANDLE_PTR phSession)
771 {
772     CK_RV rc = CKR_OK;
773     SESSION *sess;
774 
775     if (tokdata->initialized == FALSE) {
776         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
777         return CKR_CRYPTOKI_NOT_INITIALIZED;
778     }
779     if (phSession == NULL) {
780         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
781         return CKR_ARGUMENTS_BAD;
782     }
783     if (sid >= NUMBER_SLOTS_MANAGED) {
784         TRACE_ERROR("%s\n", ock_err(ERR_SLOT_ID_INVALID));
785         return CKR_SLOT_ID_INVALID;
786     }
787     flags |= CKF_SERIAL_SESSION;
788     if ((flags & CKF_RW_SESSION) == 0) {
789         if (session_mgr_so_session_exists()) {
790             TRACE_ERROR("%s\n", ock_err(ERR_SESSION_READ_WRITE_SO_EXISTS));
791             return CKR_SESSION_READ_WRITE_SO_EXISTS;
792         }
793     }
794 
795     rc = session_mgr_new(flags, sid, phSession);
796     if (rc != CKR_OK) {
797         TRACE_DEVEL("session_mgr_new() failed\n");
798         return rc;
799     }
800 
801     sess = session_mgr_find(*phSession);
802     if (!sess) {
803         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
804         return CKR_SESSION_HANDLE_INVALID;
805     }
806 
807     sess->handle = *phSession;
808 
809     TRACE_INFO("C_OpenSession: rc = 0x%08lx sess = %lu\n", rc, sess->handle);
810 
811     return rc;
812 }
813 
SC_CloseSession(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession)814 CK_RV SC_CloseSession(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession)
815 {
816     CK_RV rc = CKR_OK;
817 
818     if (tokdata->initialized == FALSE) {
819         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
820         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
821         goto done;
822     }
823 
824     rc = session_mgr_close_session(tokdata, sSession->sessionh);
825 
826 done:
827     TRACE_INFO("C_CloseSession: rc = 0x%08lx, sess = %lu\n",
828                rc, sSession->sessionh);
829 
830     return rc;
831 }
832 
SC_CloseAllSessions(STDLL_TokData_t * tokdata,CK_SLOT_ID sid)833 CK_RV SC_CloseAllSessions(STDLL_TokData_t *tokdata, CK_SLOT_ID sid)
834 {
835     CK_RV rc = CKR_OK;
836 
837     if (tokdata->initialized == FALSE) {
838         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
839         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
840         goto done;
841     }
842     rc = session_mgr_close_all_sessions();
843     if (rc != CKR_OK)
844         TRACE_DEVEL("session_mgr_close_all_sessions() failed.\n");
845 
846 done:
847     TRACE_INFO("C_CloseAllSessions: rc = 0x%08lx, slot = %lu\n", rc, sid);
848 
849     return rc;
850 }
851 
SC_GetSessionInfo(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_SESSION_INFO_PTR pInfo)852 CK_RV SC_GetSessionInfo(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
853                         CK_SESSION_INFO_PTR pInfo)
854 {
855     SESSION *sess = NULL;
856     CK_RV rc = CKR_OK;
857 
858     if (tokdata->initialized == FALSE) {
859         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
860         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
861         goto done;
862     }
863 
864     if (!pInfo) {
865         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
866         rc = CKR_ARGUMENTS_BAD;
867         goto done;
868     }
869 
870     sess = session_mgr_find(sSession->sessionh);
871     if (!sess) {
872         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
873         rc = CKR_SESSION_HANDLE_INVALID;
874         goto done;
875     }
876 
877     memcpy(pInfo, &sess->session_info, sizeof(CK_SESSION_INFO));
878 
879 done:
880     TRACE_INFO("C_GetSessionInfo: sess = %lu\n", sSession->sessionh);
881 
882     return rc;
883 }
884 
SC_GetOperationState(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pOperationState,CK_ULONG_PTR pulOperationStateLen)885 CK_RV SC_GetOperationState(STDLL_TokData_t *tokdata,
886                            ST_SESSION_HANDLE *sSession,
887                            CK_BYTE_PTR pOperationState,
888                            CK_ULONG_PTR pulOperationStateLen)
889 {
890     SESSION *sess = NULL;
891     CK_BBOOL length_only = FALSE;
892     CK_RV rc = CKR_OK;
893 
894     if (tokdata->initialized == FALSE) {
895         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
896         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
897         goto done;
898     }
899 
900     if (!pulOperationStateLen) {
901         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
902         rc = CKR_ARGUMENTS_BAD;
903         goto done;
904     }
905 
906     if (!pOperationState)
907         length_only = TRUE;
908 
909     sess = session_mgr_find(sSession->sessionh);
910     if (!sess) {
911         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
912         rc = CKR_SESSION_HANDLE_INVALID;
913         goto done;
914     }
915 
916     rc = session_mgr_get_op_state(sess, length_only, pOperationState,
917                                   pulOperationStateLen);
918     if (rc != CKR_OK)
919         TRACE_DEVEL("session_mgr_get_op_state() failed.\n");
920 
921 done:
922     TRACE_INFO("C_GetOperationState: rc = 0x%08lx, sess = %lu\n",
923                rc, sSession->sessionh);
924 
925     return rc;
926 }
927 
928 
SC_SetOperationState(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pOperationState,CK_ULONG ulOperationStateLen,CK_OBJECT_HANDLE hEncryptionKey,CK_OBJECT_HANDLE hAuthenticationKey)929 CK_RV SC_SetOperationState(STDLL_TokData_t *tokdata,
930                            ST_SESSION_HANDLE *sSession,
931                            CK_BYTE_PTR pOperationState,
932                            CK_ULONG ulOperationStateLen,
933                            CK_OBJECT_HANDLE hEncryptionKey,
934                            CK_OBJECT_HANDLE hAuthenticationKey)
935 {
936     SESSION *sess = NULL;
937     CK_RV rc = CKR_OK;
938 
939     if (tokdata->initialized == FALSE) {
940         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
941         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
942         goto done;
943     }
944 
945     if (!pOperationState || (ulOperationStateLen == 0)) {
946         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
947         rc = CKR_ARGUMENTS_BAD;
948         goto done;
949     }
950 
951     sess = session_mgr_find(sSession->sessionh);
952     if (!sess) {
953         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
954         rc = CKR_SESSION_HANDLE_INVALID;
955         goto done;
956     }
957 
958     rc = session_mgr_set_op_state(sess, hEncryptionKey, hAuthenticationKey,
959                                   pOperationState, ulOperationStateLen);
960 
961     if (rc != CKR_OK)
962         TRACE_DEVEL("session_mgr_set_op_state() failed.\n");
963 
964 done:
965     TRACE_INFO("C_SetOperationState: rc = 0x%08lx, sess = %lu\n",
966                rc, sSession->sessionh);
967 
968     return rc;
969 }
970 
971 
SC_Login(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_USER_TYPE userType,CK_CHAR_PTR pPin,CK_ULONG ulPinLen)972 CK_RV SC_Login(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
973                CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
974 {
975     SESSION *sess = NULL;
976     CK_FLAGS_32 *flags = NULL;
977     CK_BYTE hash_sha[SHA1_HASH_SIZE];
978     CK_RV rc = CKR_OK;
979 
980     /* In v2.11, logins should be exclusive, since token
981      * specific flags may need to be set for a bad login. - KEY
982      */
983     rc = MY_LockMutex(&login_mutex);
984     if (rc != CKR_OK) {
985         TRACE_ERROR("Failed to get mutex lock.\n");
986         return CKR_FUNCTION_FAILED;
987     }
988 
989     if (tokdata->initialized == FALSE) {
990         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
991         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
992         goto done;
993     }
994 
995     sess = session_mgr_find(sSession->sessionh);
996     if (!sess) {
997         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
998         rc = CKR_SESSION_HANDLE_INVALID;
999         goto done;
1000     }
1001     flags = &tokdata->nv_token_data->token_info.flags;
1002 
1003     if (!pPin || ulPinLen > MAX_PIN_LEN) {
1004         set_login_flags(userType, flags);
1005         TRACE_ERROR("%s\n", ock_err(ERR_PIN_INCORRECT));
1006         rc = CKR_PIN_INCORRECT;
1007         goto done;
1008     }
1009 
1010     /* PKCS #11 v2.01 requires that all sessions have the same login status:
1011      * --> all sessions are public, all are SO or all are USER
1012      */
1013     if (userType == CKU_USER) {
1014         if (session_mgr_so_session_exists()) {
1015             TRACE_ERROR("%s\n", ock_err(ERR_USER_ANOTHER_ALREADY_LOGGED_IN));
1016             rc = CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
1017         }
1018         if (session_mgr_user_session_exists()) {
1019             TRACE_ERROR("%s\n", ock_err(ERR_USER_ALREADY_LOGGED_IN));
1020             rc = CKR_USER_ALREADY_LOGGED_IN;
1021         }
1022     } else if (userType == CKU_SO) {
1023         if (session_mgr_user_session_exists()) {
1024             TRACE_ERROR("%s\n", ock_err(ERR_USER_ANOTHER_ALREADY_LOGGED_IN));
1025             rc = CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
1026         }
1027         if (session_mgr_so_session_exists()) {
1028             TRACE_ERROR("%s\n", ock_err(ERR_USER_ALREADY_LOGGED_IN));
1029             rc = CKR_USER_ALREADY_LOGGED_IN;
1030         }
1031         if (session_mgr_readonly_session_exists()) {
1032             TRACE_ERROR("%s\n", ock_err(ERR_SESSION_READ_ONLY_EXISTS));
1033             rc = CKR_SESSION_READ_ONLY_EXISTS;
1034         }
1035     } else {
1036         rc = CKR_USER_TYPE_INVALID;
1037         TRACE_ERROR("%s\n", ock_err(ERR_USER_TYPE_INVALID));
1038     }
1039     if (rc != CKR_OK)
1040         goto done;
1041 
1042 
1043     if (userType == CKU_USER) {
1044         if (*flags & CKF_USER_PIN_LOCKED) {
1045             TRACE_ERROR("%s\n", ock_err(ERR_PIN_LOCKED));
1046             rc = CKR_PIN_LOCKED;
1047             goto done;
1048         }
1049 
1050         /* Check if token has a specific handler for this, otherwise
1051          * fall back to default behaviour.
1052          */
1053         if (token_specific.t_login) {
1054             // call the pluggable login function here - KEY
1055             rc = token_specific.t_login(tokdata, sess, userType,
1056                                         pPin, ulPinLen);
1057             if (rc == CKR_OK) {
1058                 *flags &= ~(CKF_USER_PIN_LOCKED |
1059                             CKF_USER_PIN_FINAL_TRY | CKF_USER_PIN_COUNT_LOW);
1060             } else if (rc == CKR_PIN_INCORRECT) {
1061                 set_login_flags(userType, flags);
1062             }
1063             goto done;
1064         }
1065 
1066         if (memcmp(tokdata->nv_token_data->user_pin_sha,
1067                    "00000000000000000000", SHA1_HASH_SIZE) == 0) {
1068             TRACE_ERROR("%s\n", ock_err(ERR_USER_PIN_NOT_INITIALIZED));
1069             rc = CKR_USER_PIN_NOT_INITIALIZED;
1070             goto done;
1071         }
1072 
1073         rc = compute_sha1(tokdata, pPin, ulPinLen, hash_sha);
1074         if (memcmp(tokdata->nv_token_data->user_pin_sha, hash_sha,
1075                    SHA1_HASH_SIZE) != 0) {
1076             set_login_flags(userType, flags);
1077             TRACE_ERROR("%s\n", ock_err(ERR_PIN_INCORRECT));
1078             rc = CKR_PIN_INCORRECT;
1079             goto done;
1080         }
1081         /* Successful login, clear flags */
1082         *flags &= ~(CKF_USER_PIN_LOCKED |
1083                     CKF_USER_PIN_FINAL_TRY | CKF_USER_PIN_COUNT_LOW);
1084 
1085         compute_md5(tokdata, pPin, ulPinLen, tokdata->user_pin_md5);
1086         memset(tokdata->so_pin_md5, 0x0, MD5_HASH_SIZE);
1087 
1088         rc = load_masterkey_user(tokdata);
1089         if (rc != CKR_OK) {
1090             TRACE_DEVEL("Failed to load user's masterkey.\n");
1091             goto done;
1092         }
1093 
1094         rc = XProcLock(tokdata);
1095         if (rc != CKR_OK) {
1096             TRACE_ERROR("Failed to get process lock.\n");
1097             goto done;
1098         }
1099 
1100         /* no need to return error here, we load the token data
1101          * we can and syslog the rest
1102          */
1103         load_private_token_objects(tokdata);
1104 
1105         tokdata->global_shm->priv_loaded = TRUE;
1106 
1107         rc = XProcUnLock(tokdata);
1108         if (rc != CKR_OK) {
1109             TRACE_ERROR("Failed to release process lock.\n");
1110             goto done;
1111         }
1112     } else {
1113         if (*flags & CKF_SO_PIN_LOCKED) {
1114             TRACE_ERROR("%s\n", ock_err(ERR_PIN_LOCKED));
1115             rc = CKR_PIN_LOCKED;
1116             goto done;
1117         }
1118 
1119         /* Check if token has a specific handler for this, otherwise
1120          * fall back to default behaviour.
1121          */
1122         if (token_specific.t_login) {
1123             /* call the pluggable login function here - KEY */
1124             rc = token_specific.t_login(tokdata, sess, userType,
1125                                         pPin, ulPinLen);
1126             if (rc == CKR_OK) {
1127                 *flags &= ~(CKF_SO_PIN_LOCKED |
1128                             CKF_SO_PIN_FINAL_TRY | CKF_SO_PIN_COUNT_LOW);
1129             } else if (rc == CKR_PIN_INCORRECT) {
1130                 set_login_flags(userType, flags);
1131             }
1132             goto done;
1133         }
1134 
1135         rc = compute_sha1(tokdata, pPin, ulPinLen, hash_sha);
1136         if (memcmp(tokdata->nv_token_data->so_pin_sha, hash_sha, SHA1_HASH_SIZE)
1137             != 0) {
1138             set_login_flags(userType, flags);
1139             TRACE_ERROR("%s\n", ock_err(ERR_PIN_INCORRECT));
1140             rc = CKR_PIN_INCORRECT;
1141             goto done;
1142         }
1143         /* Successful login, clear flags */
1144         *flags &= ~(CKF_SO_PIN_LOCKED | CKF_SO_PIN_FINAL_TRY |
1145                     CKF_SO_PIN_COUNT_LOW);
1146 
1147         compute_md5(tokdata, pPin, ulPinLen, tokdata->so_pin_md5);
1148         memset(tokdata->user_pin_md5, 0x0, MD5_HASH_SIZE);
1149 
1150         rc = load_masterkey_so(tokdata);
1151         if (rc != CKR_OK)
1152             TRACE_DEVEL("Failed to load SO's masterkey.\n");
1153     }
1154 
1155 done:
1156     if (rc == CKR_OK) {
1157         rc = session_mgr_login_all(tokdata, userType);
1158         if (rc != CKR_OK)
1159             TRACE_DEVEL("session_mgr_login_all failed.\n");
1160     }
1161 
1162     TRACE_INFO("C_Login: rc = 0x%08lx\n", rc);
1163     if (sess)
1164         save_token_data(tokdata, sess->session_info.slotID);
1165     MY_UnlockMutex(&login_mutex);
1166 
1167     return rc;
1168 }
1169 
1170 
SC_Logout(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession)1171 CK_RV SC_Logout(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession)
1172 {
1173     SESSION *sess = NULL;
1174     CK_RV rc = CKR_OK;
1175 
1176     if (tokdata->initialized == FALSE) {
1177         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
1178         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1179         goto done;
1180     }
1181 
1182     sess = session_mgr_find(sSession->sessionh);
1183     if (!sess) {
1184         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
1185         rc = CKR_SESSION_HANDLE_INVALID;
1186         goto done;
1187     }
1188 
1189     /* all sessions have the same state so we just have to check one */
1190     if (session_mgr_public_session_exists()) {
1191         TRACE_ERROR("%s\n", ock_err(ERR_USER_NOT_LOGGED_IN));
1192         rc = CKR_USER_NOT_LOGGED_IN;
1193         goto done;
1194     }
1195 
1196     rc = session_mgr_logout_all(tokdata);
1197     if (rc != CKR_OK)
1198         TRACE_DEVEL("session_mgr_logout_all failed.\n");
1199 
1200     /* Check if token has a specific handler for this, otherwise fall back
1201      * to default behaviour.
1202      */
1203     if (token_specific.t_logout) {
1204         rc = token_specific.t_logout();
1205         goto done;
1206     }
1207 
1208     memset(tokdata->user_pin_md5, 0x0, MD5_HASH_SIZE);
1209     memset(tokdata->so_pin_md5, 0x0, MD5_HASH_SIZE);
1210 
1211     object_mgr_purge_private_token_objects(tokdata);
1212 
1213 done:
1214     TRACE_INFO("C_Logout: rc = 0x%08lx\n", rc);
1215 
1216     return rc;
1217 }
1218 
1219 
SC_CreateObject(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phObject)1220 CK_RV SC_CreateObject(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
1221                       CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
1222                       CK_OBJECT_HANDLE_PTR phObject)
1223 {
1224     SESSION *sess = NULL;
1225     CK_RV rc = CKR_OK;
1226 
1227     if (tokdata->initialized == FALSE) {
1228         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
1229         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1230         goto done;
1231     }
1232 
1233     sess = session_mgr_find(sSession->sessionh);
1234     if (!sess) {
1235         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
1236         rc = CKR_SESSION_HANDLE_INVALID;
1237         goto done;
1238     }
1239 
1240     if (pin_expired(&sess->session_info,
1241                     tokdata->nv_token_data->token_info.flags)) {
1242         TRACE_ERROR("%s\n", ock_err(ERR_PIN_EXPIRED));
1243         rc = CKR_PIN_EXPIRED;
1244         goto done;
1245     }
1246 
1247     rc = object_mgr_add(tokdata, sess, pTemplate, ulCount, phObject);
1248     if (rc != CKR_OK)
1249         TRACE_DEVEL("object_mgr_add() failed.\n");
1250 
1251 done:
1252     TRACE_INFO("C_CreateObject: rc = 0x%08lx\n", rc);
1253 
1254 #ifdef DEBUG
1255     CK_ULONG i;
1256 
1257     for (i = 0; i < ulCount; i++) {
1258         if (pTemplate[i].type == CKA_CLASS) {
1259             TRACE_DEBUG("Object Type:  0x%02lx\n",
1260                         *((CK_ULONG *) pTemplate[i].pValue));
1261         }
1262     }
1263     if (rc == CKR_OK)
1264         TRACE_DEBUG("Handle:  %lu\n", *phObject);
1265 #endif
1266 
1267     return rc;
1268 }
1269 
1270 
SC_CopyObject(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phNewObject)1271 CK_RV SC_CopyObject(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
1272                     CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate,
1273                     CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phNewObject)
1274 {
1275     SESSION *sess = NULL;
1276     CK_RV rc = CKR_OK;
1277 
1278     if (tokdata->initialized == FALSE) {
1279         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
1280         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1281         goto done;
1282     }
1283 
1284     sess = session_mgr_find(sSession->sessionh);
1285     if (!sess) {
1286         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
1287         rc = CKR_SESSION_HANDLE_INVALID;
1288         goto done;
1289     }
1290 
1291     if (pin_expired(&sess->session_info,
1292                     tokdata->nv_token_data->token_info.flags) == TRUE) {
1293         TRACE_ERROR("%s\n", ock_err(ERR_PIN_EXPIRED));
1294         rc = CKR_PIN_EXPIRED;
1295         goto done;
1296     }
1297 
1298     rc = object_mgr_copy(tokdata, sess, pTemplate, ulCount, hObject,
1299                          phNewObject);
1300     if (rc != CKR_OK)
1301         TRACE_DEVEL("object_mgr_copy() failed\n");
1302 
1303 done:
1304     TRACE_INFO
1305         ("C_CopyObject: rc = 0x%08lx, old handle = %lu, new handle = %lu\n", rc,
1306          hObject, *phNewObject);
1307 
1308     return rc;
1309 }
1310 
1311 
SC_DestroyObject(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_OBJECT_HANDLE hObject)1312 CK_RV SC_DestroyObject(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
1313                        CK_OBJECT_HANDLE hObject)
1314 {
1315     SESSION *sess = NULL;
1316     CK_RV rc = CKR_OK;
1317 
1318     if (tokdata->initialized == FALSE) {
1319         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
1320         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1321         goto done;
1322     }
1323 
1324     sess = session_mgr_find(sSession->sessionh);
1325     if (!sess) {
1326         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
1327         rc = CKR_SESSION_HANDLE_INVALID;
1328         goto done;
1329     }
1330 
1331     if (pin_expired(&sess->session_info,
1332                     tokdata->nv_token_data->token_info.flags) == TRUE) {
1333         TRACE_ERROR("%s\n", ock_err(ERR_PIN_EXPIRED));
1334         rc = CKR_PIN_EXPIRED;
1335         goto done;
1336     }
1337 
1338     rc = object_mgr_destroy_object(tokdata, sess, hObject);
1339     if (rc != CKR_OK)
1340         TRACE_DEVEL("object_mgr_destroy_object() failed\n");
1341 
1342 done:
1343     TRACE_INFO("C_DestroyObject: rc = 0x%08lx, handle = %lu\n", rc, hObject);
1344 
1345     return rc;
1346 }
1347 
1348 
SC_GetObjectSize(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_OBJECT_HANDLE hObject,CK_ULONG_PTR pulSize)1349 CK_RV SC_GetObjectSize(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
1350                        CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize)
1351 {
1352     SESSION *sess = NULL;
1353     CK_RV rc = CKR_OK;
1354 
1355     if (tokdata->initialized == FALSE) {
1356         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
1357         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1358         goto done;
1359     }
1360 
1361     sess = session_mgr_find(sSession->sessionh);
1362     if (!sess) {
1363         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
1364         rc = CKR_SESSION_HANDLE_INVALID;
1365         goto done;
1366     }
1367 
1368     rc = object_mgr_get_object_size(tokdata, hObject, pulSize);
1369     if (rc != CKR_OK)
1370         TRACE_ERROR("object_mgr_get_object_size() failed.\n");
1371 
1372 done:
1373     TRACE_INFO("C_GetObjectSize: rc = 0x%08lx, handle = %lu\n", rc, hObject);
1374 
1375     return rc;
1376 }
1377 
1378 
SC_GetAttributeValue(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)1379 CK_RV SC_GetAttributeValue(STDLL_TokData_t *tokdata,
1380                            ST_SESSION_HANDLE *sSession,
1381                            CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate,
1382                            CK_ULONG ulCount)
1383 {
1384     SESSION *sess = NULL;
1385     CK_RV rc = CKR_OK;
1386 
1387     if (tokdata->initialized == FALSE) {
1388         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
1389         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1390         goto done;
1391     }
1392 
1393     sess = session_mgr_find(sSession->sessionh);
1394     if (!sess) {
1395         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
1396         rc = CKR_SESSION_HANDLE_INVALID;
1397         goto done;
1398     }
1399 
1400     rc = object_mgr_get_attribute_values(tokdata, sess, hObject, pTemplate,
1401                                          ulCount);
1402     if (rc != CKR_OK)
1403         TRACE_DEVEL("object_mgr_get_attribute_value() failed.\n");
1404 
1405 done:
1406     TRACE_INFO("C_GetAttributeValue: rc = 0x%08lx, handle = %lu\n",
1407                rc, hObject);
1408 
1409 #ifdef DEBUG
1410     CK_ATTRIBUTE *attr = NULL;
1411     CK_BYTE *ptr = NULL;
1412     CK_ULONG i;
1413 
1414     attr = pTemplate;
1415     for (i = 0; i < ulCount; i++, attr++) {
1416         ptr = (CK_BYTE *) attr->pValue;
1417 
1418         TRACE_DEBUG("%lu: Attribute type: 0x%08lx, Value Length: %lu\n",
1419                     i, attr->type, attr->ulValueLen);
1420 
1421         if (attr->ulValueLen != (CK_ULONG) (-1) && (ptr != NULL))
1422             TRACE_DEBUG("First 4 bytes: %02x %02x %02x %02x\n",
1423                         ptr[0], ptr[1], ptr[2], ptr[3]);
1424     }
1425 #endif
1426 
1427     return rc;
1428 }
1429 
1430 
SC_SetAttributeValue(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)1431 CK_RV SC_SetAttributeValue(STDLL_TokData_t *tokdata,
1432                            ST_SESSION_HANDLE *sSession,
1433                            CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate,
1434                            CK_ULONG ulCount)
1435 {
1436     SESSION *sess = NULL;
1437     CK_RV rc = CKR_OK;
1438 
1439     if (tokdata->initialized == FALSE) {
1440         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
1441         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1442         goto done;
1443     }
1444 
1445     sess = session_mgr_find(sSession->sessionh);
1446     if (!sess) {
1447         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
1448         rc = CKR_SESSION_HANDLE_INVALID;
1449         goto done;
1450     }
1451 
1452     rc = object_mgr_set_attribute_values(tokdata, sess, hObject, pTemplate,
1453                                          ulCount);
1454     if (rc != CKR_OK)
1455         TRACE_DEVEL("object_mgr_set_attribute_values() failed.\n");
1456 
1457 done:
1458     TRACE_INFO("C_SetAttributeValue: rc = 0x%08lx, handle = %lu\n",
1459                rc, hObject);
1460 #ifdef DEBUG
1461     CK_ATTRIBUTE *attr = NULL;
1462     CK_ULONG i;
1463 
1464     attr = pTemplate;
1465     for (i = 0; i < ulCount; i++, attr++) {
1466         CK_BYTE *ptr = (CK_BYTE *) attr->pValue;
1467 
1468         TRACE_DEBUG("%lu: Attribute type: 0x%08lx, Value Length: %lu\n",
1469                     i, attr->type, attr->ulValueLen);
1470 
1471         if (attr->ulValueLen != (CK_ULONG) (-1) && (ptr != NULL))
1472             TRACE_DEBUG("First 4 bytes: %02x %02x %02x %02x\n",
1473                         ptr[0], ptr[1], ptr[2], ptr[3]);
1474     }
1475 #endif
1476 
1477     return rc;
1478 }
1479 
1480 
SC_FindObjectsInit(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)1481 CK_RV SC_FindObjectsInit(STDLL_TokData_t *tokdata,
1482                          ST_SESSION_HANDLE *sSession,
1483                          CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
1484 {
1485     SESSION *sess = NULL;
1486     CK_RV rc = CKR_OK;
1487 
1488     if (tokdata->initialized == FALSE) {
1489         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
1490         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1491         goto done;
1492     }
1493 
1494     sess = session_mgr_find(sSession->sessionh);
1495     if (!sess) {
1496         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
1497         rc = CKR_SESSION_HANDLE_INVALID;
1498         goto done;
1499     }
1500 
1501     if (pin_expired(&sess->session_info,
1502                     tokdata->nv_token_data->token_info.flags) == TRUE) {
1503         TRACE_ERROR("%s\n", ock_err(ERR_PIN_EXPIRED));
1504         rc = CKR_PIN_EXPIRED;
1505         goto done;
1506     }
1507 
1508     if (sess->find_active == TRUE) {
1509         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_ACTIVE));
1510         rc = CKR_OPERATION_ACTIVE;
1511         goto done;
1512     }
1513 
1514     rc = object_mgr_find_init(tokdata, sess, pTemplate, ulCount);
1515 
1516 done:
1517     TRACE_INFO("C_FindObjectsInit: rc = 0x%08lx\n", rc);
1518 
1519 #ifdef DEBUG
1520     CK_ATTRIBUTE *attr = NULL;
1521     CK_ULONG i;
1522 
1523     attr = pTemplate;
1524     for (i = 0; i < ulCount; i++, attr++) {
1525         CK_BYTE *ptr = (CK_BYTE *) attr->pValue;
1526 
1527         TRACE_DEBUG("%lu: Attribute type: 0x%08lx, Value Length: %lu\n",
1528                     i, attr->type, attr->ulValueLen);
1529 
1530         if (attr->ulValueLen != (CK_ULONG) (-1) && (ptr != NULL))
1531             TRACE_DEBUG("First 4 bytes: %02x %02x %02x %02x\n",
1532                         ptr[0], ptr[1], ptr[2], ptr[3]);
1533     }
1534 #endif
1535 
1536     return rc;
1537 }
1538 
1539 
SC_FindObjects(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_OBJECT_HANDLE_PTR phObject,CK_ULONG ulMaxObjectCount,CK_ULONG_PTR pulObjectCount)1540 CK_RV SC_FindObjects(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
1541                      CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount,
1542                      CK_ULONG_PTR pulObjectCount)
1543 {
1544     SESSION *sess = NULL;
1545     CK_ULONG count = 0;
1546     CK_RV rc = CKR_OK;
1547 
1548     if (tokdata->initialized == FALSE) {
1549         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
1550         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1551         goto done;
1552     }
1553 
1554     if (!phObject || !pulObjectCount) {
1555         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
1556         rc = CKR_ARGUMENTS_BAD;
1557         goto done;
1558     }
1559 
1560     sess = session_mgr_find(sSession->sessionh);
1561     if (!sess) {
1562         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
1563         rc = CKR_SESSION_HANDLE_INVALID;
1564         goto done;
1565     }
1566 
1567     if (sess->find_active == FALSE) {
1568         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
1569         rc = CKR_OPERATION_NOT_INITIALIZED;
1570         goto done;
1571     }
1572 
1573     if (!sess->find_list) {
1574         TRACE_DEVEL("sess->find_list is NULL.\n");
1575         rc = CKR_FUNCTION_FAILED;
1576         goto done;
1577     }
1578     count = MIN(ulMaxObjectCount, (sess->find_count - sess->find_idx));
1579 
1580     memcpy(phObject, sess->find_list + sess->find_idx,
1581            count * sizeof(CK_OBJECT_HANDLE));
1582     *pulObjectCount = count;
1583 
1584     sess->find_idx += count;
1585     rc = CKR_OK;
1586 
1587 done:
1588     TRACE_INFO("C_FindObjects: rc = 0x%08lx, returned %lu objects\n",
1589                rc, count);
1590 
1591     return rc;
1592 }
1593 
1594 
SC_FindObjectsFinal(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession)1595 CK_RV SC_FindObjectsFinal(STDLL_TokData_t *tokdata,
1596                           ST_SESSION_HANDLE *sSession)
1597 {
1598     SESSION *sess = NULL;
1599     CK_RV rc = CKR_OK;
1600 
1601     if (tokdata->initialized == FALSE) {
1602         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
1603         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1604         goto done;
1605     }
1606 
1607     sess = session_mgr_find(sSession->sessionh);
1608     if (!sess) {
1609         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
1610         rc = CKR_SESSION_HANDLE_INVALID;
1611         goto done;
1612     }
1613 
1614     if (sess->find_active == FALSE) {
1615         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
1616         rc = CKR_OPERATION_NOT_INITIALIZED;
1617         goto done;
1618     }
1619 
1620     if (sess->find_list)
1621         free(sess->find_list);
1622 
1623     sess->find_list = NULL;
1624     sess->find_len = 0;
1625     sess->find_idx = 0;
1626     sess->find_active = FALSE;
1627 
1628     rc = CKR_OK;
1629 
1630 done:
1631     TRACE_INFO("C_FindObjectsFinal: rc = 0x%08lx\n", rc);
1632 
1633     return rc;
1634 }
1635 
1636 
SC_EncryptInit(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)1637 CK_RV SC_EncryptInit(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
1638                      CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
1639 {
1640     SESSION *sess = NULL;
1641     CK_RV rc = CKR_OK;
1642 
1643     if (tokdata->initialized == FALSE) {
1644         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
1645         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1646         goto done;
1647     }
1648 
1649     if (!pMechanism) {
1650         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
1651         rc = CKR_ARGUMENTS_BAD;
1652         goto done;
1653     }
1654 
1655     rc = valid_mech(tokdata, pMechanism, CKF_ENCRYPT);
1656     if (rc != CKR_OK)
1657         goto done;
1658 
1659     sess = session_mgr_find(sSession->sessionh);
1660     if (!sess) {
1661         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
1662         rc = CKR_SESSION_HANDLE_INVALID;
1663         goto done;
1664     }
1665 
1666     if (pin_expired(&sess->session_info,
1667                     tokdata->nv_token_data->token_info.flags) == TRUE) {
1668         TRACE_ERROR("%s\n", ock_err(ERR_PIN_EXPIRED));
1669         rc = CKR_PIN_EXPIRED;
1670         goto done;
1671     }
1672 
1673     if (sess->encr_ctx.active == TRUE) {
1674         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_ACTIVE));
1675         rc = CKR_OPERATION_ACTIVE;
1676         goto done;
1677     }
1678 
1679     rc = encr_mgr_init(tokdata, sess, &sess->encr_ctx, OP_ENCRYPT_INIT,
1680                        pMechanism, hKey);
1681 
1682 done:
1683     TRACE_INFO("C_EncryptInit: rc = 0x%08lx, sess = %ld, mech = 0x%lx\n",
1684                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle,
1685                (pMechanism ? pMechanism->mechanism : (CK_ULONG)(-1)));
1686 
1687     return rc;
1688 }
1689 
1690 
SC_Encrypt(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pEncryptedData,CK_ULONG_PTR pulEncryptedDataLen)1691 CK_RV SC_Encrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
1692                  CK_BYTE_PTR pData, CK_ULONG ulDataLen,
1693                  CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen)
1694 {
1695     SESSION *sess = NULL;
1696     CK_BBOOL length_only = FALSE;
1697     CK_RV rc = CKR_OK;
1698 
1699     if (tokdata->initialized == FALSE) {
1700         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
1701         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1702         goto done;
1703     }
1704 
1705     sess = session_mgr_find(sSession->sessionh);
1706     if (!sess) {
1707         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
1708         rc = CKR_SESSION_HANDLE_INVALID;
1709         goto done;
1710     }
1711 
1712     if (!pData || !pulEncryptedDataLen) {
1713         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
1714         rc = CKR_ARGUMENTS_BAD;
1715         goto done;
1716     }
1717 
1718     if (sess->encr_ctx.active == FALSE) {
1719         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
1720         rc = CKR_OPERATION_NOT_INITIALIZED;
1721         goto done;
1722     }
1723 
1724     if (!pEncryptedData)
1725         length_only = TRUE;
1726 
1727     rc = encr_mgr_encrypt(tokdata, sess, length_only, &sess->encr_ctx, pData,
1728                           ulDataLen, pEncryptedData, pulEncryptedDataLen);
1729     if (rc != CKR_OK)
1730         TRACE_DEVEL("encr_mgr_encrypt() failed.\n");
1731 
1732 done:
1733     if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) {
1734         if (sess)
1735             encr_mgr_cleanup(&sess->encr_ctx);
1736     }
1737 
1738     TRACE_INFO("C_Encrypt: rc = 0x%08lx, sess = %ld, amount = %lu\n",
1739                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle, ulDataLen);
1740 
1741     return rc;
1742 }
1743 
1744 
SC_EncryptUpdate(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen,CK_BYTE_PTR pEncryptedPart,CK_ULONG_PTR pulEncryptedPartLen)1745 CK_RV SC_EncryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
1746                        CK_BYTE_PTR pPart, CK_ULONG ulPartLen,
1747                        CK_BYTE_PTR pEncryptedPart,
1748                        CK_ULONG_PTR pulEncryptedPartLen)
1749 {
1750     SESSION *sess = NULL;
1751     CK_BBOOL length_only = FALSE;
1752     CK_RV rc = CKR_OK;
1753 
1754     if (tokdata->initialized == FALSE) {
1755         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
1756         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1757         goto done;
1758     }
1759 
1760     sess = session_mgr_find(sSession->sessionh);
1761     if (!sess) {
1762         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
1763         rc = CKR_SESSION_HANDLE_INVALID;
1764         goto done;
1765     }
1766 
1767     if ((!pPart && ulPartLen != 0) || !pulEncryptedPartLen) {
1768         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
1769         rc = CKR_ARGUMENTS_BAD;
1770         goto done;
1771     }
1772 
1773     if (sess->encr_ctx.active == FALSE) {
1774         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
1775         rc = CKR_OPERATION_NOT_INITIALIZED;
1776         goto done;
1777     }
1778 
1779     if (!pEncryptedPart)
1780         length_only = TRUE;
1781 
1782     rc = encr_mgr_encrypt_update(tokdata, sess, length_only,
1783                                  &sess->encr_ctx, pPart, ulPartLen,
1784                                  pEncryptedPart, pulEncryptedPartLen);
1785     if (rc != CKR_OK)
1786         TRACE_DEVEL("encr_mgr_encrypt_update() failed.\n");
1787 
1788 done:
1789     if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL) {
1790         if (sess)
1791             encr_mgr_cleanup(&sess->encr_ctx);
1792     }
1793 
1794     TRACE_INFO("C_EncryptUpdate: rc = 0x%08lx, sess = %ld, amount = %lu\n",
1795                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle, ulPartLen);
1796 
1797     return rc;
1798 }
1799 
1800 
1801 /* I think RSA goofed when designing the specification for C_EncryptFinal.
1802  * This function is supposed to follow the Cryptoki standard that if
1803  * pLastEncryptedPart == NULL then the user is requesting only the length
1804  * of the output.
1805  *
1806  * But it's quite possible that no output will be returned (say the user
1807  * specifies a total of 64 bytes of input data throughout the multi-part
1808  * encryption).  The same thing can happen during an EncryptUpdate.
1809  *
1810  * ie:
1811  *
1812  *    1) user calls C_EncryptFinal to get the needed length
1813  *       --> we return "0 bytes required"
1814  *    2) user passes in a NULL pointer for pLastEncryptedPart
1815  *       --> we think the user is requesting the length again <--
1816  *
1817  * So the user needs to pass in a non-NULL pointer even though we're not
1818  * going to return anything in it.  It would have been cleaner if RSA would
1819  * have simply included a "give-me-the-length-only flag" as an argument.
1820  */
SC_EncryptFinal(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pLastEncryptedPart,CK_ULONG_PTR pulLastEncryptedPartLen)1821 CK_RV SC_EncryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
1822                       CK_BYTE_PTR pLastEncryptedPart,
1823                       CK_ULONG_PTR pulLastEncryptedPartLen)
1824 {
1825     SESSION *sess = NULL;
1826     CK_BBOOL length_only = FALSE;
1827     CK_RV rc = CKR_OK;
1828 
1829     if (tokdata->initialized == FALSE) {
1830         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
1831         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1832         goto done;
1833     }
1834 
1835     sess = session_mgr_find(sSession->sessionh);
1836     if (!sess) {
1837         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
1838         rc = CKR_SESSION_HANDLE_INVALID;
1839         goto done;
1840     }
1841 
1842     if (!pulLastEncryptedPartLen) {
1843         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
1844         rc = CKR_ARGUMENTS_BAD;
1845         goto done;
1846     }
1847 
1848     if (sess->encr_ctx.active == FALSE) {
1849         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
1850         rc = CKR_OPERATION_NOT_INITIALIZED;
1851         goto done;
1852     }
1853 
1854     if (!pLastEncryptedPart)
1855         length_only = TRUE;
1856 
1857     rc = encr_mgr_encrypt_final(tokdata, sess, length_only, &sess->encr_ctx,
1858                                 pLastEncryptedPart, pulLastEncryptedPartLen);
1859     if (rc != CKR_OK)
1860         TRACE_ERROR("encr_mgr_encrypt_final() failed.\n");
1861 
1862 done:
1863     if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) {
1864         if (sess)
1865             encr_mgr_cleanup(&sess->encr_ctx);
1866     }
1867 
1868     TRACE_INFO("C_EncryptFinal: rc = 0x%08lx, sess = %ld\n",
1869                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle);
1870 
1871     return rc;
1872 }
1873 
1874 
SC_DecryptInit(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)1875 CK_RV SC_DecryptInit(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
1876                      CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
1877 {
1878     SESSION *sess = NULL;
1879     CK_RV rc = CKR_OK;
1880 
1881     if (tokdata->initialized == FALSE) {
1882         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
1883         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1884         goto done;
1885     }
1886 
1887     if (!pMechanism) {
1888         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
1889         rc = CKR_ARGUMENTS_BAD;
1890         goto done;
1891     }
1892 
1893     rc = valid_mech(tokdata, pMechanism, CKF_DECRYPT);
1894     if (rc != CKR_OK)
1895         goto done;
1896 
1897     sess = session_mgr_find(sSession->sessionh);
1898     if (!sess) {
1899         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
1900         rc = CKR_SESSION_HANDLE_INVALID;
1901         goto done;
1902     }
1903 
1904     if (pin_expired(&sess->session_info,
1905                     tokdata->nv_token_data->token_info.flags) == TRUE) {
1906         TRACE_ERROR("%s\n", ock_err(ERR_PIN_EXPIRED));
1907         rc = CKR_PIN_EXPIRED;
1908         goto done;
1909     }
1910 
1911     if (sess->decr_ctx.active == TRUE) {
1912         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_ACTIVE));
1913         rc = CKR_OPERATION_ACTIVE;
1914         goto done;
1915     }
1916 
1917     rc = decr_mgr_init(tokdata, sess, &sess->decr_ctx, OP_DECRYPT_INIT,
1918                        pMechanism, hKey);
1919     if (rc != CKR_OK)
1920         TRACE_DEVEL("decr_mgr_init() failed.\n");
1921 
1922 done:
1923     TRACE_INFO("C_DecryptInit: rc = 0x%08lx, sess = %ld, mech = 0x%lx\n",
1924                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle,
1925                (pMechanism ? pMechanism->mechanism : (CK_ULONG)(-1)));
1926 
1927     return rc;
1928 }
1929 
1930 
SC_Decrypt(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pEncryptedData,CK_ULONG ulEncryptedDataLen,CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen)1931 CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
1932                  CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen,
1933                  CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
1934 {
1935     SESSION *sess = NULL;
1936     CK_BBOOL length_only = FALSE;
1937     CK_RV rc = CKR_OK;
1938 
1939     if (tokdata->initialized == FALSE) {
1940         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
1941         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1942         goto done;
1943     }
1944 
1945     sess = session_mgr_find(sSession->sessionh);
1946     if (!sess) {
1947         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
1948         rc = CKR_SESSION_HANDLE_INVALID;
1949         goto done;
1950     }
1951 
1952     if (!pEncryptedData || !pulDataLen) {
1953         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
1954         rc = CKR_ARGUMENTS_BAD;
1955         goto done;
1956     }
1957 
1958     if (sess->decr_ctx.active == FALSE) {
1959         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
1960         rc = CKR_OPERATION_NOT_INITIALIZED;
1961         goto done;
1962     }
1963 
1964     if (!pData)
1965         length_only = TRUE;
1966 
1967     rc = decr_mgr_decrypt(tokdata, sess, length_only, &sess->decr_ctx,
1968                           pEncryptedData, ulEncryptedDataLen, pData,
1969                           pulDataLen);
1970     if (rc != CKR_OK)
1971         TRACE_DEVEL("decr_mgr_decrypt() failed.\n");
1972 
1973 done:
1974     if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) {
1975         if (sess)
1976             decr_mgr_cleanup(&sess->decr_ctx);
1977     }
1978 
1979     TRACE_INFO("C_Decrypt: rc = 0x%08lx, sess = %ld, amount = %lu\n",
1980                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle,
1981                ulEncryptedDataLen);
1982 
1983     return rc;
1984 }
1985 
1986 
SC_DecryptUpdate(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pEncryptedPart,CK_ULONG ulEncryptedPartLen,CK_BYTE_PTR pPart,CK_ULONG_PTR pulPartLen)1987 CK_RV SC_DecryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
1988                        CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen,
1989                        CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
1990 {
1991     SESSION *sess = NULL;
1992     CK_BBOOL length_only = FALSE;
1993     CK_RV rc = CKR_OK;
1994 
1995     if (tokdata->initialized == FALSE) {
1996         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
1997         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
1998         goto done;
1999     }
2000 
2001     sess = session_mgr_find(sSession->sessionh);
2002     if (!sess) {
2003         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
2004         rc = CKR_SESSION_HANDLE_INVALID;
2005         goto done;
2006     }
2007 
2008     if ((!pEncryptedPart && ulEncryptedPartLen != 0) || !pulPartLen) {
2009         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
2010         rc = CKR_ARGUMENTS_BAD;
2011         goto done;
2012     }
2013 
2014     if (sess->decr_ctx.active == FALSE) {
2015         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
2016         rc = CKR_OPERATION_NOT_INITIALIZED;
2017         goto done;
2018     }
2019 
2020     if (!pPart)
2021         length_only = TRUE;
2022 
2023     rc = decr_mgr_decrypt_update(tokdata, sess, length_only,
2024                                  &sess->decr_ctx, pEncryptedPart,
2025                                  ulEncryptedPartLen, pPart, pulPartLen);
2026     if (rc != CKR_OK)
2027         TRACE_DEVEL("decr_mgr_decrypt_update() failed.\n");
2028 
2029 done:
2030     if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL && sess != NULL) {
2031         if (sess)
2032             decr_mgr_cleanup(&sess->decr_ctx);
2033     }
2034 
2035     TRACE_INFO("C_DecryptUpdate: rc = 0x%08lx, sess = %ld, amount = %lu\n",
2036                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle,
2037                ulEncryptedPartLen);
2038 
2039     return rc;
2040 }
2041 
2042 
SC_DecryptFinal(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pLastPart,CK_ULONG_PTR pulLastPartLen)2043 CK_RV SC_DecryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
2044                       CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen)
2045 {
2046     SESSION *sess = NULL;
2047     CK_BBOOL length_only = FALSE;
2048     CK_RV rc = CKR_OK;
2049 
2050     if (tokdata->initialized == FALSE) {
2051         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
2052         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2053         goto done;
2054     }
2055 
2056     sess = session_mgr_find(sSession->sessionh);
2057     if (!sess) {
2058         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
2059         rc = CKR_SESSION_HANDLE_INVALID;
2060         goto done;
2061     }
2062 
2063     if (!pulLastPartLen) {
2064         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
2065         rc = CKR_ARGUMENTS_BAD;
2066         goto done;
2067     }
2068 
2069     if (sess->decr_ctx.active == FALSE) {
2070         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
2071         rc = CKR_OPERATION_NOT_INITIALIZED;
2072         goto done;
2073     }
2074 
2075     if (!pLastPart)
2076         length_only = TRUE;
2077 
2078     rc = decr_mgr_decrypt_final(tokdata, sess, length_only, &sess->decr_ctx,
2079                                 pLastPart, pulLastPartLen);
2080     if (rc != CKR_OK)
2081         TRACE_DEVEL("decr_mgr_decrypt_final() failed.\n");
2082 
2083 done:
2084     if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) {
2085         if (sess)
2086             decr_mgr_cleanup(&sess->decr_ctx);
2087     }
2088 
2089     TRACE_INFO("C_DecryptFinal: rc = 0x%08lx, sess = %ld, amount = %lu\n",
2090                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle,
2091                (pulLastPartLen ? *pulLastPartLen : 0));
2092 
2093     return rc;
2094 }
2095 
2096 
SC_DigestInit(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_MECHANISM_PTR pMechanism)2097 CK_RV SC_DigestInit(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
2098                     CK_MECHANISM_PTR pMechanism)
2099 {
2100     SESSION *sess = NULL;
2101     CK_RV rc = CKR_OK;
2102 
2103     if (tokdata->initialized == FALSE) {
2104         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
2105         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2106         goto done;
2107     }
2108     if (!pMechanism) {
2109         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
2110         rc = CKR_ARGUMENTS_BAD;
2111         goto done;
2112     }
2113 
2114     rc = valid_mech(tokdata, pMechanism, CKF_DIGEST);
2115     if (rc != CKR_OK)
2116         goto done;
2117 
2118     sess = session_mgr_find(sSession->sessionh);
2119     if (!sess) {
2120         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
2121         rc = CKR_SESSION_HANDLE_INVALID;
2122         goto done;
2123     }
2124 
2125     if (pin_expired(&sess->session_info,
2126                     tokdata->nv_token_data->token_info.flags) == TRUE) {
2127         TRACE_ERROR("%s\n", ock_err(ERR_PIN_EXPIRED));
2128         rc = CKR_PIN_EXPIRED;
2129         goto done;
2130     }
2131 
2132     if (sess->digest_ctx.active == TRUE) {
2133         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_ACTIVE));
2134         rc = CKR_OPERATION_ACTIVE;
2135         goto done;
2136     }
2137 
2138     rc = digest_mgr_init(tokdata, sess, &sess->digest_ctx, pMechanism);
2139     if (rc != CKR_OK)
2140         TRACE_DEVEL("digest_mgr_init() failed.\n");
2141 
2142 done:
2143     TRACE_INFO("C_DigestInit: rc = 0x%08lx, sess = %ld, mech = 0x%lx\n",
2144                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle,
2145                (pMechanism ? pMechanism->mechanism : (CK_ULONG)-1));
2146 
2147     return rc;
2148 }
2149 
2150 
SC_Digest(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pDigest,CK_ULONG_PTR pulDigestLen)2151 CK_RV SC_Digest(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
2152                 CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest,
2153                 CK_ULONG_PTR pulDigestLen)
2154 {
2155     SESSION *sess = NULL;
2156     CK_BBOOL length_only = FALSE;
2157     CK_RV rc = CKR_OK;
2158 
2159     if (tokdata->initialized == FALSE) {
2160         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
2161         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2162         goto done;
2163     }
2164 
2165     sess = session_mgr_find(sSession->sessionh);
2166     if (!sess) {
2167         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
2168         rc = CKR_SESSION_HANDLE_INVALID;
2169         goto done;
2170     }
2171 
2172     if (sess->digest_ctx.active == FALSE) {
2173         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
2174         rc = CKR_OPERATION_NOT_INITIALIZED;
2175         goto done;
2176     }
2177 
2178     if (!pDigest)
2179         length_only = TRUE;
2180 
2181     rc = digest_mgr_digest(tokdata, sess, length_only, &sess->digest_ctx,
2182                            pData, ulDataLen, pDigest, pulDigestLen);
2183     if (rc != CKR_OK)
2184         TRACE_DEVEL("digest_mgr_digest() failed.\n");
2185 
2186 done:
2187     TRACE_INFO("C_Digest: rc = 0x%08lx, sess = %ld, datalen = %lu\n",
2188                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle, ulDataLen);
2189 
2190     return rc;
2191 }
2192 
2193 
SC_DigestUpdate(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)2194 CK_RV SC_DigestUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
2195                       CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
2196 {
2197     SESSION *sess = NULL;
2198     CK_RV rc = CKR_OK;
2199 
2200     if (tokdata->initialized == FALSE) {
2201         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
2202         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2203         goto done;
2204     }
2205 
2206     sess = session_mgr_find(sSession->sessionh);
2207     if (!sess) {
2208         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
2209         rc = CKR_SESSION_HANDLE_INVALID;
2210         goto done;
2211     }
2212 
2213     if (sess->digest_ctx.active == FALSE) {
2214         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
2215         rc = CKR_OPERATION_NOT_INITIALIZED;
2216         goto done;
2217     }
2218 
2219     /* If there is data to hash, do so. */
2220     if (ulPartLen) {
2221         rc = digest_mgr_digest_update(tokdata, sess, &sess->digest_ctx,
2222                                       pPart, ulPartLen);
2223         if (rc != CKR_OK)
2224             TRACE_DEVEL("digest_mgr_digest_update() failed.\n");
2225     }
2226 
2227 done:
2228     TRACE_INFO("C_DigestUpdate: rc = 0x%08lx, sess = %ld, datalen = %lu\n",
2229                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle, ulPartLen);
2230 
2231     return rc;
2232 }
2233 
2234 
SC_DigestKey(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_OBJECT_HANDLE hKey)2235 CK_RV SC_DigestKey(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
2236                    CK_OBJECT_HANDLE hKey)
2237 {
2238     SESSION *sess = NULL;
2239     CK_RV rc = CKR_OK;
2240 
2241     if (tokdata->initialized == FALSE) {
2242         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
2243         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2244         goto done;
2245     }
2246 
2247     sess = session_mgr_find(sSession->sessionh);
2248     if (!sess) {
2249         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
2250         rc = CKR_SESSION_HANDLE_INVALID;
2251         goto done;
2252     }
2253 
2254     if (sess->digest_ctx.active == FALSE) {
2255         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
2256         rc = CKR_OPERATION_NOT_INITIALIZED;
2257         goto done;
2258     }
2259 
2260     rc = digest_mgr_digest_key(tokdata, sess, &sess->digest_ctx, hKey);
2261     if (rc != CKR_OK)
2262         TRACE_DEVEL("digest_mgr_digest_key() failed.\n");
2263 
2264 done:
2265     TRACE_INFO("C_DigestKey: rc = 0x%08lx, sess = %ld, key = %lu\n",
2266                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle, hKey);
2267 
2268     return rc;
2269 }
2270 
2271 
SC_DigestFinal(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pDigest,CK_ULONG_PTR pulDigestLen)2272 CK_RV SC_DigestFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
2273                      CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
2274 {
2275     SESSION *sess = NULL;
2276     CK_BBOOL length_only = FALSE;
2277     CK_RV rc = CKR_OK;
2278 
2279     if (tokdata->initialized == FALSE) {
2280         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
2281         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2282         goto done;
2283     }
2284 
2285     sess = session_mgr_find(sSession->sessionh);
2286     if (!sess) {
2287         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
2288         rc = CKR_SESSION_HANDLE_INVALID;
2289         goto done;
2290     }
2291 
2292     if (sess->digest_ctx.active == FALSE) {
2293         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
2294         rc = CKR_OPERATION_NOT_INITIALIZED;
2295         goto done;
2296     }
2297 
2298     if (!pDigest)
2299         length_only = TRUE;
2300 
2301     rc = digest_mgr_digest_final(tokdata, sess, length_only,
2302                                  &sess->digest_ctx, pDigest, pulDigestLen);
2303     if (rc != CKR_OK)
2304         TRACE_ERROR("digest_mgr_digest_final() failed.\n");
2305 
2306 done:
2307     TRACE_INFO("C_DigestFinal: rc = 0x%08lx, sess = %ld\n",
2308                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle);
2309 
2310     return rc;
2311 }
2312 
2313 
SC_SignInit(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)2314 CK_RV SC_SignInit(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
2315                   CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
2316 {
2317     SESSION *sess = NULL;
2318     CK_RV rc = CKR_OK;
2319 
2320     if (tokdata->initialized == FALSE) {
2321         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
2322         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2323         goto done;
2324     }
2325 
2326     if (!pMechanism) {
2327         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
2328         rc = CKR_ARGUMENTS_BAD;
2329         goto done;
2330     }
2331 
2332     sess = session_mgr_find(sSession->sessionh);
2333     if (!sess) {
2334         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
2335         rc = CKR_SESSION_HANDLE_INVALID;
2336         goto done;
2337     }
2338 
2339     rc = valid_mech(tokdata, pMechanism, CKF_SIGN);
2340     if (rc != CKR_OK)
2341         goto done;
2342 
2343     if (pin_expired(&sess->session_info,
2344                     tokdata->nv_token_data->token_info.flags) == TRUE) {
2345         TRACE_ERROR("%s\n", ock_err(ERR_PIN_EXPIRED));
2346         rc = CKR_PIN_EXPIRED;
2347         goto done;
2348     }
2349 
2350     if (sess->sign_ctx.active == TRUE) {
2351         rc = CKR_OPERATION_ACTIVE;
2352         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_ACTIVE));
2353         goto done;
2354     }
2355 
2356     rc = sign_mgr_init(tokdata, sess, &sess->sign_ctx, pMechanism, FALSE, hKey);
2357     if (rc != CKR_OK)
2358         TRACE_DEVEL("sign_mgr_init() failed.\n");
2359 
2360 done:
2361     TRACE_INFO("C_SignInit: rc = 0x%08lx, sess = %ld, mech = 0x%lx\n",
2362                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle,
2363                (pMechanism ? pMechanism->mechanism : (CK_ULONG)-1));
2364 
2365     return rc;
2366 }
2367 
2368 
SC_Sign(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen)2369 CK_RV SC_Sign(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
2370               CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
2371               CK_ULONG_PTR pulSignatureLen)
2372 {
2373     SESSION *sess = NULL;
2374     CK_BBOOL length_only = FALSE;
2375     CK_RV rc = CKR_OK;
2376 
2377     if (tokdata->initialized == FALSE) {
2378         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
2379         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2380         goto done;
2381     }
2382 
2383     if (!pData || !pulSignatureLen) {
2384         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
2385         rc = CKR_ARGUMENTS_BAD;
2386         goto done;
2387     }
2388 
2389     sess = session_mgr_find(sSession->sessionh);
2390     if (!sess) {
2391         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
2392         rc = CKR_SESSION_HANDLE_INVALID;
2393         goto done;
2394     }
2395 
2396     if (sess->sign_ctx.active == FALSE) {
2397         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
2398         rc = CKR_OPERATION_NOT_INITIALIZED;
2399         goto done;
2400     }
2401 
2402     if (!pSignature)
2403         length_only = TRUE;
2404 
2405     rc = sign_mgr_sign(tokdata, sess, length_only, &sess->sign_ctx, pData,
2406                        ulDataLen, pSignature, pulSignatureLen);
2407     if (rc != CKR_OK)
2408         TRACE_DEVEL("sign_mgr_sign() failed.\n");
2409 
2410 done:
2411     if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE))
2412         sign_mgr_cleanup(&sess->sign_ctx);
2413 
2414     TRACE_INFO("C_Sign: rc = 0x%08lx, sess = %ld, datalen = %lu\n",
2415                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle, ulDataLen);
2416 
2417     return rc;
2418 }
2419 
2420 
SC_SignUpdate(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)2421 CK_RV SC_SignUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
2422                     CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
2423 {
2424     SESSION *sess = NULL;
2425     CK_RV rc = CKR_OK;
2426 
2427     if (tokdata->initialized == FALSE) {
2428         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
2429         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2430         goto done;
2431     }
2432 
2433     if (!pPart && ulPartLen != 0) {
2434         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
2435         rc = CKR_ARGUMENTS_BAD;
2436         goto done;
2437     }
2438 
2439     sess = session_mgr_find(sSession->sessionh);
2440     if (!sess) {
2441         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
2442         rc = CKR_SESSION_HANDLE_INVALID;
2443         goto done;
2444     }
2445 
2446     if (sess->sign_ctx.active == FALSE) {
2447         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
2448         rc = CKR_OPERATION_NOT_INITIALIZED;
2449         goto done;
2450     }
2451 
2452     rc = sign_mgr_sign_update(tokdata, sess, &sess->sign_ctx, pPart, ulPartLen);
2453     if (rc != CKR_OK)
2454         TRACE_DEVEL("sign_mgr_sign_update() failed.\n");
2455 
2456 done:
2457     if (rc != CKR_OK)
2458         sign_mgr_cleanup(&sess->sign_ctx);
2459 
2460     TRACE_INFO("C_SignUpdate: rc = 0x%08lx, sess = %ld, datalen = %lu\n",
2461                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle, ulPartLen);
2462 
2463     return rc;
2464 }
2465 
2466 
SC_SignFinal(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen)2467 CK_RV SC_SignFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
2468                    CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
2469 {
2470     SESSION *sess = NULL;
2471     CK_BBOOL length_only = FALSE;
2472     CK_RV rc = CKR_OK;
2473 
2474     if (tokdata->initialized == FALSE) {
2475         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
2476         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2477         goto done;
2478     }
2479 
2480     if (!pulSignatureLen) {
2481         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
2482         rc = CKR_ARGUMENTS_BAD;
2483         goto done;
2484     }
2485 
2486     sess = session_mgr_find(sSession->sessionh);
2487     if (!sess) {
2488         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
2489         rc = CKR_SESSION_HANDLE_INVALID;
2490         goto done;
2491     }
2492 
2493     if (sess->sign_ctx.active == FALSE) {
2494         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
2495         rc = CKR_OPERATION_NOT_INITIALIZED;
2496         goto done;
2497     }
2498 
2499     if (!pSignature)
2500         length_only = TRUE;
2501 
2502     rc = sign_mgr_sign_final(tokdata, sess, length_only, &sess->sign_ctx,
2503                              pSignature, pulSignatureLen);
2504     if (rc != CKR_OK)
2505         TRACE_ERROR("sign_mgr_sign_final() failed.\n");
2506 
2507 done:
2508     if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE))
2509         sign_mgr_cleanup(&sess->sign_ctx);
2510 
2511     TRACE_INFO("C_SignFinal: rc = 0x%08lx, sess = %ld\n",
2512                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle);
2513 
2514     return rc;
2515 }
2516 
2517 
SC_SignRecoverInit(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)2518 CK_RV SC_SignRecoverInit(STDLL_TokData_t *tokdata,
2519                          ST_SESSION_HANDLE *sSession,
2520                          CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
2521 {
2522     SESSION *sess = NULL;
2523     CK_RV rc = CKR_OK;
2524 
2525     if (tokdata->initialized == FALSE) {
2526         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
2527         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2528         goto done;
2529     }
2530     if (!pMechanism) {
2531         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
2532         rc = CKR_ARGUMENTS_BAD;
2533         goto done;
2534     }
2535 
2536     rc = valid_mech(tokdata, pMechanism, CKF_SIGN_RECOVER);
2537     if (rc != CKR_OK)
2538         goto done;
2539 
2540     sess = session_mgr_find(sSession->sessionh);
2541     if (!sess) {
2542         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
2543         rc = CKR_SESSION_HANDLE_INVALID;
2544         goto done;
2545     }
2546 
2547     if (pin_expired(&sess->session_info,
2548                     tokdata->nv_token_data->token_info.flags) == TRUE) {
2549         TRACE_ERROR("%s\n", ock_err(ERR_PIN_EXPIRED));
2550         rc = CKR_PIN_EXPIRED;
2551         goto done;
2552     }
2553 
2554     if (sess->sign_ctx.active == TRUE) {
2555         rc = CKR_OPERATION_ACTIVE;
2556         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_ACTIVE));
2557         goto done;
2558     }
2559 
2560     rc = sign_mgr_init(tokdata, sess, &sess->sign_ctx, pMechanism, TRUE, hKey);
2561     if (rc != CKR_OK)
2562         TRACE_DEVEL("sign_mgr_init() failed.\n");
2563 
2564 done:
2565     TRACE_INFO("C_SignRecoverInit: rc = 0x%08lx, sess = %ld, mech = 0x%lx\n",
2566                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle,
2567                (pMechanism ? pMechanism->mechanism : (CK_ULONG)-1));
2568 
2569     return rc;
2570 }
2571 
2572 
SC_SignRecover(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen)2573 CK_RV SC_SignRecover(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
2574                      CK_BYTE_PTR pData, CK_ULONG ulDataLen,
2575                      CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
2576 {
2577     SESSION *sess = NULL;
2578     CK_BBOOL length_only = FALSE;
2579     CK_RV rc = CKR_OK;
2580 
2581     if (tokdata->initialized == FALSE) {
2582         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
2583         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2584         goto done;
2585     }
2586 
2587     if (!pData || !pulSignatureLen) {
2588         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
2589         rc = CKR_ARGUMENTS_BAD;
2590         goto done;
2591     }
2592 
2593     sess = session_mgr_find(sSession->sessionh);
2594     if (!sess) {
2595         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
2596         rc = CKR_SESSION_HANDLE_INVALID;
2597         goto done;
2598     }
2599 
2600     if ((sess->sign_ctx.active == FALSE) || (sess->sign_ctx.recover == FALSE)) {
2601         rc = CKR_OPERATION_NOT_INITIALIZED;
2602         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
2603         goto done;
2604     }
2605 
2606     if (!pSignature)
2607         length_only = TRUE;
2608 
2609     rc = sign_mgr_sign_recover(tokdata, sess, length_only, &sess->sign_ctx,
2610                                pData, ulDataLen, pSignature, pulSignatureLen);
2611     if (rc != CKR_OK)
2612         TRACE_DEVEL("sign_mgr_sign_recover() failed.\n");
2613 
2614 done:
2615     if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE))
2616         sign_mgr_cleanup(&sess->sign_ctx);
2617 
2618     TRACE_INFO("C_SignRecover: rc = 0x%08lx, sess = %ld, datalen = %lu\n",
2619                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle, ulDataLen);
2620 
2621     return rc;
2622 }
2623 
2624 
SC_VerifyInit(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)2625 CK_RV SC_VerifyInit(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
2626                     CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
2627 {
2628     SESSION *sess = NULL;
2629     CK_RV rc = CKR_OK;
2630 
2631     if (tokdata->initialized == FALSE) {
2632         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
2633         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2634         goto done;
2635     }
2636     if (!pMechanism) {
2637         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
2638         rc = CKR_ARGUMENTS_BAD;
2639         goto done;
2640     }
2641 
2642     rc = valid_mech(tokdata, pMechanism, CKF_VERIFY);
2643     if (rc != CKR_OK)
2644         goto done;
2645 
2646     sess = session_mgr_find(sSession->sessionh);
2647     if (!sess) {
2648         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
2649         rc = CKR_SESSION_HANDLE_INVALID;
2650         goto done;
2651     }
2652 
2653     if (pin_expired(&sess->session_info,
2654                     tokdata->nv_token_data->token_info.flags) == TRUE) {
2655         TRACE_ERROR("%s\n", ock_err(ERR_PIN_EXPIRED));
2656         rc = CKR_PIN_EXPIRED;
2657         goto done;
2658     }
2659 
2660     if (sess->verify_ctx.active == TRUE) {
2661         rc = CKR_OPERATION_ACTIVE;
2662         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_ACTIVE));
2663         goto done;
2664     }
2665 
2666     rc = verify_mgr_init(tokdata, sess, &sess->verify_ctx, pMechanism,
2667                          FALSE, hKey);
2668     if (rc != CKR_OK)
2669         TRACE_DEVEL("verify_mgr_init() failed.\n");
2670 
2671 done:
2672     TRACE_INFO("C_VerifyInit: rc = 0x%08lx, sess = %ld, mech = 0x%lx\n",
2673                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle,
2674                (pMechanism ? pMechanism->mechanism : (CK_ULONG)-1));
2675 
2676     return rc;
2677 }
2678 
2679 
SC_Verify(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen)2680 CK_RV SC_Verify(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
2681                 CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
2682                 CK_ULONG ulSignatureLen)
2683 {
2684     SESSION *sess = NULL;
2685     CK_RV rc = CKR_OK;
2686 
2687     if (tokdata->initialized == FALSE) {
2688         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
2689         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2690         goto done;
2691     }
2692 
2693     if (!pData || !pSignature) {
2694         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
2695         rc = CKR_ARGUMENTS_BAD;
2696         goto done;
2697     }
2698 
2699     sess = session_mgr_find(sSession->sessionh);
2700     if (!sess) {
2701         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
2702         rc = CKR_SESSION_HANDLE_INVALID;
2703         goto done;
2704     }
2705 
2706     if (sess->verify_ctx.active == FALSE) {
2707         rc = CKR_OPERATION_NOT_INITIALIZED;
2708         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
2709         goto done;
2710     }
2711 
2712     rc = verify_mgr_verify(tokdata, sess, &sess->verify_ctx, pData,
2713                            ulDataLen, pSignature, ulSignatureLen);
2714     if (rc != CKR_OK)
2715         TRACE_DEVEL("verify_mgr_verify() failed.\n");
2716 
2717 done:
2718     verify_mgr_cleanup(&sess->verify_ctx);
2719 
2720     TRACE_INFO("C_Verify: rc = 0x%08lx, sess = %ld, datalen = %lu\n",
2721                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle, ulDataLen);
2722 
2723     return rc;
2724 }
2725 
2726 
SC_VerifyUpdate(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)2727 CK_RV SC_VerifyUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
2728                       CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
2729 {
2730     SESSION *sess = NULL;
2731     CK_RV rc = CKR_OK;
2732 
2733     if (tokdata->initialized == FALSE) {
2734         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
2735         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2736         goto done;
2737     }
2738 
2739     if (!pPart && ulPartLen != 0) {
2740         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
2741         rc = CKR_ARGUMENTS_BAD;
2742         goto done;
2743     }
2744 
2745     sess = session_mgr_find(sSession->sessionh);
2746     if (!sess) {
2747         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
2748         rc = CKR_SESSION_HANDLE_INVALID;
2749         goto done;
2750     }
2751 
2752     if (sess->verify_ctx.active == FALSE) {
2753         rc = CKR_OPERATION_NOT_INITIALIZED;
2754         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
2755         goto done;
2756     }
2757 
2758     rc = verify_mgr_verify_update(tokdata, sess, &sess->verify_ctx, pPart,
2759                                   ulPartLen);
2760     if (rc != CKR_OK)
2761         TRACE_DEVEL("verify_mgr_verify_update() failed.\n");
2762 
2763 done:
2764     if (rc != CKR_OK)
2765         verify_mgr_cleanup(&sess->verify_ctx);
2766 
2767     TRACE_INFO("C_VerifyUpdate: rc = 0x%08lx, sess = %ld, datalen = %lu\n",
2768                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle, ulPartLen);
2769 
2770     return rc;
2771 }
2772 
2773 
SC_VerifyFinal(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen)2774 CK_RV SC_VerifyFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
2775                      CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
2776 {
2777     SESSION *sess = NULL;
2778     CK_RV rc = CKR_OK;
2779 
2780     if (tokdata->initialized == FALSE) {
2781         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
2782         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2783         goto done;
2784     }
2785 
2786     if (!pSignature) {
2787         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
2788         rc = CKR_ARGUMENTS_BAD;
2789         goto done;
2790     }
2791 
2792     sess = session_mgr_find(sSession->sessionh);
2793     if (!sess) {
2794         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
2795         rc = CKR_SESSION_HANDLE_INVALID;
2796         goto done;
2797     }
2798 
2799     if (sess->verify_ctx.active == FALSE) {
2800         rc = CKR_OPERATION_NOT_INITIALIZED;
2801         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
2802         goto done;
2803     }
2804 
2805     rc = verify_mgr_verify_final(tokdata, sess, &sess->verify_ctx,
2806                                  pSignature, ulSignatureLen);
2807     if (rc != CKR_OK)
2808         TRACE_DEVEL("verify_mgr_verify_final() failed.\n");
2809 
2810 done:
2811     verify_mgr_cleanup(&sess->verify_ctx);
2812 
2813     TRACE_INFO("C_VerifyFinal: rc = 0x%08lx, sess = %ld\n",
2814                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle);
2815 
2816     return rc;
2817 }
2818 
2819 
SC_VerifyRecoverInit(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)2820 CK_RV SC_VerifyRecoverInit(STDLL_TokData_t *tokdata,
2821                            ST_SESSION_HANDLE *sSession,
2822                            CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
2823 {
2824     SESSION *sess = NULL;
2825     CK_RV rc = CKR_OK;
2826 
2827     if (tokdata->initialized == FALSE) {
2828         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
2829         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2830         goto done;
2831     }
2832     if (!pMechanism) {
2833         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
2834         rc = CKR_ARGUMENTS_BAD;
2835         goto done;
2836     }
2837 
2838     rc = valid_mech(tokdata, pMechanism, CKF_VERIFY_RECOVER);
2839     if (rc != CKR_OK)
2840         goto done;
2841 
2842     sess = session_mgr_find(sSession->sessionh);
2843     if (!sess) {
2844         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
2845         rc = CKR_SESSION_HANDLE_INVALID;
2846         goto done;
2847     }
2848 
2849     if (pin_expired(&sess->session_info,
2850                     tokdata->nv_token_data->token_info.flags) == TRUE) {
2851         TRACE_ERROR("%s\n", ock_err(ERR_PIN_EXPIRED));
2852         rc = CKR_PIN_EXPIRED;
2853         goto done;
2854     }
2855 
2856     if (sess->verify_ctx.active == TRUE) {
2857         rc = CKR_OPERATION_ACTIVE;
2858         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_ACTIVE));
2859         goto done;
2860     }
2861 
2862     rc = verify_mgr_init(tokdata, sess, &sess->verify_ctx, pMechanism,
2863                          TRUE, hKey);
2864     if (rc != CKR_OK)
2865         TRACE_DEVEL("verify_mgr_init() failed.\n");
2866 
2867 done:
2868     TRACE_INFO("C_VerifyRecoverInit: rc = 0x%08lx, sess = %ld, mech = 0x%lx\n",
2869                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle,
2870                (pMechanism ? pMechanism->mechanism : (CK_ULONG)-1));
2871 
2872     return rc;
2873 }
2874 
2875 
SC_VerifyRecover(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen,CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen)2876 CK_RV SC_VerifyRecover(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
2877                        CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen,
2878                        CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
2879 {
2880     SESSION *sess = NULL;
2881     CK_BBOOL length_only = FALSE;
2882     CK_RV rc = CKR_OK;
2883 
2884     if (tokdata->initialized == FALSE) {
2885         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
2886         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
2887         goto done;
2888     }
2889 
2890     if (!pSignature || !pulDataLen) {
2891         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
2892         rc = CKR_ARGUMENTS_BAD;
2893         goto done;
2894     }
2895 
2896     sess = session_mgr_find(sSession->sessionh);
2897     if (!sess) {
2898         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
2899         rc = CKR_SESSION_HANDLE_INVALID;
2900         goto done;
2901     }
2902 
2903     if ((sess->verify_ctx.active == FALSE) ||
2904         (sess->verify_ctx.recover == FALSE)) {
2905         rc = CKR_OPERATION_NOT_INITIALIZED;
2906         TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
2907         goto done;
2908     }
2909 
2910     if (!pData)
2911         length_only = TRUE;
2912 
2913     rc = verify_mgr_verify_recover(tokdata, sess, length_only,
2914                                    &sess->verify_ctx, pSignature,
2915                                    ulSignatureLen, pData, pulDataLen);
2916     if (rc != CKR_OK)
2917         TRACE_DEVEL("verify_mgr_verify_recover() failed.\n");
2918 
2919 done:
2920     if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE))
2921         verify_mgr_cleanup(&sess->verify_ctx);
2922 
2923     TRACE_INFO("C_VerifyRecover: rc = 0x%08lx, sess = %ld, recover len = %lu, "
2924                "length_only = %d\n", rc,
2925                (sess == NULL) ? -1 : (CK_LONG) sess->handle,
2926                (pulDataLen ? *pulDataLen : 0), length_only);
2927 
2928     return rc;
2929 }
2930 
2931 
SC_DigestEncryptUpdate(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen,CK_BYTE_PTR pEncryptedPart,CK_ULONG_PTR pulEncryptedPartLen)2932 CK_RV SC_DigestEncryptUpdate(STDLL_TokData_t *tokdata,
2933                              ST_SESSION_HANDLE *sSession, CK_BYTE_PTR pPart,
2934                              CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
2935                              CK_ULONG_PTR pulEncryptedPartLen)
2936 {
2937     UNUSED(sSession);
2938     UNUSED(pPart);
2939     UNUSED(ulPartLen);
2940     UNUSED(pEncryptedPart);
2941     UNUSED(pulEncryptedPartLen);
2942 
2943     if (tokdata->initialized == FALSE) {
2944         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
2945         return CKR_CRYPTOKI_NOT_INITIALIZED;
2946     }
2947 
2948     TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED));
2949 
2950     return CKR_FUNCTION_NOT_SUPPORTED;
2951 }
2952 
2953 
SC_DecryptDigestUpdate(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pEncryptedPart,CK_ULONG ulEncryptedPartLen,CK_BYTE_PTR pPart,CK_ULONG_PTR pulPartLen)2954 CK_RV SC_DecryptDigestUpdate(STDLL_TokData_t *tokdata,
2955                              ST_SESSION_HANDLE *sSession,
2956                              CK_BYTE_PTR pEncryptedPart,
2957                              CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart,
2958                              CK_ULONG_PTR pulPartLen)
2959 {
2960     UNUSED(sSession);
2961     UNUSED(pEncryptedPart);
2962     UNUSED(ulEncryptedPartLen);
2963     UNUSED(pPart);
2964     UNUSED(pulPartLen);
2965 
2966     if (tokdata->initialized == FALSE) {
2967         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
2968         return CKR_CRYPTOKI_NOT_INITIALIZED;
2969     }
2970 
2971     TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED));
2972 
2973     return CKR_FUNCTION_NOT_SUPPORTED;
2974 }
2975 
2976 
SC_SignEncryptUpdate(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen,CK_BYTE_PTR pEncryptedPart,CK_ULONG_PTR pulEncryptedPartLen)2977 CK_RV SC_SignEncryptUpdate(STDLL_TokData_t *tokdata,
2978                            ST_SESSION_HANDLE *sSession, CK_BYTE_PTR pPart,
2979                            CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
2980                            CK_ULONG_PTR pulEncryptedPartLen)
2981 {
2982     UNUSED(sSession);
2983     UNUSED(pPart);
2984     UNUSED(ulPartLen);
2985     UNUSED(pEncryptedPart);
2986     UNUSED(pulEncryptedPartLen);
2987 
2988     if (tokdata->initialized == FALSE) {
2989         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
2990         return CKR_CRYPTOKI_NOT_INITIALIZED;
2991     }
2992 
2993     TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED));
2994 
2995     return CKR_FUNCTION_NOT_SUPPORTED;
2996 }
2997 
2998 
SC_DecryptVerifyUpdate(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pEncryptedPart,CK_ULONG ulEncryptedPartLen,CK_BYTE_PTR pPart,CK_ULONG_PTR pulPartLen)2999 CK_RV SC_DecryptVerifyUpdate(STDLL_TokData_t *tokdata,
3000                              ST_SESSION_HANDLE *sSession,
3001                              CK_BYTE_PTR pEncryptedPart,
3002                              CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart,
3003                              CK_ULONG_PTR pulPartLen)
3004 {
3005     UNUSED(sSession);
3006     UNUSED(pEncryptedPart);
3007     UNUSED(ulEncryptedPartLen);
3008     UNUSED(pPart);
3009     UNUSED(pulPartLen);
3010 
3011     if (tokdata->initialized == FALSE) {
3012         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
3013         return CKR_CRYPTOKI_NOT_INITIALIZED;
3014     }
3015 
3016     TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED));
3017 
3018     return CKR_FUNCTION_NOT_SUPPORTED;
3019 }
3020 
3021 
SC_GenerateKey(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_MECHANISM_PTR pMechanism,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phKey)3022 CK_RV SC_GenerateKey(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
3023                      CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate,
3024                      CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey)
3025 {
3026     SESSION *sess = NULL;
3027     CK_RV rc = CKR_OK;
3028 
3029     if (tokdata->initialized == FALSE) {
3030         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
3031         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
3032         goto done;
3033     }
3034 
3035     if (!pMechanism || !phKey || (pTemplate == NULL && ulCount != 0)) {
3036         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
3037         rc = CKR_ARGUMENTS_BAD;
3038         goto done;
3039     }
3040 
3041     rc = valid_mech(tokdata, pMechanism, CKF_GENERATE);
3042     if (rc != CKR_OK)
3043         goto done;
3044 
3045     sess = session_mgr_find(sSession->sessionh);
3046     if (!sess) {
3047         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
3048         rc = CKR_SESSION_HANDLE_INVALID;
3049         goto done;
3050     }
3051 
3052     if (pin_expired(&sess->session_info,
3053                     tokdata->nv_token_data->token_info.flags) == TRUE) {
3054         TRACE_ERROR("%s\n", ock_err(ERR_PIN_EXPIRED));
3055         rc = CKR_PIN_EXPIRED;
3056         goto done;
3057     }
3058 
3059     rc = key_mgr_generate_key(tokdata, sess, pMechanism, pTemplate,
3060                               ulCount, phKey);
3061     if (rc != CKR_OK)
3062         TRACE_DEVEL("key_mgr_generate_key() failed.\n");
3063 
3064 done:
3065     TRACE_INFO("C_GenerateKey: rc = 0x%08lx, sess = %ld, mech = 0x%lx\n", rc,
3066                (sess == NULL) ? -1 : (CK_LONG) sess->handle,
3067                (pMechanism ? pMechanism->mechanism : (CK_ULONG)(-1)));
3068 
3069 #ifdef DEBUG
3070     CK_ATTRIBUTE *attr = NULL;
3071     CK_ULONG i;
3072 
3073     attr = pTemplate;
3074     if (attr != NULL) {
3075         for (i = 0; i < ulCount; i++, attr++) {
3076             CK_BYTE *ptr = (CK_BYTE *) attr->pValue;
3077             TRACE_DEBUG("%lu: Attribute type: 0x%08lx,Value Length: %lu\n",
3078                         i, attr->type, attr->ulValueLen);
3079             if (attr->ulValueLen != ((CK_ULONG) - 1) && (ptr != NULL)) {
3080                 TRACE_DEBUG("First 4 bytes: %02x %02x %02x %02x\n",
3081                             ptr[0], ptr[1], ptr[2], ptr[3]);
3082             }
3083         }
3084     } else {
3085         TRACE_DEBUG("No attributes\n");
3086     }
3087 #endif
3088 
3089     return rc;
3090 }
3091 
3092 
SC_GenerateKeyPair(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_MECHANISM_PTR pMechanism,CK_ATTRIBUTE_PTR pPublicKeyTemplate,CK_ULONG ulPublicKeyAttributeCount,CK_ATTRIBUTE_PTR pPrivateKeyTemplate,CK_ULONG ulPrivateKeyAttributeCount,CK_OBJECT_HANDLE_PTR phPublicKey,CK_OBJECT_HANDLE_PTR phPrivateKey)3093 CK_RV SC_GenerateKeyPair(STDLL_TokData_t *tokdata,
3094                          ST_SESSION_HANDLE *sSession,
3095                          CK_MECHANISM_PTR pMechanism,
3096                          CK_ATTRIBUTE_PTR pPublicKeyTemplate,
3097                          CK_ULONG ulPublicKeyAttributeCount,
3098                          CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
3099                          CK_ULONG ulPrivateKeyAttributeCount,
3100                          CK_OBJECT_HANDLE_PTR phPublicKey,
3101                          CK_OBJECT_HANDLE_PTR phPrivateKey)
3102 {
3103     SESSION *sess = NULL;
3104     CK_RV rc = CKR_OK;
3105 
3106     if (tokdata->initialized == FALSE) {
3107         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
3108         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
3109         goto done;
3110     }
3111 
3112     if (!pMechanism || !phPublicKey || !phPrivateKey ||
3113         (!pPublicKeyTemplate && (ulPublicKeyAttributeCount != 0)) ||
3114         (!pPrivateKeyTemplate && (ulPrivateKeyAttributeCount != 0))) {
3115         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
3116         rc = CKR_ARGUMENTS_BAD;
3117         goto done;
3118     }
3119 
3120     rc = valid_mech(tokdata, pMechanism, CKF_GENERATE_KEY_PAIR);
3121     if (rc != CKR_OK)
3122         goto done;
3123 
3124     sess = session_mgr_find(sSession->sessionh);
3125     if (!sess) {
3126         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
3127         rc = CKR_SESSION_HANDLE_INVALID;
3128         goto done;
3129     }
3130 
3131     if (pin_expired(&sess->session_info,
3132                     tokdata->nv_token_data->token_info.flags) == TRUE) {
3133         TRACE_ERROR("%s\n", ock_err(ERR_PIN_EXPIRED));
3134         rc = CKR_PIN_EXPIRED;
3135         goto done;
3136     }
3137 
3138     rc = key_mgr_generate_key_pair(tokdata, sess, pMechanism,
3139                                    pPublicKeyTemplate,
3140                                    ulPublicKeyAttributeCount,
3141                                    pPrivateKeyTemplate,
3142                                    ulPrivateKeyAttributeCount,
3143                                    phPublicKey, phPrivateKey);
3144     if (rc != CKR_OK)
3145         TRACE_DEVEL("key_mgr_generate_key_pair() failed.\n");
3146 
3147 done:
3148     TRACE_INFO("C_GenerateKeyPair: rc = 0x%08lx, sess = %ld, mech = 0x%lx\n",
3149                rc, (sess == NULL) ? -1 : ((CK_LONG) sess->handle),
3150                (pMechanism ? pMechanism->mechanism : (CK_ULONG)-1));
3151 
3152 #ifdef DEBUG
3153     CK_ATTRIBUTE *attr = NULL;
3154     CK_ULONG i;
3155 
3156     if (rc == CKR_OK) {
3157         TRACE_DEBUG("Public handle: %lu, Private handle: %lu\n",
3158                     *phPublicKey, *phPrivateKey);
3159     }
3160 
3161     TRACE_DEBUG("Public Template:\n");
3162     attr = pPublicKeyTemplate;
3163     if (attr != NULL) {
3164         for (i = 0; i < ulPublicKeyAttributeCount; i++, attr++) {
3165             CK_BYTE *ptr = (CK_BYTE *) attr->pValue;
3166             TRACE_DEBUG("%lu: Attribute type: 0x%08lx, Value Length: %lu\n",
3167                         i, attr->type, attr->ulValueLen);
3168             if (attr->ulValueLen != ((CK_ULONG) - 1) && (ptr != NULL))
3169                 TRACE_DEBUG("First 4 bytes: %02x %02x %02x %02x\n",
3170                              ptr[0], ptr[1], ptr[2], ptr[3]);
3171         }
3172     } else {
3173         TRACE_DEBUG("No Attributes\n");
3174     }
3175 
3176     TRACE_DEBUG("Private Template:\n");
3177     attr = pPublicKeyTemplate;
3178     if (attr != NULL) {
3179         for (i = 0; i < ulPublicKeyAttributeCount; i++, attr++) {
3180             CK_BYTE *ptr = (CK_BYTE *) attr->pValue;
3181             TRACE_DEBUG("%lu: Attribute type: 0x%08lx, Value Length: %lu\n",
3182                         i, attr->type, attr->ulValueLen);
3183             if (attr->ulValueLen != (CK_ULONG) (-1) && (ptr != NULL))
3184                 TRACE_DEBUG("First 4 bytes: %02x %02x %02x %02x\n",
3185                             ptr[0], ptr[1], ptr[2], ptr[3]);
3186         }
3187     } else {
3188         TRACE_DEBUG("No Attributes\n");
3189     }
3190 #endif
3191 
3192     return rc;
3193 }
3194 
3195 
SC_WrapKey(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hWrappingKey,CK_OBJECT_HANDLE hKey,CK_BYTE_PTR pWrappedKey,CK_ULONG_PTR pulWrappedKeyLen)3196 CK_RV SC_WrapKey(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
3197                  CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey,
3198                  CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey,
3199                  CK_ULONG_PTR pulWrappedKeyLen)
3200 {
3201     SESSION *sess = NULL;
3202     CK_BBOOL length_only = FALSE;
3203     CK_RV rc = CKR_OK;
3204 
3205     if (tokdata->initialized == FALSE) {
3206         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
3207         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
3208         goto done;
3209     }
3210 
3211     if (!pMechanism || !pulWrappedKeyLen) {
3212         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
3213         rc = CKR_ARGUMENTS_BAD;
3214         goto done;
3215     }
3216 
3217     rc = valid_mech(tokdata, pMechanism, CKF_WRAP);
3218     if (rc != CKR_OK)
3219         goto done;
3220 
3221     if (!pWrappedKey)
3222         length_only = TRUE;
3223 
3224     sess = session_mgr_find(sSession->sessionh);
3225     if (!sess) {
3226         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
3227         rc = CKR_SESSION_HANDLE_INVALID;
3228         goto done;
3229     }
3230 
3231     if (pin_expired(&sess->session_info,
3232                     tokdata->nv_token_data->token_info.flags) == TRUE) {
3233         TRACE_ERROR("%s\n", ock_err(ERR_PIN_EXPIRED));
3234         rc = CKR_PIN_EXPIRED;
3235         goto done;
3236     }
3237 
3238     rc = key_mgr_wrap_key(tokdata, sess, length_only, pMechanism,
3239                           hWrappingKey, hKey, pWrappedKey, pulWrappedKeyLen);
3240     if (rc != CKR_OK)
3241         TRACE_DEVEL("key_mgr_wrap_key() failed.\n");
3242 
3243 done:
3244     TRACE_INFO("C_WrapKey: rc = 0x%08lx, sess = %ld, encrypting key = %lu, "
3245                "wrapped key = %lu\n", rc,
3246                (sess == NULL) ? -1 : (CK_LONG) sess->handle,
3247                hWrappingKey, hKey);
3248 
3249     return rc;
3250 }
3251 
3252 
SC_UnwrapKey(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hUnwrappingKey,CK_BYTE_PTR pWrappedKey,CK_ULONG ulWrappedKeyLen,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phKey)3253 CK_RV SC_UnwrapKey(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
3254                    CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey,
3255                    CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen,
3256                    CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
3257                    CK_OBJECT_HANDLE_PTR phKey)
3258 {
3259     SESSION *sess = NULL;
3260     CK_RV rc = CKR_OK;
3261 
3262     if (tokdata->initialized == FALSE) {
3263         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
3264         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
3265         goto done;
3266     }
3267 
3268     if (!pMechanism || !pWrappedKey || (!pTemplate && ulCount != 0) || !phKey) {
3269         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
3270         rc = CKR_ARGUMENTS_BAD;
3271         goto done;
3272     }
3273 
3274     rc = valid_mech(tokdata, pMechanism, CKF_UNWRAP);
3275     if (rc != CKR_OK)
3276         goto done;
3277 
3278     sess = session_mgr_find(sSession->sessionh);
3279     if (!sess) {
3280         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
3281         rc = CKR_SESSION_HANDLE_INVALID;
3282         goto done;
3283     }
3284 
3285     if (pin_expired(&sess->session_info,
3286                     tokdata->nv_token_data->token_info.flags) == TRUE) {
3287         TRACE_ERROR("%s\n", ock_err(ERR_PIN_EXPIRED));
3288         rc = CKR_PIN_EXPIRED;
3289         goto done;
3290     }
3291 
3292     rc = key_mgr_unwrap_key(tokdata, sess, pMechanism, pTemplate, ulCount,
3293                             pWrappedKey, ulWrappedKeyLen, hUnwrappingKey,
3294                             phKey);
3295     if (rc != CKR_OK)
3296         TRACE_DEVEL("key_mgr_unwrap_key() failed.\n");
3297 
3298 done:
3299     TRACE_INFO("C_UnwrapKey: rc = 0x%08lx, sess = %ld, decrypting key = %lu,"
3300                "unwrapped key = %lu\n", rc,
3301                (sess == NULL) ? -1 : (CK_LONG) sess->handle,
3302                hUnwrappingKey, (phKey ? *phKey : 0));
3303 
3304 #ifdef DEBUG
3305     CK_ATTRIBUTE *attr = NULL;
3306     CK_BYTE *ptr = NULL;
3307     CK_ULONG i;
3308 
3309     attr = pTemplate;
3310     if (attr != NULL) {
3311         for (i = 0; i < ulCount; i++, attr++) {
3312             ptr = (CK_BYTE *) attr->pValue;
3313             TRACE_DEBUG("%lu: Attribute type: 0x%08lx,Value Length: %lu\n",
3314                         i, attr->type, attr->ulValueLen);
3315             if (attr->ulValueLen != ((CK_ULONG) - 1) && (ptr != NULL)) {
3316                 TRACE_DEBUG("First 4 bytes: %02x %02x %02x %02x\n",
3317                             ptr[0], ptr[1], ptr[2], ptr[3]);
3318             }
3319         }
3320     } else {
3321         TRACE_DEBUG("No attributes\n");
3322     }
3323 #endif
3324 
3325     return rc;
3326 }
3327 
3328 
SC_DeriveKey(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hBaseKey,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phKey)3329 CK_RV SC_DeriveKey(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
3330                    CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey,
3331                    CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
3332                    CK_OBJECT_HANDLE_PTR phKey)
3333 {
3334     SESSION *sess = NULL;
3335     CK_RV rc = CKR_OK;
3336 
3337     if (tokdata->initialized == FALSE) {
3338         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
3339         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
3340         goto done;
3341     }
3342 
3343     if (!pMechanism || (!pTemplate && ulCount != 0)) {
3344         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
3345         rc = CKR_ARGUMENTS_BAD;
3346         goto done;
3347     }
3348 
3349     rc = valid_mech(tokdata, pMechanism, CKF_DERIVE);
3350     if (rc != CKR_OK)
3351         goto done;
3352 
3353     sess = session_mgr_find(sSession->sessionh);
3354     if (!sess) {
3355         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
3356         rc = CKR_SESSION_HANDLE_INVALID;
3357         goto done;
3358     }
3359 
3360     if (pin_expired(&sess->session_info,
3361                     tokdata->nv_token_data->token_info.flags) == TRUE) {
3362         TRACE_ERROR("%s\n", ock_err(ERR_PIN_EXPIRED));
3363         rc = CKR_PIN_EXPIRED;
3364         goto done;
3365     }
3366 
3367     rc = key_mgr_derive_key(tokdata, sess, pMechanism, hBaseKey, phKey,
3368                             pTemplate, ulCount);
3369     if (rc != CKR_OK)
3370         TRACE_DEVEL("key_mgr_derive_key() failed.\n");
3371 
3372 done:
3373     TRACE_INFO("C_DeriveKey: rc = 0x%08lx, sess = %ld, mech = 0x%lx\n",
3374                rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle,
3375                (pMechanism ? pMechanism->mechanism : (CK_ULONG)(-1)));
3376 #ifdef DEBUG
3377     CK_ATTRIBUTE *attr = NULL;
3378     CK_BYTE *ptr = NULL;
3379     CK_ULONG i;
3380 
3381     if (rc == CKR_OK) {
3382         switch (pMechanism->mechanism) {
3383         case CKM_SSL3_KEY_AND_MAC_DERIVE:
3384             {
3385                 CK_SSL3_KEY_MAT_PARAMS *pReq;
3386                 CK_SSL3_KEY_MAT_OUT *pPtr;
3387                 pReq = (CK_SSL3_KEY_MAT_PARAMS *) pMechanism->pParameter;
3388                 pPtr = pReq->pReturnedKeyMaterial;
3389 
3390                 TRACE_DEBUG("Client MAC key: %lu, Server MAC key: %lu, "
3391                             "Client Key: %lu, Server Key: %lu\n",
3392                             pPtr->hClientMacSecret,
3393                             pPtr->hServerMacSecret, pPtr->hClientKey,
3394                             pPtr->hServerKey);
3395             }
3396             break;
3397         case CKM_DH_PKCS_DERIVE:
3398             TRACE_DEBUG("DH Shared Secret:\n");
3399             break;
3400         default:
3401             TRACE_DEBUG("Derived key: %lu\n", *phKey);
3402         }
3403     }
3404 
3405     attr = pTemplate;
3406     if (attr != NULL) {
3407         for (i = 0; i < ulCount; i++, attr++) {
3408             ptr = (CK_BYTE *) attr->pValue;
3409             TRACE_DEBUG("%lu: Attribute type: 0x%08lx,Value Length: %lu\n",
3410                         i, attr->type, attr->ulValueLen);
3411             if (attr->ulValueLen != ((CK_ULONG) - 1) && (ptr != NULL)) {
3412                 TRACE_DEBUG("First 4 bytes: %02x %02x %02x %02x\n",
3413                             ptr[0], ptr[1], ptr[2], ptr[3]);
3414             }
3415         }
3416     } else {
3417         TRACE_DEBUG("No attributes\n");
3418     }
3419 #endif                          /* DEBUG */
3420 
3421     return rc;
3422 }
3423 
3424 
SC_SeedRandom(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pSeed,CK_ULONG ulSeedLen)3425 CK_RV SC_SeedRandom(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
3426                     CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen)
3427 {
3428     UNUSED(sSession);
3429     UNUSED(pSeed);
3430     UNUSED(ulSeedLen);
3431 
3432     if (tokdata->initialized == FALSE) {
3433         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
3434         return CKR_CRYPTOKI_NOT_INITIALIZED;
3435     }
3436 
3437     TRACE_ERROR("%s\n", ock_err(ERR_RANDOM_SEED_NOT_SUPPORTED));
3438 
3439     return CKR_RANDOM_SEED_NOT_SUPPORTED;
3440 }
3441 
3442 
SC_GenerateRandom(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession,CK_BYTE_PTR pRandomData,CK_ULONG ulRandomLen)3443 CK_RV SC_GenerateRandom(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
3444                         CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen)
3445 {
3446     SESSION *sess = NULL;
3447     CK_RV rc = CKR_OK;
3448 
3449     if (tokdata->initialized == FALSE) {
3450         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
3451         rc = CKR_CRYPTOKI_NOT_INITIALIZED;
3452         goto done;
3453     }
3454 
3455     if (!pRandomData && ulRandomLen != 0) {
3456         TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD));
3457         rc = CKR_ARGUMENTS_BAD;
3458         goto done;
3459     }
3460 
3461     sess = session_mgr_find(sSession->sessionh);
3462     if (!sess) {
3463         TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
3464         rc = CKR_SESSION_HANDLE_INVALID;
3465         goto done;
3466     }
3467 
3468     rc = rng_generate(tokdata, pRandomData, ulRandomLen);
3469     if (rc != CKR_OK)
3470         TRACE_DEVEL("rng_generate() failed.\n");
3471 
3472 done:
3473     TRACE_INFO("C_GenerateRandom: rc = 0x%08lx, %lu bytes\n", rc, ulRandomLen);
3474 
3475     return rc;
3476 }
3477 
3478 
SC_GetFunctionStatus(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession)3479 CK_RV SC_GetFunctionStatus(STDLL_TokData_t *tokdata,
3480                            ST_SESSION_HANDLE *sSession)
3481 {
3482     UNUSED(sSession);
3483 
3484     if (tokdata->initialized == FALSE) {
3485         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
3486         return CKR_CRYPTOKI_NOT_INITIALIZED;
3487     }
3488 
3489     TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_PARALLEL));
3490 
3491     return CKR_FUNCTION_NOT_PARALLEL;
3492 }
3493 
3494 
SC_CancelFunction(STDLL_TokData_t * tokdata,ST_SESSION_HANDLE * sSession)3495 CK_RV SC_CancelFunction(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession)
3496 {
3497     UNUSED(sSession);
3498 
3499     if (tokdata->initialized == FALSE) {
3500         TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
3501         return CKR_CRYPTOKI_NOT_INITIALIZED;
3502     }
3503 
3504     TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_PARALLEL));
3505 
3506     return CKR_FUNCTION_NOT_PARALLEL;
3507 }
3508 
3509 
SC_SetFunctionList(void)3510 void SC_SetFunctionList(void)
3511 {
3512     function_list.ST_Initialize = ST_Initialize;
3513     function_list.ST_GetTokenInfo = SC_GetTokenInfo;
3514     function_list.ST_GetMechanismList = SC_GetMechanismList;
3515     function_list.ST_GetMechanismInfo = SC_GetMechanismInfo;
3516     function_list.ST_InitToken = SC_InitToken;
3517     function_list.ST_InitPIN = SC_InitPIN;
3518     function_list.ST_SetPIN = SC_SetPIN;
3519     function_list.ST_OpenSession = SC_OpenSession;
3520     function_list.ST_CloseSession = SC_CloseSession;
3521     function_list.ST_GetSessionInfo = SC_GetSessionInfo;
3522     function_list.ST_GetOperationState = SC_GetOperationState;
3523     function_list.ST_SetOperationState = SC_SetOperationState;
3524     function_list.ST_Login = SC_Login;
3525     function_list.ST_Logout = SC_Logout;
3526     function_list.ST_CreateObject = SC_CreateObject;
3527     function_list.ST_CopyObject = SC_CopyObject;
3528     function_list.ST_DestroyObject = SC_DestroyObject;
3529     function_list.ST_GetObjectSize = SC_GetObjectSize;
3530     function_list.ST_GetAttributeValue = SC_GetAttributeValue;
3531     function_list.ST_SetAttributeValue = SC_SetAttributeValue;
3532     function_list.ST_FindObjectsInit = SC_FindObjectsInit;
3533     function_list.ST_FindObjects = SC_FindObjects;
3534     function_list.ST_FindObjectsFinal = SC_FindObjectsFinal;
3535     function_list.ST_EncryptInit = SC_EncryptInit;
3536     function_list.ST_Encrypt = SC_Encrypt;
3537     function_list.ST_EncryptUpdate = SC_EncryptUpdate;
3538     function_list.ST_EncryptFinal = SC_EncryptFinal;
3539     function_list.ST_DecryptInit = SC_DecryptInit;
3540     function_list.ST_Decrypt = SC_Decrypt;
3541     function_list.ST_DecryptUpdate = SC_DecryptUpdate;
3542     function_list.ST_DecryptFinal = SC_DecryptFinal;
3543     function_list.ST_DigestInit = SC_DigestInit;
3544     function_list.ST_Digest = SC_Digest;
3545     function_list.ST_DigestUpdate = SC_DigestUpdate;
3546     function_list.ST_DigestKey = SC_DigestKey;
3547     function_list.ST_DigestFinal = SC_DigestFinal;
3548     function_list.ST_SignInit = SC_SignInit;
3549     function_list.ST_Sign = SC_Sign;
3550     function_list.ST_SignUpdate = SC_SignUpdate;
3551     function_list.ST_SignFinal = SC_SignFinal;
3552     function_list.ST_SignRecoverInit = SC_SignRecoverInit;
3553     function_list.ST_SignRecover = SC_SignRecover;
3554     function_list.ST_VerifyInit = SC_VerifyInit;
3555     function_list.ST_Verify = SC_Verify;
3556     function_list.ST_VerifyUpdate = SC_VerifyUpdate;
3557     function_list.ST_VerifyFinal = SC_VerifyFinal;
3558     function_list.ST_VerifyRecoverInit = SC_VerifyRecoverInit;
3559     function_list.ST_VerifyRecover = SC_VerifyRecover;
3560     function_list.ST_DigestEncryptUpdate = NULL;      // SC_DigestEncryptUpdate;
3561     function_list.ST_DecryptDigestUpdate = NULL;      // SC_DecryptDigestUpdate;
3562     function_list.ST_SignEncryptUpdate = NULL;  //SC_SignEncryptUpdate;
3563     function_list.ST_DecryptVerifyUpdate = NULL;      // SC_DecryptVerifyUpdate;
3564     function_list.ST_GenerateKey = SC_GenerateKey;
3565     function_list.ST_GenerateKeyPair = SC_GenerateKeyPair;
3566     function_list.ST_WrapKey = SC_WrapKey;
3567     function_list.ST_UnwrapKey = SC_UnwrapKey;
3568     function_list.ST_DeriveKey = SC_DeriveKey;
3569     function_list.ST_SeedRandom = SC_SeedRandom;
3570     function_list.ST_GenerateRandom = SC_GenerateRandom;
3571     function_list.ST_GetFunctionStatus = NULL;  // SC_GetFunctionStatus;
3572     function_list.ST_CancelFunction = NULL;     // SC_CancelFunction;
3573 }
3574