1 /*
   2  *              Common Public License Version 0.5
   3  *
   4  *              THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF
   5  *              THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE,
   6  *              REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES
   7  *              RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
   8  *
   9  *              1. DEFINITIONS
  10  *
  11  *              "Contribution" means:
  12  *                    a) in the case of the initial Contributor, the
  13  *                    initial code and documentation distributed under
  14  *                    this Agreement, and
  15  *
  16  *                    b) in the case of each subsequent Contributor:
  17  *                    i) changes to the Program, and
  18  *                    ii) additions to the Program;
  19  *
  20  *                    where such changes and/or additions to the Program
  21  *                    originate from and are distributed by that
  22  *                    particular Contributor. A Contribution 'originates'
  23  *                    from a Contributor if it was added to the Program
  24  *                    by such Contributor itself or anyone acting on such
  25  *                    Contributor's behalf. Contributions do not include
  26  *                    additions to the Program which: (i) are separate
  27  *                    modules of software distributed in conjunction with
  28  *                    the Program under their own license agreement, and
  29  *                    (ii) are not derivative works of the Program.
  30  *
  31  *
  32  *              "Contributor" means any person or entity that distributes
  33  *              the Program.
  34  *
  35  *              "Licensed Patents " mean patent claims licensable by a
  36  *              Contributor which are necessarily infringed by the use or
  37  *              sale of its Contribution alone or when combined with the
  38  *              Program.
  39  *
  40  *              "Program" means the Contributions distributed in
  41  *              accordance with this Agreement.
  42  *
  43  *              "Recipient" means anyone who receives the Program under
  44  *              this Agreement, including all Contributors.
  45  *
  46  *              2. GRANT OF RIGHTS
  47  *
  48  *                    a) Subject to the terms of this Agreement, each
  49  *                    Contributor hereby grants Recipient a
  50  *                    no - exclusive, worldwide, royalt - free copyright
  51  *                    license to reproduce, prepare derivative works of,
  52  *                    publicly display, publicly perform, distribute and
  53  *                    sublicense the Contribution of such Contributor, if
  54  *                    any, and such derivative works, in source code and
  55  *                    object code form.
  56  *
  57  *                    b) Subject to the terms of this Agreement, each
  58  *                    Contributor hereby grants Recipient a
  59  *                    no - exclusive, worldwide, royalt - free patent
  60  *                    license under Licensed Patents to make, use, sell,
  61  *                    offer to sell, import and otherwise transfer the
  62  *                    Contribution of such Contributor, if any, in source
  63  *                    code and object code form. This patent license
  64  *                    shall apply to the combination of the Contribution
  65  *                    and the Program if, at the time the Contribution is
  66  *                    added by the Contributor, such addition of the
  67  *                    Contribution causes such combination to be covered
  68  *                    by the Licensed Patents. The patent license shall
  69  *                    not apply to any other combinations which include
  70  *                    the Contribution. No hardware per se is licensed
  71  *                    hereunder.
  72  *
  73  *                    c) Recipient understands that although each
  74  *                    Contributor grants the licenses to its
  75  *                    Contributions set forth herein, no assurances are
  76  *                    provided by any Contributor that the Program does
  77  *                    not infringe the patent or other intellectual
  78  *                    property rights of any other entity. Each
  79  *                    Contributor disclaims any liability to Recipient
  80  *                    for claims brought by any other entity based on
  81  *                    infringement of intellectual property rights or
  82  *                    otherwise. As a condition to exercising the rights
  83  *                    and licenses granted hereunder, each Recipient
  84  *                    hereby assumes sole responsibility to secure any
  85  *                    other intellectual property rights needed, if any.
  86  *
  87  *                    For example, if a third party patent license is
  88  *                    required to allow Recipient to distribute the
  89  *                    Program, it is Recipient's responsibility to
  90  *                    acquire that license before distributing the
  91  *                    Program.
  92  *
  93  *                    d) Each Contributor represents that to its
  94  *                    knowledge it has sufficient copyright rights in its
  95  *                    Contribution, if any, to grant the copyright
  96  *                    license set forth in this Agreement.
  97  *
  98  *              3. REQUIREMENTS
  99  *
 100  *              A Contributor may choose to distribute the Program in
 101  *              object code form under its own license agreement, provided
 102  *              that:
 103  *                    a) it complies with the terms and conditions of
 104  *                    this Agreement; and
 105  *
 106  *                    b) its license agreement:
 107  *                    i) effectively disclaims on behalf of all
 108  *                    Contributors all warranties and conditions, express
 109  *                    and implied, including warranties or conditions of
 110  *                    title and no - infringement, and implied warranties
 111  *                    or conditions of merchantability and fitness for a
 112  *                    particular purpose;
 113  *
 114  *                    ii) effectively excludes on behalf of all
 115  *                    Contributors all liability for damages, including
 116  *                    direct, indirect, special, incidental and
 117  *                    consequential damages, such as lost profits;
 118  *
 119  *                    iii) states that any provisions which differ from
 120  *                    this Agreement are offered by that Contributor
 121  *                    alone and not by any other party; and
 122  *
 123  *                    iv) states that source code for the Program is
 124  *                    available from such Contributor, and informs
 125  *                    licensees how to obtain it in a reasonable manner
 126  *                    on or through a medium customarily used for
 127  *                    software exchange.
 128  *
 129  *              When the Program is made available in source code form:
 130  *                    a) it must be made available under this Agreement;
 131  *                    and
 132  *                    b) a copy of this Agreement must be included with
 133  *                    each copy of the Program.
 134  *
 135  *              Contributors may not remove or alter any copyright notices
 136  *              contained within the Program.
 137  *
 138  *              Each Contributor must identify itself as the originator of
 139  *              its Contribution, if any, in a manner that reasonably
 140  *              allows subsequent Recipients to identify the originator of
 141  *              the Contribution.
 142  *
 143  *
 144  *              4. COMMERCIAL DISTRIBUTION
 145  *
 146  *              Commercial distributors of software may accept certain
 147  *              responsibilities with respect to end users, business
 148  *              partners and the like. While this license is intended to
 149  *              facilitate the commercial use of the Program, the
 150  *              Contributor who includes the Program in a commercial
 151  *              product offering should do so in a manner which does not
 152  *              create potential liability for other Contributors.
 153  *              Therefore, if a Contributor includes the Program in a
 154  *              commercial product offering, such Contributor ("Commercial
 155  *              Contributor") hereby agrees to defend and indemnify every
 156  *              other Contributor ("Indemnified Contributor") against any
 157  *              losses, damages and costs (collectively "Losses") arising
 158  *              from claims, lawsuits and other legal actions brought by a
 159  *              third party against the Indemnified Contributor to the
 160  *              extent caused by the acts or omissions of such Commercial
 161  *              Contributor in connection with its distribution of the
 162  *              Program in a commercial product offering. The obligations
 163  *              in this section do not apply to any claims or Losses
 164  *              relating to any actual or alleged intellectual property
 165  *              infringement. In order to qualify, an Indemnified
 166  *              Contributor must: a) promptly notify the Commercial
 167  *              Contributor in writing of such claim, and b) allow the
 168  *              Commercial Contributor to control, and cooperate with the
 169  *              Commercial Contributor in, the defense and any related
 170  *              settlement negotiations. The Indemnified Contributor may
 171  *              participate in any such claim at its own expense.
 172  *
 173  *
 174  *              For example, a Contributor might include the Program in a
 175  *              commercial product offering, Product X. That Contributor
 176  *              is then a Commercial Contributor. If that Commercial
 177  *              Contributor then makes performance claims, or offers
 178  *              warranties related to Product X, those performance claims
 179  *              and warranties are such Commercial Contributor's
 180  *              responsibility alone. Under this section, the Commercial
 181  *              Contributor would have to defend claims against the other
 182  *              Contributors related to those performance claims and
 183  *              warranties, and if a court requires any other Contributor
 184  *              to pay any damages as a result, the Commercial Contributor
 185  *              must pay those damages.
 186  *
 187  *
 188  *              5. NO WARRANTY
 189  *
 190  *              EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE
 191  *              PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
 192  *              WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
 193  *              IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
 194  *              CONDITIONS OF TITLE, NO - INFRINGEMENT, MERCHANTABILITY OR
 195  *              FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
 196  *              responsible for determining the appropriateness of using
 197  *              and distributing the Program and assumes all risks
 198  *              associated with its exercise of rights under this
 199  *              Agreement, including but not limited to the risks and
 200  *              costs of program errors, compliance with applicable laws,
 201  *              damage to or loss of data, programs or equipment, and
 202  *              unavailability or interruption of operations.
 203  *
 204  *              6. DISCLAIMER OF LIABILITY
 205  *              EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER
 206  *              RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY
 207  *              FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 208  *              OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
 209  *              LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
 210  *              LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 211  *              (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 212  *              OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE
 213  *              OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
 214  *              POSSIBILITY OF SUCH DAMAGES.
 215  *
 216  *              7. GENERAL
 217  *
 218  *              If any provision of this Agreement is invalid or
 219  *              unenforceable under applicable law, it shall not affect
 220  *              the validity or enforceability of the remainder of the
 221  *              terms of this Agreement, and without further action by the
 222  *              parties hereto, such provision shall be reformed to the
 223  *              minimum extent necessary to make such provision valid and
 224  *              enforceable.
 225  *
 226  *
 227  *              If Recipient institutes patent litigation against a
 228  *              Contributor with respect to a patent applicable to
 229  *              software (including a cros - claim or counterclaim in a
 230  *              lawsuit), then any patent licenses granted by that
 231  *              Contributor to such Recipient under this Agreement shall
 232  *              terminate as of the date such litigation is filed. In
 233  *              addition, If Recipient institutes patent litigation
 234  *              against any entity (including a cros - claim or
 235  *              counterclaim in a lawsuit) alleging that the Program
 236  *              itself (excluding combinations of the Program with other
 237  *              software or hardware) infringes such Recipient's
 238  *              patent(s), then such Recipient's rights granted under
 239  *              Section 2(b) shall terminate as of the date such
 240  *              litigation is filed.
 241  *
 242  *              All Recipient's rights under this Agreement shall
 243  *              terminate if it fails to comply with any of the material
 244  *              terms or conditions of this Agreement and does not cure
 245  *              such failure in a reasonable period of time after becoming
 246  *              aware of such noncompliance. If all Recipient's rights
 247  *              under this Agreement terminate, Recipient agrees to cease
 248  *              use and distribution of the Program as soon as reasonably
 249  *              practicable. However, Recipient's obligations under this
 250  *              Agreement and any licenses granted by Recipient relating
 251  *              to the Program shall continue and survive.
 252  *
 253  *              Everyone is permitted to copy and distribute copies of
 254  *              this Agreement, but in order to avoid inconsistency the
 255  *              Agreement is copyrighted and may only be modified in the
 256  *              following manner. The Agreement Steward reserves the right
 257  *              to publish new versions (including revisions) of this
 258  *              Agreement from time to time. No one other than the
 259  *              Agreement Steward has the right to modify this Agreement.
 260  *
 261  *              IBM is the initial Agreement Steward. IBM may assign the
 262  *              responsibility to serve as the Agreement Steward to a
 263  *              suitable separate entity. Each new version of the
 264  *              Agreement will be given a distinguishing version number.
 265  *              The Program (including Contributions) may always be
 266  *              distributed subject to the version of the Agreement under
 267  *              which it was received. In addition, after a new version of
 268  *              the Agreement is published, Contributor may elect to
 269  *              distribute the Program (including its Contributions) under
 270  *              the new version. Except as expressly stated in Sections
 271  *              2(a) and 2(b) above, Recipient receives no rights or
 272  *              licenses to the intellectual property of any Contributor
 273  *              under this Agreement, whether expressly, by implication,
 274  *              estoppel or otherwise. All rights in the Program not
 275  *              expressly granted under this Agreement are reserved.
 276  *
 277  *
 278  *              This Agreement is governed by the laws of the State of New
 279  *              York and the intellectual property laws of the United
 280  *              States of America. No party to this Agreement will bring a
 281  *              legal action under this Agreement more than one year after
 282  *              the cause of action arose. Each party waives its rights to
 283  *              a jury trial in any resulting litigation.
 284  *
 285  *
 286  *
 287  * (C) COPYRIGHT International Business Machines Corp. 2001, 2002
 288  */
 289 /*
 290  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 291  * Use is subject to license terms.
 292  */
 293 
 294 #include "tpmtok_int.h"
 295 
 296 #define LOG(x)  logit(LOG_DEBUG, x)
 297 
 298 /*
 299  * NOTES:
 300  * In many cases the specificaiton does not allow returns
 301  * of CKR_ARGUMENTSB_BAD.  We break the spec, since validation of parameters
 302  * to the function are best represented by this return code (where
 303  * specific RC's such as CKR_INVALID_SESSION do not exist).
 304  * NOTE NOTE NOTE NOTE
 305  *    The parameter checking on the update operations may need to be
 306  *    modified (as well as the encrypt/decrypt) to call the std API
 307  *    anyway with sanatized parameters since on error, the encrypt/decrypt
 308  *    sign operations are all supposed to complete.
 309  *    Therefor the parameter checking here might need to be done in
 310  *    the STDLL instead of the API.
 311  *    This would affect ALL the Multipart operations which have
 312  *    an init followed by one or more operations.
 313  *
 314  * Globals for the API
 315  */
 316 API_Proc_Struct_t  *Anchor = NULL;
 317 static unsigned int   Initialized = 0;
 318 static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER;
 319 struct ST_FCN_LIST FuncList;
 320 CK_FUNCTION_LIST PK11_Functions;
 321 extern pthread_rwlock_t obj_list_rw_mutex;
 322 
 323 
 324 static void
 325 tpmtoken_fork_prepare()
 326 {
 327         (void) pthread_mutex_lock(&global_mutex);
 328         (void) pthread_mutex_lock(&pkcs_mutex);
 329         (void) pthread_mutex_lock(&obj_list_mutex);
 330         (void) pthread_rwlock_wrlock(&obj_list_rw_mutex);
 331         (void) pthread_mutex_lock(&sess_list_mutex);
 332         (void) pthread_mutex_lock(&login_mutex);
 333         if (Anchor) {
 334                 (void) pthread_mutex_lock(&Anchor->ProcMutex);
 335                 (void) pthread_mutex_lock(&Anchor->SessListMutex);
 336         }
 337 }
 338 
 339 static void
 340 tpmtoken_fork_parent()
 341 {
 342         if (Anchor) {
 343                 (void) pthread_mutex_unlock(&Anchor->SessListMutex);
 344                 (void) pthread_mutex_unlock(&Anchor->ProcMutex);
 345         }
 346         (void) pthread_mutex_unlock(&login_mutex);
 347         (void) pthread_mutex_unlock(&sess_list_mutex);
 348         (void) pthread_rwlock_unlock(&obj_list_rw_mutex);
 349         (void) pthread_mutex_unlock(&obj_list_mutex);
 350         (void) pthread_mutex_unlock(&pkcs_mutex);
 351         (void) pthread_mutex_unlock(&global_mutex);
 352 }
 353 
 354 static void
 355 tpmtoken_fork_child()
 356 {
 357         if (Anchor) {
 358                 (void) pthread_mutex_unlock(&Anchor->SessListMutex);
 359                 (void) pthread_mutex_unlock(&Anchor->ProcMutex);
 360         }
 361 
 362         (void) pthread_mutex_unlock(&login_mutex);
 363         (void) pthread_mutex_unlock(&sess_list_mutex);
 364         (void) pthread_rwlock_unlock(&obj_list_rw_mutex);
 365         (void) pthread_mutex_unlock(&obj_list_mutex);
 366         (void) pthread_mutex_unlock(&pkcs_mutex);
 367         (void) pthread_mutex_unlock(&global_mutex);
 368 
 369         if (Anchor) {
 370                 Terminate_All_Process_Sessions();
 371                 free(Anchor);
 372                 Anchor = NULL;
 373         }
 374         if (FuncList.ST_Finalize)
 375                 FuncList.ST_Finalize(0);
 376 
 377         logterm();
 378         loginit();
 379 }
 380 
 381 /*ARGSUSED*/
 382 CK_RV
 383 C_CancelFunction(CK_SESSION_HANDLE hSession)
 384 {
 385         LOG("C_CancelFunction");
 386         if (API_Initialized() == FALSE) {
 387                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 388         }
 389         return (CKR_FUNCTION_NOT_PARALLEL);
 390 }
 391 
 392 CK_RV
 393 C_CloseAllSessions(CK_SLOT_ID slotID)
 394 {
 395         Session_Struct_t *pCur, *pPrev;
 396         CK_RV    rv;
 397         /*
 398          * Although why does modutil do a close all sessions.  It is a single
 399          * application it can only close its sessions...
 400          * And all sessions should be closed anyhow.
 401          */
 402         LOG("CloseAllSessions");
 403         if (API_Initialized() == FALSE)
 404                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 405 
 406         if (!global_shm->token_available || (slotID > NUMBER_SLOTS_MANAGED))
 407                 return (CKR_SLOT_ID_INVALID);
 408         /*
 409          * Proc Mutex is locked when we remove from the seesion list in
 410          * Close SEssion.  Therefore we don't need to do any locking
 411          * the atomic operations are controled when we use the linked list
 412          */
 413         pCur = (Anchor ? Anchor->SessListBeg : NULL);
 414         while (pCur) {
 415                 /*
 416                  * Session owned by the slot we are working on
 417                  * There is a basic problem here.  We are using th pCur
 418                  * to point to the current one, however we delete it from
 419                  * the linked list and can no longer go Forward.  So we
 420                  * have to use the fact that this is a doubly linked list
 421                  * and get the previous pointer.  After deletion, the next
 422                  * pointer of this block will point to the next one in the
 423                  * list.
 424                  * If the value is Null, then this was the first one in
 425                  * the list and we just set pCur to the SessListBeg.
 426                  */
 427                 if (pCur->SltId == slotID) {
 428                         pPrev = pCur->Previous;
 429                         rv = C_CloseSession((CK_SESSION_HANDLE)pCur);
 430                         if (rv == CKR_OK ||
 431                             rv == CKR_SESSION_CLOSED ||
 432                             rv == CKR_SESSION_HANDLE_INVALID) {
 433                                 if (pPrev == NULL) {
 434                                         pCur = Anchor->SessListBeg;
 435                                 } else {
 436                                         pCur = pPrev->Next;
 437                                 }
 438                         } else {
 439                                 return (rv);
 440                         }
 441                 } else {
 442                         pCur = pCur->Next;
 443                 }
 444         }
 445         LOG("CloseAllSessions OK");
 446         return (CKR_OK);
 447 }
 448 CK_RV
 449 C_CloseSession(CK_SESSION_HANDLE hSession)
 450 {
 451         CK_RV rv;
 452         Session_Struct_t *sessp;
 453         ST_SESSION_T rSession;
 454         LOG("C_CloseSession");
 455         if (API_Initialized() == FALSE) {
 456                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 457         }
 458         /* Validate Session */
 459         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
 460                 return (CKR_SESSION_HANDLE_INVALID);
 461         }
 462 
 463         if (FuncList.ST_CloseSession) {
 464                 /* Map the Session to the slot session */
 465                 rv = FuncList.ST_CloseSession(rSession);
 466 
 467                 if (rv == CKR_OK) {
 468                         sessp = (Session_Struct_t *)hSession;
 469                         RemoveFromSessionList(sessp);
 470                 }
 471         } else {
 472                 rv = CKR_FUNCTION_NOT_SUPPORTED;
 473         }
 474         return (rv);
 475 }
 476 
 477 CK_RV
 478 C_CopyObject(
 479         CK_SESSION_HANDLE       hSession,
 480         CK_OBJECT_HANDLE        hObject,
 481         CK_ATTRIBUTE_PTR        pTemplate,
 482         CK_ULONG                ulCount,
 483         CK_OBJECT_HANDLE_PTR    phNewObject)
 484 {
 485         CK_RV rv;
 486         ST_SESSION_T rSession;
 487         LOG("C_CopyObject");
 488         if (API_Initialized() == FALSE) {
 489                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 490         }
 491         if (!Valid_Session((Session_Struct_t *)hSession, &rSession)) {
 492                 return (CKR_SESSION_HANDLE_INVALID);
 493         }
 494         if (!phNewObject) {
 495                 return (CKR_ARGUMENTS_BAD);
 496         }
 497         /*
 498          * A null template with a count will cause the lower layer
 499          * to have problems.
 500          * Template with 0 count is not a problem.
 501          */
 502         if (!pTemplate && ulCount) {
 503                 return (CKR_ARGUMENTS_BAD);
 504         }
 505         if (FuncList.ST_CopyObject) {
 506                 rv = FuncList.ST_CopyObject(rSession, hObject, pTemplate,
 507                     ulCount, phNewObject);
 508         } else {
 509                 rv = CKR_FUNCTION_NOT_SUPPORTED;
 510         }
 511         return (rv);
 512 }
 513 
 514 CK_RV
 515 C_CreateObject(
 516         CK_SESSION_HANDLE       hSession,
 517         CK_ATTRIBUTE_PTR        pTemplate,
 518         CK_ULONG                ulCount,
 519         CK_OBJECT_HANDLE_PTR    phObject)
 520 {
 521         CK_RV   rv;
 522         ST_SESSION_T rSession;
 523 
 524         if (API_Initialized() == FALSE) {
 525                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 526         }
 527         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
 528                 return (CKR_SESSION_HANDLE_INVALID);
 529         }
 530         if (! pTemplate) {
 531                 return (CKR_TEMPLATE_INCOMPLETE);
 532         }
 533         if (ulCount == 0) {
 534                 return (CKR_TEMPLATE_INCOMPLETE);
 535         }
 536         if (! phObject) {
 537                 return (CKR_ARGUMENTS_BAD);
 538         }
 539         if (FuncList.ST_CreateObject) {
 540                 // Map the Session to the slot session
 541                 rv = FuncList.ST_CreateObject(rSession, pTemplate,
 542                     ulCount, phObject);
 543         } else {
 544                 rv = CKR_FUNCTION_NOT_SUPPORTED;
 545         }
 546         return (rv);
 547 }
 548 
 549 CK_RV
 550 C_Decrypt(CK_SESSION_HANDLE hSession,
 551         CK_BYTE_PTR     pEncryptedData,
 552         CK_ULONG        ulEncryptedDataLen,
 553         CK_BYTE_PTR     pData,
 554         CK_ULONG_PTR    pulDataLen)
 555 {
 556         CK_RV   rv;
 557         ST_SESSION_T rSession;
 558 
 559         if (API_Initialized() == FALSE) {
 560                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 561         }
 562         if (!Valid_Session((Session_Struct_t *)hSession, &rSession)) {
 563                 return (CKR_SESSION_HANDLE_INVALID);
 564         }
 565         if (FuncList.ST_Decrypt) {
 566                 rv = FuncList.ST_Decrypt(rSession, pEncryptedData,
 567                     ulEncryptedDataLen, pData, pulDataLen);
 568         } else {
 569                 rv = CKR_FUNCTION_NOT_SUPPORTED;
 570         }
 571         return (rv);
 572 }
 573 
 574 CK_RV
 575 C_DecryptDigestUpdate(
 576         CK_SESSION_HANDLE hSession,
 577         CK_BYTE_PTR     pEncryptedPart,
 578         CK_ULONG        ulEncryptedPartLen,
 579         CK_BYTE_PTR     pPart,
 580         CK_ULONG_PTR    pulPartLen)
 581 {
 582         CK_RV   rv;
 583         ST_SESSION_T rSession;
 584 
 585         if (API_Initialized() == FALSE) {
 586                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 587         }
 588         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
 589                 return (CKR_SESSION_HANDLE_INVALID);
 590         }
 591         if (! pEncryptedPart || ! pulPartLen) {
 592                 return (CKR_ARGUMENTS_BAD);
 593         }
 594         if (FuncList.ST_DecryptDigestUpdate) {
 595                 rv = FuncList.ST_DecryptDigestUpdate(rSession, pEncryptedPart,
 596                     ulEncryptedPartLen, pPart, pulPartLen);
 597         } else {
 598                 rv = CKR_FUNCTION_NOT_SUPPORTED;
 599         }
 600         return (rv);
 601 }
 602 
 603 CK_RV
 604 C_DecryptFinal(CK_SESSION_HANDLE hSession,
 605         CK_BYTE_PTR     pLastPart,
 606         CK_ULONG_PTR    pulLastPartLen)
 607 {
 608         CK_RV   rv;
 609         ST_SESSION_T rSession;
 610 
 611         if (API_Initialized() == FALSE) {
 612                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 613         }
 614         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
 615                 return (CKR_SESSION_HANDLE_INVALID);
 616         }
 617         /*
 618          * It is acceptable to have a Null pointer for the data since
 619          * it is trying to get the length of the last part....
 620          * The spec is unclear if a second call to Final is needed
 621          * if there is no data in the last part.
 622          */
 623         if (! pulLastPartLen) {
 624                 return (CKR_ARGUMENTS_BAD);
 625         }
 626         if (FuncList.ST_DecryptFinal) {
 627                 rv = FuncList.ST_DecryptFinal(rSession, pLastPart,
 628                     pulLastPartLen);
 629         } else {
 630                 rv = CKR_FUNCTION_NOT_SUPPORTED;
 631         }
 632         return (rv);
 633 }
 634 
 635 CK_RV
 636 C_DecryptInit(CK_SESSION_HANDLE hSession,
 637         CK_MECHANISM_PTR pMechanism,
 638         CK_OBJECT_HANDLE hKey)
 639 {
 640         CK_RV rv;
 641         ST_SESSION_T rSession;
 642 
 643         if (API_Initialized() == FALSE) {
 644                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 645         }
 646         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
 647                 return (CKR_SESSION_HANDLE_INVALID);
 648         }
 649         if (! pMechanism) {
 650                 return (CKR_MECHANISM_INVALID);
 651         }
 652         if (FuncList.ST_DecryptInit) {
 653                 rv = FuncList.ST_DecryptInit(rSession, pMechanism, hKey);
 654         } else {
 655                 rv = CKR_FUNCTION_NOT_SUPPORTED;
 656         }
 657         return (rv);
 658 }
 659 
 660 CK_RV
 661 C_DecryptUpdate(CK_SESSION_HANDLE hSession,
 662         CK_BYTE_PTR     pEncryptedPart,
 663         CK_ULONG        ulEncryptedPartLen,
 664         CK_BYTE_PTR     pPart,
 665         CK_ULONG_PTR    pulPartLen)
 666 {
 667         CK_RV   rv;
 668         ST_SESSION_T rSession;
 669 
 670         if (API_Initialized() == FALSE) {
 671                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 672         }
 673         if (!Valid_Session((Session_Struct_t *)hSession, &rSession)) {
 674                 return (CKR_SESSION_HANDLE_INVALID);
 675         }
 676         if (!pEncryptedPart || !pulPartLen) {
 677                 return (CKR_ARGUMENTS_BAD);
 678         }
 679         if (FuncList.ST_DecryptUpdate) {
 680                 rv = FuncList.ST_DecryptUpdate(rSession, pEncryptedPart,
 681                     ulEncryptedPartLen, pPart, pulPartLen);
 682         } else {
 683                 rv = CKR_FUNCTION_NOT_SUPPORTED;
 684         }
 685         return (rv);
 686 }
 687 
 688 CK_RV
 689 C_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession,
 690         CK_BYTE_PTR     pEncryptedPart,
 691         CK_ULONG        ulEncryptedPartLen,
 692         CK_BYTE_PTR     pPart,
 693         CK_ULONG_PTR    pulPartLen)
 694 {
 695         CK_RV   rv;
 696         ST_SESSION_T rSession;
 697 
 698         if (API_Initialized() == FALSE) {
 699                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 700         }
 701         // Validate Session
 702         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
 703                 return (CKR_SESSION_HANDLE_INVALID);
 704         }
 705         // May have to let these go through and let the STDLL handle them
 706         if (! pEncryptedPart || ! pulPartLen) {
 707                 return (CKR_ARGUMENTS_BAD);
 708         }
 709         // Get local pointers to session
 710         if (FuncList.ST_DecryptVerifyUpdate) {
 711                 // Map the Session to the slot session
 712                 rv = FuncList.ST_DecryptVerifyUpdate(rSession,
 713                     pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen);
 714         } else {
 715                 rv = CKR_FUNCTION_NOT_SUPPORTED;
 716         }
 717         return (rv);
 718 }
 719 
 720 CK_RV
 721 C_DeriveKey(CK_SESSION_HANDLE   hSession,
 722         CK_MECHANISM_PTR        pMechanism,
 723         CK_OBJECT_HANDLE        hBaseKey,
 724         CK_ATTRIBUTE_PTR        pTemplate,
 725         CK_ULONG                ulAttributeCount,
 726         CK_OBJECT_HANDLE_PTR    phKey)
 727 {
 728         CK_RV   rv;
 729         ST_SESSION_T rSession;
 730 
 731         if (API_Initialized() == FALSE) {
 732                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 733         }
 734         if (!Valid_Session((Session_Struct_t *)hSession, &rSession)) {
 735                 return (CKR_SESSION_HANDLE_INVALID);
 736         }
 737 
 738         if (!pMechanism) {
 739                 return (CKR_MECHANISM_INVALID);
 740         }
 741         if (!pTemplate && ulAttributeCount) {
 742                 return (CKR_ARGUMENTS_BAD);
 743         }
 744         if (FuncList.ST_DeriveKey) {
 745                 rv = FuncList.ST_DeriveKey(rSession, pMechanism,
 746                     hBaseKey, pTemplate, ulAttributeCount, phKey);
 747         } else {
 748                 rv = CKR_FUNCTION_NOT_SUPPORTED;
 749         }
 750         return (rv);
 751 }
 752 
 753 CK_RV
 754 C_DestroyObject(CK_SESSION_HANDLE hSession,
 755         CK_OBJECT_HANDLE hObject)
 756 {
 757         CK_RV rv;
 758         ST_SESSION_T rSession;
 759 
 760         if (API_Initialized() == FALSE) {
 761                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 762         }
 763         if (!Valid_Session((Session_Struct_t *)hSession, &rSession)) {
 764                 return (CKR_SESSION_HANDLE_INVALID);
 765         }
 766         if (FuncList.ST_DestroyObject) {
 767                 rv = FuncList.ST_DestroyObject(rSession, hObject);
 768         } else {
 769                 rv = CKR_FUNCTION_NOT_SUPPORTED;
 770         }
 771         return (rv);
 772 }
 773 
 774 CK_RV
 775 C_Digest(CK_SESSION_HANDLE hSession,
 776         CK_BYTE_PTR     pData,
 777         CK_ULONG        ulDataLen,
 778         CK_BYTE_PTR     pDigest,
 779         CK_ULONG_PTR    pulDigestLen)
 780 {
 781         CK_RV   rv;
 782         ST_SESSION_T rSession;
 783 
 784         if (API_Initialized() == FALSE) {
 785                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 786         }
 787         if (!Valid_Session((Session_Struct_t *)hSession, &rSession)) {
 788                 return (CKR_SESSION_HANDLE_INVALID);
 789         }
 790         if (FuncList.ST_Digest) {
 791                 rv = FuncList.ST_Digest(rSession, pData, ulDataLen,
 792                     pDigest, pulDigestLen);
 793         } else {
 794                 rv = CKR_FUNCTION_NOT_SUPPORTED;
 795         }
 796         return (rv);
 797 }
 798 
 799 CK_RV
 800 C_DigestEncryptUpdate(CK_SESSION_HANDLE hSession,
 801         CK_BYTE_PTR     pPart,
 802         CK_ULONG        ulPartLen,
 803         CK_BYTE_PTR     pEncryptedPart,
 804         CK_ULONG_PTR    pulEncryptedPartLen)
 805 {
 806         CK_RV rv;
 807         ST_SESSION_T rSession;
 808 
 809         if (API_Initialized() == FALSE) {
 810                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 811         }
 812         if (! pPart || ! pulEncryptedPartLen) {
 813                 return (CKR_ARGUMENTS_BAD);
 814         }
 815         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
 816                 return (CKR_SESSION_HANDLE_INVALID);
 817         }
 818         if (FuncList.ST_DigestEncryptUpdate) {
 819                 rv = FuncList.ST_DigestEncryptUpdate(rSession, pPart,
 820                     ulPartLen, pEncryptedPart, pulEncryptedPartLen);
 821         } else {
 822                 rv = CKR_FUNCTION_NOT_SUPPORTED;
 823         }
 824         return (rv);
 825 }
 826 
 827 CK_RV
 828 C_DigestFinal(CK_SESSION_HANDLE hSession,
 829         CK_BYTE_PTR     pDigest,
 830         CK_ULONG_PTR    pulDigestLen)
 831 {
 832         CK_RV rv;
 833         ST_SESSION_T rSession;
 834 
 835         if (API_Initialized() == FALSE) {
 836                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 837         }
 838         if (! pulDigestLen) {
 839                 return (CKR_ARGUMENTS_BAD);
 840         }
 841         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
 842                 return (CKR_SESSION_HANDLE_INVALID);
 843         }
 844         if (FuncList.ST_DigestFinal) {
 845                 rv = FuncList.ST_DigestFinal(rSession, pDigest, pulDigestLen);
 846         } else {
 847                 rv = CKR_FUNCTION_NOT_SUPPORTED;
 848         }
 849         return (rv);
 850 }
 851 
 852 CK_RV
 853 C_DigestInit(CK_SESSION_HANDLE hSession,
 854         CK_MECHANISM_PTR pMechanism)
 855 {
 856         CK_RV rv;
 857         ST_SESSION_T rSession;
 858 
 859         if (API_Initialized() == FALSE) {
 860                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 861         }
 862         if (! pMechanism) {
 863                 return (CKR_MECHANISM_INVALID);
 864         }
 865         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
 866                 return (CKR_SESSION_HANDLE_INVALID);
 867         }
 868         if (FuncList.ST_DigestInit) {
 869                 rv = FuncList.ST_DigestInit(rSession, pMechanism);
 870         } else {
 871                 rv = CKR_FUNCTION_NOT_SUPPORTED;
 872         }
 873         return (rv);
 874 }
 875 
 876 CK_RV
 877 C_DigestKey(CK_SESSION_HANDLE hSession,
 878         CK_OBJECT_HANDLE hKey)
 879 {
 880         CK_RV rv;
 881         ST_SESSION_T rSession;
 882 
 883         if (API_Initialized() == FALSE) {
 884                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 885         }
 886         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
 887                 return (CKR_SESSION_HANDLE_INVALID);
 888         }
 889         if (FuncList.ST_DigestKey) {
 890                 rv = FuncList.ST_DigestKey(rSession, hKey);
 891         } else {
 892                 rv = CKR_FUNCTION_NOT_SUPPORTED;
 893         }
 894         return (rv);
 895 }
 896 
 897 CK_RV
 898 C_DigestUpdate(CK_SESSION_HANDLE hSession,
 899         CK_BYTE_PTR pPart,
 900         CK_ULONG ulPartLen)
 901 {
 902         CK_RV rv;
 903         ST_SESSION_T rSession;
 904         if (API_Initialized() == FALSE) {
 905                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 906         }
 907         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
 908                 return (CKR_SESSION_HANDLE_INVALID);
 909         }
 910         if (FuncList.ST_DigestUpdate) {
 911                 rv = FuncList.ST_DigestUpdate(rSession, pPart, ulPartLen);
 912         } else {
 913                 rv = CKR_FUNCTION_NOT_SUPPORTED;
 914         }
 915         return (rv);
 916 }
 917 
 918 CK_RV
 919 C_Encrypt(CK_SESSION_HANDLE hSession,
 920         CK_BYTE_PTR pData,
 921         CK_ULONG ulDataLen,
 922         CK_BYTE_PTR pEncryptedData,
 923         CK_ULONG_PTR pulEncryptedDataLen)
 924 {
 925         CK_RV rv;
 926         ST_SESSION_T rSession;
 927 
 928         if (API_Initialized() == FALSE) {
 929                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 930         }
 931         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
 932                 return (CKR_SESSION_HANDLE_INVALID);
 933         }
 934         // Get local pointers to session
 935         if (FuncList.ST_Encrypt) {
 936                 // Map the Session to the slot session
 937                 rv = FuncList.ST_Encrypt(rSession, pData, ulDataLen,
 938                     pEncryptedData, pulEncryptedDataLen);
 939         } else {
 940                 rv = CKR_FUNCTION_NOT_SUPPORTED;
 941         }
 942         return (rv);
 943 }
 944 
 945 CK_RV
 946 C_EncryptFinal(CK_SESSION_HANDLE hSession,
 947         CK_BYTE_PTR pLastEncryptedPart,
 948         CK_ULONG_PTR pulLastEncryptedPartLen)
 949 {
 950         CK_RV rv;
 951         ST_SESSION_T rSession;
 952 
 953         if (API_Initialized() == FALSE) {
 954                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 955         }
 956         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
 957                 return (CKR_SESSION_HANDLE_INVALID);
 958         }
 959         if (FuncList.ST_EncryptFinal) {
 960                 rv = FuncList.ST_EncryptFinal(rSession,
 961                     pLastEncryptedPart, pulLastEncryptedPartLen);
 962         } else {
 963                 rv = CKR_FUNCTION_NOT_SUPPORTED;
 964         }
 965         return (rv);
 966 }
 967 
 968 CK_RV
 969 C_EncryptInit(CK_SESSION_HANDLE hSession,
 970         CK_MECHANISM_PTR pMechanism,
 971         CK_OBJECT_HANDLE hKey)
 972 {
 973         CK_RV rv;
 974         ST_SESSION_T rSession;
 975 
 976         if (API_Initialized() == FALSE) {
 977                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
 978         }
 979         if (! pMechanism) {
 980                 return (CKR_MECHANISM_INVALID);
 981         }
 982         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
 983                 return (CKR_SESSION_HANDLE_INVALID);
 984         }
 985         if (FuncList.ST_EncryptInit) {
 986                 rv = FuncList.ST_EncryptInit(rSession, pMechanism, hKey);
 987         } else {
 988                 rv = CKR_FUNCTION_NOT_SUPPORTED;
 989         }
 990         return (rv);
 991 }
 992 
 993 CK_RV
 994 C_EncryptUpdate(CK_SESSION_HANDLE hSession,
 995         CK_BYTE_PTR pPart,
 996         CK_ULONG ulPartLen,
 997         CK_BYTE_PTR pEncryptedPart,
 998         CK_ULONG_PTR pulEncryptedPartLen)
 999 {
1000         CK_RV rv;
1001         ST_SESSION_T rSession;
1002 
1003         if (API_Initialized() == FALSE) {
1004                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1005         }
1006         if (!pPart || !pulEncryptedPartLen) {
1007                 return (CKR_ARGUMENTS_BAD);
1008         }
1009         if (!Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1010                 return (CKR_SESSION_HANDLE_INVALID);
1011         }
1012         if (FuncList.ST_EncryptUpdate) {
1013                 rv = FuncList.ST_EncryptUpdate(rSession, pPart, ulPartLen,
1014                     pEncryptedPart, pulEncryptedPartLen);
1015         } else {
1016                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1017         }
1018         return (rv);
1019 }
1020 
1021 CK_RV
1022 do_finalize(CK_VOID_PTR pReserved)
1023 {
1024         if (API_Initialized() == FALSE) {
1025                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1026         }
1027         if (pReserved != NULL) {
1028                 return (CKR_ARGUMENTS_BAD);
1029         }
1030         (void) pthread_mutex_lock(&global_mutex);
1031         if (Anchor)
1032                 Terminate_All_Process_Sessions();
1033 
1034         if (FuncList.ST_Finalize)
1035                 FuncList.ST_Finalize(0);
1036 
1037         free(Anchor);
1038         Anchor = NULL;
1039 
1040         (void) pthread_mutex_unlock(&global_mutex);
1041         return (CKR_OK);
1042 }
1043 
1044 CK_RV
1045 C_Finalize(CK_VOID_PTR pReserved) {
1046         return (do_finalize(pReserved));
1047 }
1048 
1049 CK_RV
1050 C_FindObjects(CK_SESSION_HANDLE    hSession,
1051         CK_OBJECT_HANDLE_PTR phObject,
1052         CK_ULONG ulMaxObjectCount,
1053         CK_ULONG_PTR pulObjectCount)
1054 {
1055         CK_RV rv;
1056         ST_SESSION_T rSession;
1057 
1058         if (API_Initialized() == FALSE) {
1059                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1060         }
1061         if (! phObject || ! pulObjectCount) {
1062                 return (CKR_ARGUMENTS_BAD);
1063         }
1064         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1065                 return (CKR_SESSION_HANDLE_INVALID);
1066         }
1067         if (FuncList.ST_FindObjects) {
1068                 rv = FuncList.ST_FindObjects(rSession, phObject,
1069                     ulMaxObjectCount, pulObjectCount);
1070         } else {
1071                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1072         }
1073         return (rv);
1074 }
1075 
1076 CK_RV
1077 C_FindObjectsFinal(CK_SESSION_HANDLE hSession)
1078 {
1079         CK_RV rv;
1080         ST_SESSION_T rSession;
1081 
1082         if (API_Initialized() == FALSE) {
1083                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1084         }
1085         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1086                 return (CKR_SESSION_HANDLE_INVALID);
1087         }
1088         if (FuncList.ST_FindObjectsFinal) {
1089                 rv = FuncList.ST_FindObjectsFinal(rSession);
1090         } else {
1091                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1092         }
1093         return (rv);
1094 }
1095 
1096 CK_RV
1097 C_FindObjectsInit(CK_SESSION_HANDLE hSession,
1098         CK_ATTRIBUTE_PTR pTemplate,
1099         CK_ULONG ulCount)
1100 {
1101         CK_RV rv;
1102         ST_SESSION_T rSession;
1103 
1104         if (API_Initialized() == FALSE) {
1105                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1106         }
1107         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1108                 return (CKR_SESSION_HANDLE_INVALID);
1109         }
1110         if (FuncList.ST_FindObjectsInit) {
1111                 rv = FuncList.ST_FindObjectsInit(rSession, pTemplate, ulCount);
1112         } else {
1113                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1114         }
1115         return (rv);
1116 }
1117 
1118 CK_RV
1119 C_GenerateKey(CK_SESSION_HANDLE    hSession,
1120         CK_MECHANISM_PTR pMechanism,
1121         CK_ATTRIBUTE_PTR pTemplate,
1122         CK_ULONG ulCount,
1123         CK_OBJECT_HANDLE_PTR phKey)
1124 {
1125         CK_RV rv;
1126         ST_SESSION_T rSession;
1127 
1128         if (API_Initialized() == FALSE) {
1129                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1130         }
1131         if (! pMechanism) {
1132                 return (CKR_MECHANISM_INVALID);
1133         }
1134         if (! phKey) {
1135                 return (CKR_ARGUMENTS_BAD);
1136         }
1137         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1138                 return (CKR_SESSION_HANDLE_INVALID);
1139         }
1140         if (FuncList.ST_GenerateKey) {
1141                 rv = FuncList.ST_GenerateKey(rSession, pMechanism,
1142                     pTemplate, ulCount, phKey);
1143         } else {
1144                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1145         }
1146         return (rv);
1147 }
1148 
1149 CK_RV
1150 C_GenerateKeyPair(CK_SESSION_HANDLE    hSession,
1151         CK_MECHANISM_PTR pMechanism,
1152         CK_ATTRIBUTE_PTR pPublicKeyTemplate,
1153         CK_ULONG ulPublicKeyAttributeCount,
1154         CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
1155         CK_ULONG ulPrivateKeyAttributeCount,
1156         CK_OBJECT_HANDLE_PTR phPublicKey,
1157         CK_OBJECT_HANDLE_PTR phPrivateKey)
1158 {
1159         CK_RV rv;
1160         ST_SESSION_T rSession;
1161 
1162         if (API_Initialized() == FALSE) {
1163                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1164         }
1165         if (! pMechanism) {
1166                 return (CKR_MECHANISM_INVALID);
1167         }
1168         if (! phPublicKey || ! phPrivateKey) {
1169                 return (CKR_ARGUMENTS_BAD);
1170         }
1171         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1172                 return (CKR_SESSION_HANDLE_INVALID);
1173         }
1174         if (FuncList.ST_GenerateKeyPair) {
1175                 rv = FuncList.ST_GenerateKeyPair(rSession,
1176                     pMechanism, pPublicKeyTemplate,
1177                     ulPublicKeyAttributeCount, pPrivateKeyTemplate,
1178                     ulPrivateKeyAttributeCount, phPublicKey, phPrivateKey);
1179         } else {
1180                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1181         }
1182         return (rv);
1183 }
1184 
1185 CK_RV
1186 C_GenerateRandom(CK_SESSION_HANDLE hSession,
1187         CK_BYTE_PTR RandomData,
1188         CK_ULONG ulRandomLen)
1189 {
1190         CK_RV rv;
1191         ST_SESSION_T rSession;
1192 
1193         if (API_Initialized() == FALSE) {
1194                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1195         }
1196         if (! RandomData)
1197                 return (CKR_ARGUMENTS_BAD);
1198 
1199         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1200                 return (CKR_SESSION_HANDLE_INVALID);
1201         }
1202         if (FuncList.ST_GenerateRandom) {
1203                 rv = FuncList.ST_GenerateRandom(rSession, RandomData,
1204                     ulRandomLen);
1205         } else {
1206                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1207         }
1208         return (rv);
1209 }
1210 
1211 CK_RV
1212 C_GetAttributeValue(CK_SESSION_HANDLE hSession,
1213         CK_OBJECT_HANDLE hObject,
1214         CK_ATTRIBUTE_PTR pTemplate,
1215         CK_ULONG ulCount)
1216 {
1217         CK_RV rv;
1218         ST_SESSION_T rSession;
1219 
1220         if (API_Initialized() == FALSE) {
1221                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1222         }
1223         if (! pTemplate) {
1224                 return (CKR_TEMPLATE_INCOMPLETE);
1225         }
1226         if (ulCount == 0) {
1227                 return (CKR_TEMPLATE_INCOMPLETE);
1228         }
1229         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1230                 return (CKR_SESSION_HANDLE_INVALID);
1231         }
1232         if (FuncList.ST_GetAttributeValue) {
1233                 rv = FuncList.ST_GetAttributeValue(rSession, hObject,
1234                     pTemplate, ulCount);
1235         } else {
1236                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1237         }
1238         return (rv);
1239 }
1240 
1241 CK_RV
1242 C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)
1243 {
1244         _init();
1245 
1246         PK11_Functions.version.major = VERSION_MAJOR;
1247         PK11_Functions.version.minor = VERSION_MINOR;
1248         PK11_Functions.C_Initialize = C_Initialize;
1249         PK11_Functions.C_Finalize = C_Finalize;
1250         PK11_Functions.C_GetInfo = C_GetInfo;
1251         PK11_Functions.C_GetFunctionList = C_GetFunctionList;
1252         PK11_Functions.C_GetSlotList = C_GetSlotList;
1253         PK11_Functions.C_GetSlotInfo = C_GetSlotInfo;
1254         PK11_Functions.C_GetTokenInfo = C_GetTokenInfo;
1255         PK11_Functions.C_GetMechanismList = C_GetMechanismList;
1256         PK11_Functions.C_GetMechanismInfo = C_GetMechanismInfo;
1257         PK11_Functions.C_InitToken = C_InitToken;
1258         PK11_Functions.C_InitPIN = C_InitPIN;
1259         PK11_Functions.C_SetPIN = C_SetPIN;
1260         PK11_Functions.C_OpenSession = C_OpenSession;
1261         PK11_Functions.C_CloseSession = C_CloseSession;
1262         PK11_Functions.C_CloseAllSessions = C_CloseAllSessions;
1263         PK11_Functions.C_GetSessionInfo = C_GetSessionInfo;
1264         PK11_Functions.C_GetOperationState = C_GetOperationState;
1265         PK11_Functions.C_SetOperationState = C_SetOperationState;
1266         PK11_Functions.C_Login = C_Login;
1267         PK11_Functions.C_Logout = C_Logout;
1268         PK11_Functions.C_CreateObject = C_CreateObject;
1269         PK11_Functions.C_CopyObject = C_CopyObject;
1270         PK11_Functions.C_DestroyObject = C_DestroyObject;
1271         PK11_Functions.C_GetObjectSize = C_GetObjectSize;
1272         PK11_Functions.C_GetAttributeValue = C_GetAttributeValue;
1273         PK11_Functions.C_SetAttributeValue = C_SetAttributeValue;
1274         PK11_Functions.C_FindObjectsInit = C_FindObjectsInit;
1275         PK11_Functions.C_FindObjects = C_FindObjects;
1276         PK11_Functions.C_FindObjectsFinal = C_FindObjectsFinal;
1277         PK11_Functions.C_EncryptInit = C_EncryptInit;
1278         PK11_Functions.C_Encrypt = C_Encrypt;
1279         PK11_Functions.C_EncryptUpdate = C_EncryptUpdate;
1280         PK11_Functions.C_EncryptFinal = C_EncryptFinal;
1281         PK11_Functions.C_DecryptInit = C_DecryptInit;
1282         PK11_Functions.C_Decrypt = C_Decrypt;
1283         PK11_Functions.C_DecryptUpdate = C_DecryptUpdate;
1284         PK11_Functions.C_DecryptFinal = C_DecryptFinal;
1285         PK11_Functions.C_DigestInit = C_DigestInit;
1286         PK11_Functions.C_Digest = C_Digest;
1287         PK11_Functions.C_DigestUpdate = C_DigestUpdate;
1288         PK11_Functions.C_DigestKey = C_DigestKey;
1289         PK11_Functions.C_DigestFinal = C_DigestFinal;
1290         PK11_Functions.C_SignInit = C_SignInit;
1291         PK11_Functions.C_Sign = C_Sign;
1292         PK11_Functions.C_SignUpdate = C_SignUpdate;
1293         PK11_Functions.C_SignFinal = C_SignFinal;
1294         PK11_Functions.C_SignRecoverInit = C_SignRecoverInit;
1295         PK11_Functions.C_SignRecover = C_SignRecover;
1296         PK11_Functions.C_VerifyInit = C_VerifyInit;
1297         PK11_Functions.C_Verify = C_Verify;
1298         PK11_Functions.C_VerifyUpdate = C_VerifyUpdate;
1299         PK11_Functions.C_VerifyFinal = C_VerifyFinal;
1300         PK11_Functions.C_VerifyRecoverInit = C_VerifyRecoverInit;
1301         PK11_Functions.C_VerifyRecover = C_VerifyRecover;
1302         PK11_Functions.C_DigestEncryptUpdate = C_DigestEncryptUpdate;
1303         PK11_Functions.C_DecryptDigestUpdate = C_DecryptDigestUpdate;
1304         PK11_Functions.C_SignEncryptUpdate = C_SignEncryptUpdate;
1305         PK11_Functions.C_DecryptVerifyUpdate = C_DecryptVerifyUpdate;
1306         PK11_Functions.C_GenerateKey = C_GenerateKey;
1307         PK11_Functions.C_GenerateKeyPair = C_GenerateKeyPair;
1308         PK11_Functions.C_WrapKey = C_WrapKey;
1309         PK11_Functions.C_UnwrapKey = C_UnwrapKey;
1310         PK11_Functions.C_DeriveKey = C_DeriveKey;
1311         PK11_Functions.C_SeedRandom = C_SeedRandom;
1312         PK11_Functions.C_GenerateRandom = C_GenerateRandom;
1313         PK11_Functions.C_GetFunctionStatus = C_GetFunctionStatus;
1314         PK11_Functions.C_CancelFunction = C_CancelFunction;
1315         PK11_Functions.C_WaitForSlotEvent = C_WaitForSlotEvent;
1316         if (ppFunctionList) {
1317                 (*ppFunctionList) = &PK11_Functions;
1318                 return (CKR_OK);
1319         } else {
1320                 return (CKR_ARGUMENTS_BAD);
1321         }
1322 }
1323 
1324 /*ARGSUSED*/
1325 CK_RV
1326 C_GetFunctionStatus(CK_SESSION_HANDLE hSession)
1327 {
1328         if (API_Initialized() == FALSE) {
1329                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1330         }
1331         return (CKR_FUNCTION_NOT_PARALLEL); // PER Specification PG 170
1332 }
1333 
1334 CK_RV
1335 C_GetInfo(CK_INFO_PTR pInfo)
1336 {
1337         TOKEN_DATA td;
1338         TSS_HCONTEXT hContext;
1339 
1340         if (! API_Initialized()) {
1341                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1342         }
1343         if (! pInfo) {
1344                 return (CKR_FUNCTION_FAILED);
1345         }
1346         (void) memset(pInfo, 0, sizeof (*pInfo));
1347         pInfo->cryptokiVersion.major = 2;
1348         pInfo->cryptokiVersion.minor = 20;
1349 
1350         if (open_tss_context(&hContext) == 0) {
1351                 /*
1352                  * Only populate the TPM info if we can establish
1353                  * a context, but don't return failure because
1354                  * the framework needs to know some of the info.
1355                  */
1356                 (void) token_get_tpm_info(hContext, &td);
1357 
1358                 (void) Tspi_Context_Close(hContext);
1359 
1360                 (void) memcpy(pInfo->manufacturerID,
1361                     &(td.token_info.manufacturerID),
1362                     sizeof (pInfo->manufacturerID) - 1);
1363 
1364                 pInfo->flags = td.token_info.flags;
1365         }
1366         (void) strcpy((char *)pInfo->libraryDescription,
1367             "PKCS11 Interface for TPM");
1368 
1369         pInfo->libraryVersion.major = 1;
1370         pInfo->libraryVersion.minor = 0;
1371 
1372         return (CKR_OK);
1373 }
1374 
1375 CK_RV
1376 C_GetMechanismInfo(CK_SLOT_ID   slotID,
1377         CK_MECHANISM_TYPE       type,
1378         CK_MECHANISM_INFO_PTR   pInfo)
1379 {
1380         CK_RV rv;
1381         if (API_Initialized() == FALSE)
1382                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1383 
1384         if (!global_shm->token_available || (slotID > NUMBER_SLOTS_MANAGED))
1385                 return (CKR_SLOT_ID_INVALID);
1386 
1387         if (FuncList.ST_GetMechanismInfo) {
1388                 rv = FuncList.ST_GetMechanismInfo(slotID, type, pInfo);
1389         } else {
1390                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1391         }
1392         return (rv);
1393 }
1394 
1395 CK_RV
1396 C_GetMechanismList(CK_SLOT_ID slotID,
1397         CK_MECHANISM_TYPE_PTR pMechanismList,
1398         CK_ULONG_PTR pulCount)
1399 {
1400         CK_RV rv;
1401 
1402         if (API_Initialized() == FALSE)
1403                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1404 
1405         if (! pulCount)
1406                 return (CKR_ARGUMENTS_BAD);
1407 
1408         if (!global_shm->token_available || (slotID > NUMBER_SLOTS_MANAGED))
1409                 return (CKR_SLOT_ID_INVALID);
1410 
1411         if (FuncList.ST_GetMechanismList) {
1412                 rv = FuncList.ST_GetMechanismList(slotID,
1413                     pMechanismList, pulCount);
1414         } else {
1415                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1416         }
1417         if (rv == CKR_OK) {
1418                 if (pMechanismList) {
1419                         unsigned long i;
1420                         for (i = 0; i < *pulCount; i++) {
1421                                 logit(LOG_DEBUG, "Mechanism[%d] 0x%08X ",
1422                                     i, pMechanismList[i]);
1423                         }
1424                 }
1425         }
1426         return (rv);
1427 }
1428 
1429 CK_RV
1430 C_GetObjectSize(CK_SESSION_HANDLE hSession,
1431         CK_OBJECT_HANDLE hObject,
1432         CK_ULONG_PTR pulSize)
1433 {
1434         CK_RV rv;
1435         ST_SESSION_T rSession;
1436 
1437         if (API_Initialized() == FALSE) {
1438                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1439         }
1440         if (! pulSize) {
1441                 return (CKR_ARGUMENTS_BAD);
1442         }
1443         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1444                 return (CKR_SESSION_HANDLE_INVALID);
1445         }
1446         if (FuncList.ST_GetObjectSize) {
1447                 rv = FuncList.ST_GetObjectSize(rSession, hObject, pulSize);
1448         } else {
1449                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1450         }
1451         return (rv);
1452 }
1453 
1454 CK_RV
1455 C_GetOperationState(CK_SESSION_HANDLE hSession,
1456         CK_BYTE_PTR pOperationState,
1457         CK_ULONG_PTR pulOperationStateLen)
1458 {
1459         CK_RV rv;
1460         ST_SESSION_T rSession;
1461 
1462         if (API_Initialized() == FALSE) {
1463                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1464         }
1465         if (! pulOperationStateLen) {
1466                 return (CKR_ARGUMENTS_BAD);
1467         }
1468         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1469                 return (CKR_SESSION_HANDLE_INVALID);
1470         }
1471         if (FuncList.ST_GetOperationState) {
1472                 rv = FuncList.ST_GetOperationState(rSession,
1473                     pOperationState, pulOperationStateLen);
1474         } else {
1475                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1476         }
1477         return (rv);
1478 }
1479 
1480 CK_RV
1481 C_GetSessionInfo(CK_SESSION_HANDLE hSession,
1482         CK_SESSION_INFO_PTR pInfo)
1483 {
1484         CK_RV rv;
1485         ST_SESSION_T rSession;
1486 
1487         if (API_Initialized() == FALSE) {
1488                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1489         }
1490         if (! pInfo) {
1491                 return (CKR_ARGUMENTS_BAD);
1492         }
1493         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1494                 return (CKR_SESSION_HANDLE_INVALID);
1495         }
1496         if (FuncList.ST_GetSessionInfo) {
1497                 rv = FuncList.ST_GetSessionInfo(rSession, pInfo);
1498         } else {
1499                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1500         }
1501         return (rv);
1502 }
1503 
1504 CK_RV
1505 C_GetSlotInfo(CK_SLOT_ID slotID,
1506         CK_SLOT_INFO_PTR pInfo)
1507 {
1508         if (API_Initialized() == FALSE)
1509                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1510 
1511         if (!pInfo)
1512                 return (CKR_FUNCTION_FAILED);
1513 
1514         if (!global_shm->token_available || (slotID > NUMBER_SLOTS_MANAGED))
1515                 return (CKR_SLOT_ID_INVALID);
1516 
1517         copy_slot_info(slotID, pInfo);
1518         return (CKR_OK);
1519 }
1520 
1521 /*ARGSUSED*/
1522 CK_RV
1523 C_GetSlotList(CK_BBOOL tokenPresent,
1524         CK_SLOT_ID_PTR pSlotList,
1525         CK_ULONG_PTR pulCount)
1526 {
1527         CK_ULONG count;
1528         CK_SLOT_INFO slotInfo;
1529 
1530         if (API_Initialized() == FALSE)
1531                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1532 
1533         if (pulCount == NULL)
1534                 return (CKR_FUNCTION_FAILED);
1535 
1536         count = 0;
1537         /*
1538          * If we can't talk to the TPM, present no slots
1539          */
1540         if (!global_shm->token_available) {
1541                 *pulCount = 0;
1542                 return (CKR_OK);
1543         }
1544 
1545         copy_slot_info(TPM_SLOTID, &slotInfo);
1546         if ((slotInfo.flags & CKF_TOKEN_PRESENT))
1547                 count++;
1548 
1549         *pulCount = count;
1550 
1551         if (pSlotList == NULL) {
1552                 return (CKR_OK);
1553         } else {
1554                 if (*pulCount < count)
1555                         return (CKR_BUFFER_TOO_SMALL);
1556                 pSlotList[0] = TPM_SLOTID;
1557         }
1558         return (CKR_OK);
1559 }
1560 
1561 CK_RV
1562 C_GetTokenInfo(CK_SLOT_ID slotID,
1563         CK_TOKEN_INFO_PTR pInfo)
1564 {
1565         CK_RV rv;
1566 
1567         if (API_Initialized() == FALSE)
1568                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1569 
1570         if (!pInfo)
1571                 return (CKR_ARGUMENTS_BAD);
1572 
1573         if (!global_shm->token_available || (slotID > NUMBER_SLOTS_MANAGED))
1574                 return (CKR_SLOT_ID_INVALID);
1575 
1576         slotID = TPM_SLOTID;
1577         if (FuncList.ST_GetTokenInfo) {
1578                 rv = FuncList.ST_GetTokenInfo(slotID, pInfo);
1579         } else {
1580                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1581         }
1582         return (rv);
1583 }
1584 
1585 CK_RV
1586 C_Initialize(CK_VOID_PTR pVoid)
1587 {
1588         CK_RV rv = CKR_OK;
1589         CK_C_INITIALIZE_ARGS *pArg;
1590         extern CK_RV ST_Initialize(void *,
1591             CK_SLOT_ID, unsigned char *);
1592 
1593         (void) pthread_mutex_lock(&global_mutex);
1594         if (! Anchor) {
1595                 Anchor = (API_Proc_Struct_t *)malloc(
1596                     sizeof (API_Proc_Struct_t));
1597                 if (Anchor == NULL) {
1598                         (void) pthread_mutex_unlock(&global_mutex);
1599                         return (CKR_HOST_MEMORY);
1600                 }
1601         } else {
1602                 (void) pthread_mutex_unlock(&global_mutex);
1603                 return (CKR_CRYPTOKI_ALREADY_INITIALIZED);
1604         }
1605         /*
1606          * if pVoid is NULL, then everything is OK.  The applicaiton
1607          * will not be doing multi thread accesses.  We can use the OS
1608          * locks anyhow.
1609          */
1610         if (pVoid != NULL) {
1611                 int supplied_ok;
1612                 pArg = (CK_C_INITIALIZE_ARGS *)pVoid;
1613 
1614                 /*
1615                  * ALL supplied function pointers need to have the value
1616                  * either NULL or no - NULL.
1617                  */
1618                 supplied_ok = (pArg->CreateMutex == NULL &&
1619                     pArg->DestroyMutex == NULL &&
1620                     pArg->LockMutex == NULL &&
1621                     pArg->UnlockMutex == NULL) ||
1622                     (pArg->CreateMutex != NULL &&
1623                     pArg->DestroyMutex != NULL &&
1624                     pArg->LockMutex != NULL &&
1625                     pArg->UnlockMutex != NULL);
1626 
1627                 if (!supplied_ok) {
1628                         (void) pthread_mutex_unlock(&global_mutex);
1629                         return (CKR_ARGUMENTS_BAD);
1630                 }
1631                 /* Check for a pReserved set */
1632                 if (pArg->pReserved != NULL) {
1633                         free(Anchor);
1634                         Anchor = NULL;
1635                         (void) pthread_mutex_unlock(&global_mutex);
1636                         return (CKR_ARGUMENTS_BAD);
1637                 }
1638                 /*
1639                  * When the CKF_OS_LOCKING_OK flag isn't set and mutex
1640                  * function pointers are supplied by an application,
1641                  * return (an error.  We must be able to use our own primitives.
1642                  */
1643                 if (!(pArg->flags & CKF_OS_LOCKING_OK) &&
1644                     (pArg->CreateMutex != NULL)) {
1645                         (void) pthread_mutex_unlock(&global_mutex);
1646                         return (CKR_CANT_LOCK);
1647                 }
1648         }
1649         (void) memset((char *)Anchor, 0, sizeof (API_Proc_Struct_t));
1650         (void) pthread_mutex_init(&(Anchor->ProcMutex), NULL);
1651         (void) pthread_mutex_init(&(Anchor->SessListMutex), NULL);
1652         Anchor->Pid = getpid();
1653 
1654         rv = ST_Initialize((void *)&FuncList, 0, NULL);
1655         (void) pthread_mutex_unlock(&global_mutex);
1656         return (rv);
1657 }
1658 
1659 CK_RV
1660 C_InitPIN(CK_SESSION_HANDLE hSession,
1661         CK_CHAR_PTR pPin,
1662         CK_ULONG ulPinLen)
1663 {
1664         CK_RV rv;
1665         ST_SESSION_T rSession;
1666 
1667         if (API_Initialized() == FALSE)
1668                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1669 
1670         if (! pPin && ulPinLen)
1671                 return (CKR_ARGUMENTS_BAD);
1672 
1673         if (! Valid_Session((Session_Struct_t *)hSession, &rSession))
1674                 return (CKR_SESSION_HANDLE_INVALID);
1675 
1676         if (rSession.slotID > NUMBER_SLOTS_MANAGED)
1677                 return (CKR_SLOT_ID_INVALID);
1678 
1679         if (FuncList.ST_InitPIN)
1680                 rv = FuncList.ST_InitPIN(rSession, pPin, ulPinLen);
1681         else
1682                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1683 
1684         return (rv);
1685 }
1686 
1687 CK_RV
1688 C_InitToken(CK_SLOT_ID  slotID,
1689         CK_CHAR_PTR pPin,
1690         CK_ULONG    ulPinLen,
1691         CK_CHAR_PTR pLabel)
1692 {
1693         CK_RV rv;
1694 
1695         if (API_Initialized() == FALSE)
1696                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1697 
1698         if (! pPin && ulPinLen)
1699                 return (CKR_ARGUMENTS_BAD);
1700 
1701         if (! pLabel)
1702                 return (CKR_ARGUMENTS_BAD);
1703 
1704         if (!global_shm->token_available)
1705                 return (CKR_SLOT_ID_INVALID);
1706 
1707         if (FuncList.ST_InitToken)
1708                 rv = FuncList.ST_InitToken(slotID, pPin, ulPinLen, pLabel);
1709         else
1710                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1711 
1712         return (rv);
1713 }
1714 
1715 CK_RV
1716 C_Login(CK_SESSION_HANDLE hSession,
1717         CK_USER_TYPE userType,
1718         CK_CHAR_PTR pPin,
1719         CK_ULONG ulPinLen)
1720 {
1721         CK_RV rv;
1722         ST_SESSION_T rSession;
1723 
1724         if (API_Initialized() == FALSE) {
1725                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1726         }
1727         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1728                 return (CKR_SESSION_HANDLE_INVALID);
1729         }
1730         if (FuncList.ST_Login) {
1731                 rv = FuncList.ST_Login(rSession, userType, pPin, ulPinLen);
1732         } else {
1733                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1734         }
1735         return (rv);
1736 }
1737 
1738 CK_RV
1739 C_Logout(CK_SESSION_HANDLE hSession)
1740 {
1741         CK_RV rv;
1742         ST_SESSION_T rSession;
1743 
1744         if (API_Initialized() == FALSE) {
1745                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1746         }
1747         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1748                 return (CKR_SESSION_HANDLE_INVALID);
1749         }
1750         if (FuncList.ST_Logout) {
1751                 rv = FuncList.ST_Logout(rSession);
1752         } else {
1753                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1754         }
1755         return (rv);
1756 }
1757 
1758 /*ARGSUSED*/
1759 CK_RV
1760 C_OpenSession(
1761         CK_SLOT_ID slotID,
1762         CK_FLAGS flags,
1763         CK_VOID_PTR pApplication,
1764         CK_NOTIFY Notify,
1765         CK_SESSION_HANDLE_PTR phSession)
1766 {
1767         CK_RV rv;
1768         Session_Struct_t  *apiSessp;
1769 
1770         if (API_Initialized() == FALSE)
1771                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1772 
1773         if (!global_shm->token_available || (slotID > NUMBER_SLOTS_MANAGED))
1774                 return (CKR_SLOT_ID_INVALID);
1775 
1776         if (! phSession)
1777                 return (CKR_FUNCTION_FAILED);
1778 
1779         if ((flags & CKF_SERIAL_SESSION) == 0)
1780                 return (CKR_SESSION_PARALLEL_NOT_SUPPORTED);
1781 
1782         if ((apiSessp = (Session_Struct_t *)malloc(
1783             sizeof (Session_Struct_t))) == NULL)
1784                 return (CKR_HOST_MEMORY);
1785 
1786         if (FuncList.ST_OpenSession) {
1787                 rv = FuncList.ST_OpenSession(slotID, flags,
1788                     &(apiSessp->RealHandle));
1789 
1790                 if (rv == CKR_OK) {
1791                         *phSession = (CK_SESSION_HANDLE)apiSessp;
1792                         apiSessp->SltId = slotID;
1793 
1794                         AddToSessionList(apiSessp);
1795                 } else {
1796                         free(apiSessp);
1797                 }
1798         } else {
1799                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1800         }
1801         return (rv);
1802 }
1803 
1804 CK_RV
1805 C_SeedRandom(CK_SESSION_HANDLE hSession,
1806         CK_BYTE_PTR pSeed,
1807         CK_ULONG ulSeedLen)
1808 {
1809         CK_RV rv;
1810         ST_SESSION_T rSession;
1811 
1812         if (API_Initialized() == FALSE) {
1813                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1814         }
1815         if (! pSeed && ulSeedLen) {
1816                 return (CKR_ARGUMENTS_BAD);
1817         }
1818         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1819                 return (CKR_SESSION_HANDLE_INVALID);
1820         }
1821         if (FuncList.ST_SeedRandom) {
1822                 rv = FuncList.ST_SeedRandom(rSession, pSeed, ulSeedLen);
1823         } else {
1824                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1825         }
1826         return (rv);
1827 }
1828 
1829 CK_RV
1830 C_SetAttributeValue(CK_SESSION_HANDLE hSession,
1831         CK_OBJECT_HANDLE hObject,
1832         CK_ATTRIBUTE_PTR pTemplate,
1833         CK_ULONG ulCount)
1834 {
1835         CK_RV rv;
1836         ST_SESSION_T rSession;
1837 
1838         if (API_Initialized() == FALSE) {
1839                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1840         }
1841         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1842                 return (CKR_SESSION_HANDLE_INVALID);
1843         }
1844         if (! pTemplate) {
1845                 return (CKR_TEMPLATE_INCOMPLETE);
1846         }
1847         if (! ulCount) {
1848                 return (CKR_TEMPLATE_INCOMPLETE);
1849         }
1850         // Get local pointers to session
1851         if (FuncList.ST_SetAttributeValue) {
1852                 rv = FuncList.ST_SetAttributeValue(rSession, hObject,
1853                     pTemplate, ulCount);
1854         } else {
1855                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1856         }
1857         return (rv);
1858 }
1859 
1860 CK_RV
1861 C_SetOperationState(CK_SESSION_HANDLE hSession,
1862         CK_BYTE_PTR pOperationState,
1863         CK_ULONG ulOperationStateLen,
1864         CK_OBJECT_HANDLE hEncryptionKey,
1865         CK_OBJECT_HANDLE hAuthenticationKey)
1866 {
1867         CK_RV rv;
1868         ST_SESSION_T rSession;
1869 
1870         if (API_Initialized() == FALSE) {
1871                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1872         }
1873         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1874                 return (CKR_SESSION_HANDLE_INVALID);
1875         }
1876         if (! pOperationState || ulOperationStateLen == 0) {
1877                 return (CKR_ARGUMENTS_BAD);
1878         }
1879         if (FuncList.ST_SetOperationState) {
1880                 rv = FuncList.ST_SetOperationState(rSession, pOperationState,
1881                     ulOperationStateLen, hEncryptionKey, hAuthenticationKey);
1882         } else {
1883                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1884         }
1885         return (rv);
1886 }
1887 
1888 CK_RV
1889 C_SetPIN(CK_SESSION_HANDLE hSession,
1890         CK_CHAR_PTR pOldPin,
1891         CK_ULONG ulOldLen,
1892         CK_CHAR_PTR pNewPin,
1893         CK_ULONG ulNewLen)
1894 {
1895         CK_RV rv;
1896         ST_SESSION_T rSession;
1897 
1898         if (API_Initialized() == FALSE) {
1899                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1900         }
1901         if (! pOldPin || ! pNewPin)
1902                 return (CKR_PIN_INVALID);
1903         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1904                 return (CKR_SESSION_HANDLE_INVALID);
1905         }
1906         if (FuncList.ST_SetPIN) {
1907                 rv = FuncList.ST_SetPIN(rSession, pOldPin, ulOldLen,
1908                     pNewPin, ulNewLen);
1909         } else {
1910                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1911         }
1912         return (rv);
1913 }
1914 
1915 CK_RV
1916 C_Sign(CK_SESSION_HANDLE hSession,
1917         CK_BYTE_PTR pData,
1918         CK_ULONG ulDataLen,
1919         CK_BYTE_PTR pSignature,
1920         CK_ULONG_PTR pulSignatureLen)
1921 {
1922         CK_RV rv;
1923         ST_SESSION_T rSession;
1924 
1925         if (API_Initialized() == FALSE) {
1926                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1927         }
1928         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1929                 return (CKR_SESSION_HANDLE_INVALID);
1930         }
1931         if (FuncList.ST_Sign) {
1932                 rv = FuncList.ST_Sign(rSession, pData, ulDataLen,
1933                     pSignature, pulSignatureLen);
1934         } else {
1935                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1936         }
1937         return (rv);
1938 }
1939 
1940 CK_RV
1941 C_SignEncryptUpdate(CK_SESSION_HANDLE hSession,
1942         CK_BYTE_PTR pPart,
1943         CK_ULONG ulPartLen,
1944         CK_BYTE_PTR pEncryptedPart,
1945         CK_ULONG_PTR pulEncryptedPartLen)
1946 {
1947         CK_RV rv;
1948         ST_SESSION_T rSession;
1949         if (API_Initialized() == FALSE) {
1950                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1951         }
1952         if (! pPart || ! pulEncryptedPartLen) {
1953                 return (CKR_ARGUMENTS_BAD);
1954         }
1955         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1956                 return (CKR_SESSION_HANDLE_INVALID);
1957         }
1958         if (FuncList.ST_SignEncryptUpdate) {
1959                 rv = FuncList.ST_SignEncryptUpdate(rSession, pPart,
1960                     ulPartLen, pEncryptedPart, pulEncryptedPartLen);
1961         } else {
1962                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1963         }
1964         return (rv);
1965 }
1966 
1967 CK_RV
1968 C_SignFinal(CK_SESSION_HANDLE hSession,
1969         CK_BYTE_PTR pSignature,
1970         CK_ULONG_PTR pulSignatureLen)
1971 {
1972         CK_RV rv;
1973         ST_SESSION_T rSession;
1974 
1975         if (API_Initialized() == FALSE) {
1976                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1977         }
1978         if (! pulSignatureLen) {
1979                 return (CKR_ARGUMENTS_BAD);
1980         }
1981         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1982                 return (CKR_SESSION_HANDLE_INVALID);
1983         }
1984         if (FuncList.ST_SignFinal) {
1985                 rv = FuncList.ST_SignFinal(rSession, pSignature,
1986                     pulSignatureLen);
1987         } else {
1988                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1989         }
1990         return (rv);
1991 }
1992 
1993 CK_RV
1994 C_SignInit(CK_SESSION_HANDLE hSession,
1995         CK_MECHANISM_PTR pMechanism,
1996         CK_OBJECT_HANDLE hKey)
1997 {
1998         CK_RV rv;
1999         ST_SESSION_T rSession;
2000 
2001         if (API_Initialized() == FALSE) {
2002                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2003         }
2004         if (! pMechanism) {
2005                 return (CKR_MECHANISM_INVALID);
2006         }
2007         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2008                 return (CKR_SESSION_HANDLE_INVALID);
2009         }
2010         if (FuncList.ST_SignInit) {
2011                 rv = FuncList.ST_SignInit(rSession, pMechanism, hKey);
2012         } else {
2013                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2014         }
2015         return (rv);
2016 }
2017 
2018 CK_RV
2019 C_SignRecover(CK_SESSION_HANDLE hSession,
2020         CK_BYTE_PTR pData,
2021         CK_ULONG ulDataLen,
2022         CK_BYTE_PTR pSignature,
2023         CK_ULONG_PTR pulSignatureLen)
2024 {
2025         CK_RV rv;
2026         ST_SESSION_T rSession;
2027 
2028         if (API_Initialized() == FALSE) {
2029                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2030         }
2031         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2032                 return (CKR_SESSION_HANDLE_INVALID);
2033         }
2034         if (FuncList.ST_SignRecover) {
2035                 rv = FuncList.ST_SignRecover(rSession, pData,
2036                     ulDataLen, pSignature, pulSignatureLen);
2037         } else {
2038                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2039         }
2040         return (rv);
2041 }
2042 
2043 CK_RV
2044 C_SignRecoverInit(CK_SESSION_HANDLE hSession,
2045         CK_MECHANISM_PTR pMechanism,
2046         CK_OBJECT_HANDLE hKey)
2047 {
2048         CK_RV rv;
2049         ST_SESSION_T rSession;
2050 
2051         if (API_Initialized() == FALSE) {
2052                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2053         }
2054         if (! pMechanism) {
2055                 return (CKR_MECHANISM_INVALID);
2056         }
2057         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2058                 return (CKR_SESSION_HANDLE_INVALID);
2059         }
2060         if (FuncList.ST_SignRecoverInit) {
2061                 rv = FuncList.ST_SignRecoverInit(rSession, pMechanism, hKey);
2062         } else {
2063                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2064         }
2065         return (rv);
2066 }
2067 
2068 CK_RV
2069 C_SignUpdate(CK_SESSION_HANDLE hSession,
2070         CK_BYTE_PTR pPart,
2071         CK_ULONG ulPartLen)
2072 {
2073         CK_RV rv;
2074         ST_SESSION_T rSession;
2075 
2076         if (API_Initialized() == FALSE) {
2077                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2078         }
2079         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2080                 return (CKR_SESSION_HANDLE_INVALID);
2081         }
2082         if (FuncList.ST_SignUpdate) {
2083                 rv = FuncList.ST_SignUpdate(rSession, pPart, ulPartLen);
2084         } else {
2085                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2086         }
2087         return (rv);
2088 }
2089 
2090 CK_RV
2091 C_UnwrapKey(CK_SESSION_HANDLE hSession,
2092         CK_MECHANISM_PTR pMechanism,
2093         CK_OBJECT_HANDLE hUnwrappingKey,
2094         CK_BYTE_PTR pWrappedKey,
2095         CK_ULONG ulWrappedKeyLen,
2096         CK_ATTRIBUTE_PTR pTemplate,
2097         CK_ULONG ulAttributeCount,
2098         CK_OBJECT_HANDLE_PTR phKey)
2099 {
2100         CK_RV rv;
2101         ST_SESSION_T rSession;
2102 
2103         if (API_Initialized() == FALSE) {
2104                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2105         }
2106         if (!pMechanism) {
2107                 return (CKR_MECHANISM_INVALID);
2108         }
2109         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2110                 return (CKR_SESSION_HANDLE_INVALID);
2111         }
2112         if (FuncList.ST_UnwrapKey) {
2113                 rv = FuncList.ST_UnwrapKey(rSession, pMechanism,
2114                     hUnwrappingKey, pWrappedKey, ulWrappedKeyLen,
2115                     pTemplate, ulAttributeCount, phKey);
2116         } else {
2117                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2118         }
2119         return (rv);
2120 }
2121 
2122 CK_RV
2123 C_Verify(CK_SESSION_HANDLE hSession,
2124         CK_BYTE_PTR pData,
2125         CK_ULONG ulDataLen,
2126         CK_BYTE_PTR pSignature,
2127         CK_ULONG ulSignatureLen)
2128 {
2129         CK_RV rv;
2130         ST_SESSION_T rSession;
2131 
2132         if (API_Initialized() == FALSE) {
2133                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2134         }
2135         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2136                 return (CKR_SESSION_HANDLE_INVALID);
2137         }
2138         if (FuncList.ST_Verify) {
2139                 rv = FuncList.ST_Verify(rSession, pData, ulDataLen,
2140                     pSignature, ulSignatureLen);
2141         } else {
2142                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2143         }
2144         return (rv);
2145 }
2146 
2147 CK_RV
2148 C_VerifyFinal(CK_SESSION_HANDLE hSession,
2149         CK_BYTE_PTR pSignature,
2150         CK_ULONG ulSignatureLen)
2151 {
2152         CK_RV rv;
2153         ST_SESSION_T rSession;
2154 
2155         if (API_Initialized() == FALSE) {
2156                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2157         }
2158         if (! pSignature) {
2159                 return (CKR_ARGUMENTS_BAD);
2160         }
2161 
2162         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2163                 return (CKR_SESSION_HANDLE_INVALID);
2164         }
2165         if (FuncList.ST_VerifyFinal) {
2166                 rv = FuncList.ST_VerifyFinal(rSession, pSignature,
2167                     ulSignatureLen);
2168         } else {
2169                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2170         }
2171         return (rv);
2172 }
2173 
2174 CK_RV
2175 C_VerifyInit(CK_SESSION_HANDLE hSession,
2176         CK_MECHANISM_PTR pMechanism,
2177         CK_OBJECT_HANDLE hKey)
2178 {
2179         CK_RV rv;
2180         ST_SESSION_T rSession;
2181 
2182         if (API_Initialized() == FALSE) {
2183                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2184         }
2185         if (! pMechanism) {
2186                 return (CKR_MECHANISM_INVALID);
2187         }
2188         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2189                 return (CKR_SESSION_HANDLE_INVALID);
2190         }
2191 
2192         if (FuncList.ST_VerifyInit) {
2193                 rv = FuncList.ST_VerifyInit(rSession, pMechanism, hKey);
2194         } else {
2195                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2196         }
2197         return (rv);
2198 }
2199 
2200 CK_RV
2201 C_VerifyRecover(CK_SESSION_HANDLE hSession,
2202         CK_BYTE_PTR pSignature,
2203         CK_ULONG ulSignatureLen,
2204         CK_BYTE_PTR pData,
2205         CK_ULONG_PTR pulDataLen)
2206 {
2207         CK_RV rv;
2208         ST_SESSION_T rSession;
2209 
2210         if (API_Initialized() == FALSE) {
2211                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2212         }
2213         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2214                 return (CKR_SESSION_HANDLE_INVALID);
2215         }
2216         if (FuncList.ST_VerifyRecover) {
2217                 rv = FuncList.ST_VerifyRecover(rSession, pSignature,
2218                     ulSignatureLen, pData, pulDataLen);
2219         } else {
2220                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2221         }
2222         return (rv);
2223 }
2224 
2225 CK_RV
2226 C_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
2227         CK_MECHANISM_PTR pMechanism,
2228         CK_OBJECT_HANDLE hKey)
2229 {
2230         CK_RV rv;
2231         ST_SESSION_T rSession;
2232 
2233         if (API_Initialized() == FALSE) {
2234                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2235         }
2236         if (! pMechanism) {
2237                 return (CKR_MECHANISM_INVALID);
2238         }
2239         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2240                 return (CKR_SESSION_HANDLE_INVALID);
2241         }
2242         if (FuncList.ST_VerifyRecoverInit) {
2243                 rv = FuncList.ST_VerifyRecoverInit(rSession, pMechanism, hKey);
2244         } else {
2245                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2246         }
2247         return (rv);
2248 }
2249 
2250 CK_RV
2251 C_VerifyUpdate(CK_SESSION_HANDLE hSession,
2252         CK_BYTE_PTR pPart,
2253         CK_ULONG ulPartLen)
2254 {
2255         CK_RV rv;
2256         ST_SESSION_T rSession;
2257 
2258         if (API_Initialized() == FALSE) {
2259                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2260         }
2261         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2262                 return (CKR_SESSION_HANDLE_INVALID);
2263         }
2264         if (FuncList.ST_VerifyUpdate) {
2265                 rv = FuncList.ST_VerifyUpdate(rSession, pPart, ulPartLen);
2266         } else {
2267                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2268         }
2269         return (rv);
2270 }
2271 
2272 /*ARGSUSED*/
2273 CK_RV
2274 C_WaitForSlotEvent(CK_FLAGS flags,
2275         CK_SLOT_ID_PTR pSlot,
2276         CK_VOID_PTR pReserved)
2277 {
2278         if (API_Initialized() == FALSE) {
2279                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2280         }
2281         return (CKR_FUNCTION_NOT_SUPPORTED);
2282 }
2283 
2284 CK_RV
2285 C_WrapKey(CK_SESSION_HANDLE hSession,
2286         CK_MECHANISM_PTR pMechanism,
2287         CK_OBJECT_HANDLE hWrappingKey,
2288         CK_OBJECT_HANDLE hKey,
2289         CK_BYTE_PTR pWrappedKey,
2290         CK_ULONG_PTR pulWrappedKeyLen)
2291 {
2292         CK_RV rv;
2293         ST_SESSION_T rSession;
2294 
2295         if (API_Initialized() == FALSE) {
2296                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2297         }
2298         if (! pMechanism) {
2299                 return (CKR_MECHANISM_INVALID);
2300         }
2301         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2302                 return (CKR_SESSION_HANDLE_INVALID);
2303         }
2304         if (FuncList.ST_WrapKey) {
2305                 rv = FuncList.ST_WrapKey(rSession, pMechanism, hWrappingKey,
2306                     hKey, pWrappedKey, pulWrappedKeyLen);
2307         } else {
2308                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2309         }
2310         return (rv);
2311 }
2312 
2313 #pragma init(api_init)
2314 #pragma fini(api_fini)
2315 
2316 static void
2317 api_init(void)
2318 {
2319         loginit();
2320         if (! Initialized) {
2321                 (void) pthread_atfork(tpmtoken_fork_prepare,
2322                     tpmtoken_fork_parent, tpmtoken_fork_child);
2323                 Initialized = 1;
2324         }
2325 }
2326 
2327 static void
2328 api_fini()
2329 {
2330         logterm();
2331         if (API_Initialized() == TRUE) {
2332                 (void) do_finalize(NULL);
2333         }
2334 }