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         PK11_Functions.version.major = VERSION_MAJOR;
1245         PK11_Functions.version.minor = VERSION_MINOR;
1246         PK11_Functions.C_Initialize = C_Initialize;
1247         PK11_Functions.C_Finalize = C_Finalize;
1248         PK11_Functions.C_GetInfo = C_GetInfo;
1249         PK11_Functions.C_GetFunctionList = C_GetFunctionList;
1250         PK11_Functions.C_GetSlotList = C_GetSlotList;
1251         PK11_Functions.C_GetSlotInfo = C_GetSlotInfo;
1252         PK11_Functions.C_GetTokenInfo = C_GetTokenInfo;
1253         PK11_Functions.C_GetMechanismList = C_GetMechanismList;
1254         PK11_Functions.C_GetMechanismInfo = C_GetMechanismInfo;
1255         PK11_Functions.C_InitToken = C_InitToken;
1256         PK11_Functions.C_InitPIN = C_InitPIN;
1257         PK11_Functions.C_SetPIN = C_SetPIN;
1258         PK11_Functions.C_OpenSession = C_OpenSession;
1259         PK11_Functions.C_CloseSession = C_CloseSession;
1260         PK11_Functions.C_CloseAllSessions = C_CloseAllSessions;
1261         PK11_Functions.C_GetSessionInfo = C_GetSessionInfo;
1262         PK11_Functions.C_GetOperationState = C_GetOperationState;
1263         PK11_Functions.C_SetOperationState = C_SetOperationState;
1264         PK11_Functions.C_Login = C_Login;
1265         PK11_Functions.C_Logout = C_Logout;
1266         PK11_Functions.C_CreateObject = C_CreateObject;
1267         PK11_Functions.C_CopyObject = C_CopyObject;
1268         PK11_Functions.C_DestroyObject = C_DestroyObject;
1269         PK11_Functions.C_GetObjectSize = C_GetObjectSize;
1270         PK11_Functions.C_GetAttributeValue = C_GetAttributeValue;
1271         PK11_Functions.C_SetAttributeValue = C_SetAttributeValue;
1272         PK11_Functions.C_FindObjectsInit = C_FindObjectsInit;
1273         PK11_Functions.C_FindObjects = C_FindObjects;
1274         PK11_Functions.C_FindObjectsFinal = C_FindObjectsFinal;
1275         PK11_Functions.C_EncryptInit = C_EncryptInit;
1276         PK11_Functions.C_Encrypt = C_Encrypt;
1277         PK11_Functions.C_EncryptUpdate = C_EncryptUpdate;
1278         PK11_Functions.C_EncryptFinal = C_EncryptFinal;
1279         PK11_Functions.C_DecryptInit = C_DecryptInit;
1280         PK11_Functions.C_Decrypt = C_Decrypt;
1281         PK11_Functions.C_DecryptUpdate = C_DecryptUpdate;
1282         PK11_Functions.C_DecryptFinal = C_DecryptFinal;
1283         PK11_Functions.C_DigestInit = C_DigestInit;
1284         PK11_Functions.C_Digest = C_Digest;
1285         PK11_Functions.C_DigestUpdate = C_DigestUpdate;
1286         PK11_Functions.C_DigestKey = C_DigestKey;
1287         PK11_Functions.C_DigestFinal = C_DigestFinal;
1288         PK11_Functions.C_SignInit = C_SignInit;
1289         PK11_Functions.C_Sign = C_Sign;
1290         PK11_Functions.C_SignUpdate = C_SignUpdate;
1291         PK11_Functions.C_SignFinal = C_SignFinal;
1292         PK11_Functions.C_SignRecoverInit = C_SignRecoverInit;
1293         PK11_Functions.C_SignRecover = C_SignRecover;
1294         PK11_Functions.C_VerifyInit = C_VerifyInit;
1295         PK11_Functions.C_Verify = C_Verify;
1296         PK11_Functions.C_VerifyUpdate = C_VerifyUpdate;
1297         PK11_Functions.C_VerifyFinal = C_VerifyFinal;
1298         PK11_Functions.C_VerifyRecoverInit = C_VerifyRecoverInit;
1299         PK11_Functions.C_VerifyRecover = C_VerifyRecover;
1300         PK11_Functions.C_DigestEncryptUpdate = C_DigestEncryptUpdate;
1301         PK11_Functions.C_DecryptDigestUpdate = C_DecryptDigestUpdate;
1302         PK11_Functions.C_SignEncryptUpdate = C_SignEncryptUpdate;
1303         PK11_Functions.C_DecryptVerifyUpdate = C_DecryptVerifyUpdate;
1304         PK11_Functions.C_GenerateKey = C_GenerateKey;
1305         PK11_Functions.C_GenerateKeyPair = C_GenerateKeyPair;
1306         PK11_Functions.C_WrapKey = C_WrapKey;
1307         PK11_Functions.C_UnwrapKey = C_UnwrapKey;
1308         PK11_Functions.C_DeriveKey = C_DeriveKey;
1309         PK11_Functions.C_SeedRandom = C_SeedRandom;
1310         PK11_Functions.C_GenerateRandom = C_GenerateRandom;
1311         PK11_Functions.C_GetFunctionStatus = C_GetFunctionStatus;
1312         PK11_Functions.C_CancelFunction = C_CancelFunction;
1313         PK11_Functions.C_WaitForSlotEvent = C_WaitForSlotEvent;
1314         if (ppFunctionList) {
1315                 (*ppFunctionList) = &PK11_Functions;
1316                 return (CKR_OK);
1317         } else {
1318                 return (CKR_ARGUMENTS_BAD);
1319         }
1320 }
1321 
1322 /*ARGSUSED*/
1323 CK_RV
1324 C_GetFunctionStatus(CK_SESSION_HANDLE hSession)
1325 {
1326         if (API_Initialized() == FALSE) {
1327                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1328         }
1329         return (CKR_FUNCTION_NOT_PARALLEL); // PER Specification PG 170
1330 }
1331 
1332 CK_RV
1333 C_GetInfo(CK_INFO_PTR pInfo)
1334 {
1335         TOKEN_DATA td;
1336         TSS_HCONTEXT hContext;
1337 
1338         if (! API_Initialized()) {
1339                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1340         }
1341         if (! pInfo) {
1342                 return (CKR_FUNCTION_FAILED);
1343         }
1344         (void) memset(pInfo, 0, sizeof (*pInfo));
1345         pInfo->cryptokiVersion.major = 2;
1346         pInfo->cryptokiVersion.minor = 20;
1347 
1348         if (open_tss_context(&hContext) == 0) {
1349                 /*
1350                  * Only populate the TPM info if we can establish
1351                  * a context, but don't return failure because
1352                  * the framework needs to know some of the info.
1353                  */
1354                 (void) token_get_tpm_info(hContext, &td);
1355 
1356                 (void) Tspi_Context_Close(hContext);
1357 
1358                 (void) memcpy(pInfo->manufacturerID,
1359                     &(td.token_info.manufacturerID),
1360                     sizeof (pInfo->manufacturerID) - 1);
1361 
1362                 pInfo->flags = td.token_info.flags;
1363         }
1364         (void) strcpy((char *)pInfo->libraryDescription,
1365             "PKCS11 Interface for TPM");
1366 
1367         pInfo->libraryVersion.major = 1;
1368         pInfo->libraryVersion.minor = 0;
1369 
1370         return (CKR_OK);
1371 }
1372 
1373 CK_RV
1374 C_GetMechanismInfo(CK_SLOT_ID   slotID,
1375         CK_MECHANISM_TYPE       type,
1376         CK_MECHANISM_INFO_PTR   pInfo)
1377 {
1378         CK_RV rv;
1379         if (API_Initialized() == FALSE)
1380                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1381 
1382         if (!global_shm->token_available || (slotID > NUMBER_SLOTS_MANAGED))
1383                 return (CKR_SLOT_ID_INVALID);
1384 
1385         if (FuncList.ST_GetMechanismInfo) {
1386                 rv = FuncList.ST_GetMechanismInfo(slotID, type, pInfo);
1387         } else {
1388                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1389         }
1390         return (rv);
1391 }
1392 
1393 CK_RV
1394 C_GetMechanismList(CK_SLOT_ID slotID,
1395         CK_MECHANISM_TYPE_PTR pMechanismList,
1396         CK_ULONG_PTR pulCount)
1397 {
1398         CK_RV rv;
1399 
1400         if (API_Initialized() == FALSE)
1401                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1402 
1403         if (! pulCount)
1404                 return (CKR_ARGUMENTS_BAD);
1405 
1406         if (!global_shm->token_available || (slotID > NUMBER_SLOTS_MANAGED))
1407                 return (CKR_SLOT_ID_INVALID);
1408 
1409         if (FuncList.ST_GetMechanismList) {
1410                 rv = FuncList.ST_GetMechanismList(slotID,
1411                     pMechanismList, pulCount);
1412         } else {
1413                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1414         }
1415         if (rv == CKR_OK) {
1416                 if (pMechanismList) {
1417                         unsigned long i;
1418                         for (i = 0; i < *pulCount; i++) {
1419                                 logit(LOG_DEBUG, "Mechanism[%d] 0x%08X ",
1420                                     i, pMechanismList[i]);
1421                         }
1422                 }
1423         }
1424         return (rv);
1425 }
1426 
1427 CK_RV
1428 C_GetObjectSize(CK_SESSION_HANDLE hSession,
1429         CK_OBJECT_HANDLE hObject,
1430         CK_ULONG_PTR pulSize)
1431 {
1432         CK_RV rv;
1433         ST_SESSION_T rSession;
1434 
1435         if (API_Initialized() == FALSE) {
1436                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1437         }
1438         if (! pulSize) {
1439                 return (CKR_ARGUMENTS_BAD);
1440         }
1441         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1442                 return (CKR_SESSION_HANDLE_INVALID);
1443         }
1444         if (FuncList.ST_GetObjectSize) {
1445                 rv = FuncList.ST_GetObjectSize(rSession, hObject, pulSize);
1446         } else {
1447                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1448         }
1449         return (rv);
1450 }
1451 
1452 CK_RV
1453 C_GetOperationState(CK_SESSION_HANDLE hSession,
1454         CK_BYTE_PTR pOperationState,
1455         CK_ULONG_PTR pulOperationStateLen)
1456 {
1457         CK_RV rv;
1458         ST_SESSION_T rSession;
1459 
1460         if (API_Initialized() == FALSE) {
1461                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1462         }
1463         if (! pulOperationStateLen) {
1464                 return (CKR_ARGUMENTS_BAD);
1465         }
1466         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1467                 return (CKR_SESSION_HANDLE_INVALID);
1468         }
1469         if (FuncList.ST_GetOperationState) {
1470                 rv = FuncList.ST_GetOperationState(rSession,
1471                     pOperationState, pulOperationStateLen);
1472         } else {
1473                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1474         }
1475         return (rv);
1476 }
1477 
1478 CK_RV
1479 C_GetSessionInfo(CK_SESSION_HANDLE hSession,
1480         CK_SESSION_INFO_PTR pInfo)
1481 {
1482         CK_RV rv;
1483         ST_SESSION_T rSession;
1484 
1485         if (API_Initialized() == FALSE) {
1486                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1487         }
1488         if (! pInfo) {
1489                 return (CKR_ARGUMENTS_BAD);
1490         }
1491         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1492                 return (CKR_SESSION_HANDLE_INVALID);
1493         }
1494         if (FuncList.ST_GetSessionInfo) {
1495                 rv = FuncList.ST_GetSessionInfo(rSession, pInfo);
1496         } else {
1497                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1498         }
1499         return (rv);
1500 }
1501 
1502 CK_RV
1503 C_GetSlotInfo(CK_SLOT_ID slotID,
1504         CK_SLOT_INFO_PTR pInfo)
1505 {
1506         if (API_Initialized() == FALSE)
1507                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1508 
1509         if (!pInfo)
1510                 return (CKR_FUNCTION_FAILED);
1511 
1512         if (!global_shm->token_available || (slotID > NUMBER_SLOTS_MANAGED))
1513                 return (CKR_SLOT_ID_INVALID);
1514 
1515         copy_slot_info(slotID, pInfo);
1516         return (CKR_OK);
1517 }
1518 
1519 /*ARGSUSED*/
1520 CK_RV
1521 C_GetSlotList(CK_BBOOL tokenPresent,
1522         CK_SLOT_ID_PTR pSlotList,
1523         CK_ULONG_PTR pulCount)
1524 {
1525         CK_ULONG count;
1526         CK_SLOT_INFO slotInfo;
1527 
1528         if (API_Initialized() == FALSE)
1529                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1530 
1531         if (pulCount == NULL)
1532                 return (CKR_FUNCTION_FAILED);
1533 
1534         count = 0;
1535         /*
1536          * If we can't talk to the TPM, present no slots
1537          */
1538         if (!global_shm->token_available) {
1539                 *pulCount = 0;
1540                 return (CKR_OK);
1541         }
1542 
1543         copy_slot_info(TPM_SLOTID, &slotInfo);
1544         if ((slotInfo.flags & CKF_TOKEN_PRESENT))
1545                 count++;
1546 
1547         *pulCount = count;
1548 
1549         if (pSlotList == NULL) {
1550                 return (CKR_OK);
1551         } else {
1552                 if (*pulCount < count)
1553                         return (CKR_BUFFER_TOO_SMALL);
1554                 pSlotList[0] = TPM_SLOTID;
1555         }
1556         return (CKR_OK);
1557 }
1558 
1559 CK_RV
1560 C_GetTokenInfo(CK_SLOT_ID slotID,
1561         CK_TOKEN_INFO_PTR pInfo)
1562 {
1563         CK_RV rv;
1564 
1565         if (API_Initialized() == FALSE)
1566                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1567 
1568         if (!pInfo)
1569                 return (CKR_ARGUMENTS_BAD);
1570 
1571         if (!global_shm->token_available || (slotID > NUMBER_SLOTS_MANAGED))
1572                 return (CKR_SLOT_ID_INVALID);
1573 
1574         slotID = TPM_SLOTID;
1575         if (FuncList.ST_GetTokenInfo) {
1576                 rv = FuncList.ST_GetTokenInfo(slotID, pInfo);
1577         } else {
1578                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1579         }
1580         return (rv);
1581 }
1582 
1583 CK_RV
1584 C_Initialize(CK_VOID_PTR pVoid)
1585 {
1586         CK_RV rv = CKR_OK;
1587         CK_C_INITIALIZE_ARGS *pArg;
1588         extern CK_RV ST_Initialize(void *,
1589             CK_SLOT_ID, unsigned char *);
1590 
1591         (void) pthread_mutex_lock(&global_mutex);
1592         if (! Anchor) {
1593                 Anchor = (API_Proc_Struct_t *)malloc(
1594                     sizeof (API_Proc_Struct_t));
1595                 if (Anchor == NULL) {
1596                         (void) pthread_mutex_unlock(&global_mutex);
1597                         return (CKR_HOST_MEMORY);
1598                 }
1599         } else {
1600                 (void) pthread_mutex_unlock(&global_mutex);
1601                 return (CKR_CRYPTOKI_ALREADY_INITIALIZED);
1602         }
1603         /*
1604          * if pVoid is NULL, then everything is OK.  The applicaiton
1605          * will not be doing multi thread accesses.  We can use the OS
1606          * locks anyhow.
1607          */
1608         if (pVoid != NULL) {
1609                 int supplied_ok;
1610                 pArg = (CK_C_INITIALIZE_ARGS *)pVoid;
1611 
1612                 /*
1613                  * ALL supplied function pointers need to have the value
1614                  * either NULL or no - NULL.
1615                  */
1616                 supplied_ok = (pArg->CreateMutex == NULL &&
1617                     pArg->DestroyMutex == NULL &&
1618                     pArg->LockMutex == NULL &&
1619                     pArg->UnlockMutex == NULL) ||
1620                     (pArg->CreateMutex != NULL &&
1621                     pArg->DestroyMutex != NULL &&
1622                     pArg->LockMutex != NULL &&
1623                     pArg->UnlockMutex != NULL);
1624 
1625                 if (!supplied_ok) {
1626                         (void) pthread_mutex_unlock(&global_mutex);
1627                         return (CKR_ARGUMENTS_BAD);
1628                 }
1629                 /* Check for a pReserved set */
1630                 if (pArg->pReserved != NULL) {
1631                         free(Anchor);
1632                         Anchor = NULL;
1633                         (void) pthread_mutex_unlock(&global_mutex);
1634                         return (CKR_ARGUMENTS_BAD);
1635                 }
1636                 /*
1637                  * When the CKF_OS_LOCKING_OK flag isn't set and mutex
1638                  * function pointers are supplied by an application,
1639                  * return (an error.  We must be able to use our own primitives.
1640                  */
1641                 if (!(pArg->flags & CKF_OS_LOCKING_OK) &&
1642                     (pArg->CreateMutex != NULL)) {
1643                         (void) pthread_mutex_unlock(&global_mutex);
1644                         return (CKR_CANT_LOCK);
1645                 }
1646         }
1647         (void) memset((char *)Anchor, 0, sizeof (API_Proc_Struct_t));
1648         (void) pthread_mutex_init(&(Anchor->ProcMutex), NULL);
1649         (void) pthread_mutex_init(&(Anchor->SessListMutex), NULL);
1650         Anchor->Pid = getpid();
1651 
1652         rv = ST_Initialize((void *)&FuncList, 0, NULL);
1653         (void) pthread_mutex_unlock(&global_mutex);
1654         return (rv);
1655 }
1656 
1657 CK_RV
1658 C_InitPIN(CK_SESSION_HANDLE hSession,
1659         CK_CHAR_PTR pPin,
1660         CK_ULONG ulPinLen)
1661 {
1662         CK_RV rv;
1663         ST_SESSION_T rSession;
1664 
1665         if (API_Initialized() == FALSE)
1666                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1667 
1668         if (! pPin && ulPinLen)
1669                 return (CKR_ARGUMENTS_BAD);
1670 
1671         if (! Valid_Session((Session_Struct_t *)hSession, &rSession))
1672                 return (CKR_SESSION_HANDLE_INVALID);
1673 
1674         if (rSession.slotID > NUMBER_SLOTS_MANAGED)
1675                 return (CKR_SLOT_ID_INVALID);
1676 
1677         if (FuncList.ST_InitPIN)
1678                 rv = FuncList.ST_InitPIN(rSession, pPin, ulPinLen);
1679         else
1680                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1681 
1682         return (rv);
1683 }
1684 
1685 CK_RV
1686 C_InitToken(CK_SLOT_ID  slotID,
1687         CK_CHAR_PTR pPin,
1688         CK_ULONG    ulPinLen,
1689         CK_CHAR_PTR pLabel)
1690 {
1691         CK_RV rv;
1692 
1693         if (API_Initialized() == FALSE)
1694                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1695 
1696         if (! pPin && ulPinLen)
1697                 return (CKR_ARGUMENTS_BAD);
1698 
1699         if (! pLabel)
1700                 return (CKR_ARGUMENTS_BAD);
1701 
1702         if (!global_shm->token_available)
1703                 return (CKR_SLOT_ID_INVALID);
1704 
1705         if (FuncList.ST_InitToken)
1706                 rv = FuncList.ST_InitToken(slotID, pPin, ulPinLen, pLabel);
1707         else
1708                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1709 
1710         return (rv);
1711 }
1712 
1713 CK_RV
1714 C_Login(CK_SESSION_HANDLE hSession,
1715         CK_USER_TYPE userType,
1716         CK_CHAR_PTR pPin,
1717         CK_ULONG ulPinLen)
1718 {
1719         CK_RV rv;
1720         ST_SESSION_T rSession;
1721 
1722         if (API_Initialized() == FALSE) {
1723                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1724         }
1725         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1726                 return (CKR_SESSION_HANDLE_INVALID);
1727         }
1728         if (FuncList.ST_Login) {
1729                 rv = FuncList.ST_Login(rSession, userType, pPin, ulPinLen);
1730         } else {
1731                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1732         }
1733         return (rv);
1734 }
1735 
1736 CK_RV
1737 C_Logout(CK_SESSION_HANDLE hSession)
1738 {
1739         CK_RV rv;
1740         ST_SESSION_T rSession;
1741 
1742         if (API_Initialized() == FALSE) {
1743                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1744         }
1745         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1746                 return (CKR_SESSION_HANDLE_INVALID);
1747         }
1748         if (FuncList.ST_Logout) {
1749                 rv = FuncList.ST_Logout(rSession);
1750         } else {
1751                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1752         }
1753         return (rv);
1754 }
1755 
1756 /*ARGSUSED*/
1757 CK_RV
1758 C_OpenSession(
1759         CK_SLOT_ID slotID,
1760         CK_FLAGS flags,
1761         CK_VOID_PTR pApplication,
1762         CK_NOTIFY Notify,
1763         CK_SESSION_HANDLE_PTR phSession)
1764 {
1765         CK_RV rv;
1766         Session_Struct_t  *apiSessp;
1767 
1768         if (API_Initialized() == FALSE)
1769                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1770 
1771         if (!global_shm->token_available || (slotID > NUMBER_SLOTS_MANAGED))
1772                 return (CKR_SLOT_ID_INVALID);
1773 
1774         if (! phSession)
1775                 return (CKR_FUNCTION_FAILED);
1776 
1777         if ((flags & CKF_SERIAL_SESSION) == 0)
1778                 return (CKR_SESSION_PARALLEL_NOT_SUPPORTED);
1779 
1780         if ((apiSessp = (Session_Struct_t *)malloc(
1781             sizeof (Session_Struct_t))) == NULL)
1782                 return (CKR_HOST_MEMORY);
1783 
1784         if (FuncList.ST_OpenSession) {
1785                 rv = FuncList.ST_OpenSession(slotID, flags,
1786                     &(apiSessp->RealHandle));
1787 
1788                 if (rv == CKR_OK) {
1789                         *phSession = (CK_SESSION_HANDLE)apiSessp;
1790                         apiSessp->SltId = slotID;
1791 
1792                         AddToSessionList(apiSessp);
1793                 } else {
1794                         free(apiSessp);
1795                 }
1796         } else {
1797                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1798         }
1799         return (rv);
1800 }
1801 
1802 CK_RV
1803 C_SeedRandom(CK_SESSION_HANDLE hSession,
1804         CK_BYTE_PTR pSeed,
1805         CK_ULONG ulSeedLen)
1806 {
1807         CK_RV rv;
1808         ST_SESSION_T rSession;
1809 
1810         if (API_Initialized() == FALSE) {
1811                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1812         }
1813         if (! pSeed && ulSeedLen) {
1814                 return (CKR_ARGUMENTS_BAD);
1815         }
1816         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1817                 return (CKR_SESSION_HANDLE_INVALID);
1818         }
1819         if (FuncList.ST_SeedRandom) {
1820                 rv = FuncList.ST_SeedRandom(rSession, pSeed, ulSeedLen);
1821         } else {
1822                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1823         }
1824         return (rv);
1825 }
1826 
1827 CK_RV
1828 C_SetAttributeValue(CK_SESSION_HANDLE hSession,
1829         CK_OBJECT_HANDLE hObject,
1830         CK_ATTRIBUTE_PTR pTemplate,
1831         CK_ULONG ulCount)
1832 {
1833         CK_RV rv;
1834         ST_SESSION_T rSession;
1835 
1836         if (API_Initialized() == FALSE) {
1837                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1838         }
1839         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1840                 return (CKR_SESSION_HANDLE_INVALID);
1841         }
1842         if (! pTemplate) {
1843                 return (CKR_TEMPLATE_INCOMPLETE);
1844         }
1845         if (! ulCount) {
1846                 return (CKR_TEMPLATE_INCOMPLETE);
1847         }
1848         // Get local pointers to session
1849         if (FuncList.ST_SetAttributeValue) {
1850                 rv = FuncList.ST_SetAttributeValue(rSession, hObject,
1851                     pTemplate, ulCount);
1852         } else {
1853                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1854         }
1855         return (rv);
1856 }
1857 
1858 CK_RV
1859 C_SetOperationState(CK_SESSION_HANDLE hSession,
1860         CK_BYTE_PTR pOperationState,
1861         CK_ULONG ulOperationStateLen,
1862         CK_OBJECT_HANDLE hEncryptionKey,
1863         CK_OBJECT_HANDLE hAuthenticationKey)
1864 {
1865         CK_RV rv;
1866         ST_SESSION_T rSession;
1867 
1868         if (API_Initialized() == FALSE) {
1869                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1870         }
1871         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1872                 return (CKR_SESSION_HANDLE_INVALID);
1873         }
1874         if (! pOperationState || ulOperationStateLen == 0) {
1875                 return (CKR_ARGUMENTS_BAD);
1876         }
1877         if (FuncList.ST_SetOperationState) {
1878                 rv = FuncList.ST_SetOperationState(rSession, pOperationState,
1879                     ulOperationStateLen, hEncryptionKey, hAuthenticationKey);
1880         } else {
1881                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1882         }
1883         return (rv);
1884 }
1885 
1886 CK_RV
1887 C_SetPIN(CK_SESSION_HANDLE hSession,
1888         CK_CHAR_PTR pOldPin,
1889         CK_ULONG ulOldLen,
1890         CK_CHAR_PTR pNewPin,
1891         CK_ULONG ulNewLen)
1892 {
1893         CK_RV rv;
1894         ST_SESSION_T rSession;
1895 
1896         if (API_Initialized() == FALSE) {
1897                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1898         }
1899         if (! pOldPin || ! pNewPin)
1900                 return (CKR_PIN_INVALID);
1901         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1902                 return (CKR_SESSION_HANDLE_INVALID);
1903         }
1904         if (FuncList.ST_SetPIN) {
1905                 rv = FuncList.ST_SetPIN(rSession, pOldPin, ulOldLen,
1906                     pNewPin, ulNewLen);
1907         } else {
1908                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1909         }
1910         return (rv);
1911 }
1912 
1913 CK_RV
1914 C_Sign(CK_SESSION_HANDLE hSession,
1915         CK_BYTE_PTR pData,
1916         CK_ULONG ulDataLen,
1917         CK_BYTE_PTR pSignature,
1918         CK_ULONG_PTR pulSignatureLen)
1919 {
1920         CK_RV rv;
1921         ST_SESSION_T rSession;
1922 
1923         if (API_Initialized() == FALSE) {
1924                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1925         }
1926         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1927                 return (CKR_SESSION_HANDLE_INVALID);
1928         }
1929         if (FuncList.ST_Sign) {
1930                 rv = FuncList.ST_Sign(rSession, pData, ulDataLen,
1931                     pSignature, pulSignatureLen);
1932         } else {
1933                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1934         }
1935         return (rv);
1936 }
1937 
1938 CK_RV
1939 C_SignEncryptUpdate(CK_SESSION_HANDLE hSession,
1940         CK_BYTE_PTR pPart,
1941         CK_ULONG ulPartLen,
1942         CK_BYTE_PTR pEncryptedPart,
1943         CK_ULONG_PTR pulEncryptedPartLen)
1944 {
1945         CK_RV rv;
1946         ST_SESSION_T rSession;
1947         if (API_Initialized() == FALSE) {
1948                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1949         }
1950         if (! pPart || ! pulEncryptedPartLen) {
1951                 return (CKR_ARGUMENTS_BAD);
1952         }
1953         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1954                 return (CKR_SESSION_HANDLE_INVALID);
1955         }
1956         if (FuncList.ST_SignEncryptUpdate) {
1957                 rv = FuncList.ST_SignEncryptUpdate(rSession, pPart,
1958                     ulPartLen, pEncryptedPart, pulEncryptedPartLen);
1959         } else {
1960                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1961         }
1962         return (rv);
1963 }
1964 
1965 CK_RV
1966 C_SignFinal(CK_SESSION_HANDLE hSession,
1967         CK_BYTE_PTR pSignature,
1968         CK_ULONG_PTR pulSignatureLen)
1969 {
1970         CK_RV rv;
1971         ST_SESSION_T rSession;
1972 
1973         if (API_Initialized() == FALSE) {
1974                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
1975         }
1976         if (! pulSignatureLen) {
1977                 return (CKR_ARGUMENTS_BAD);
1978         }
1979         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
1980                 return (CKR_SESSION_HANDLE_INVALID);
1981         }
1982         if (FuncList.ST_SignFinal) {
1983                 rv = FuncList.ST_SignFinal(rSession, pSignature,
1984                     pulSignatureLen);
1985         } else {
1986                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1987         }
1988         return (rv);
1989 }
1990 
1991 CK_RV
1992 C_SignInit(CK_SESSION_HANDLE hSession,
1993         CK_MECHANISM_PTR pMechanism,
1994         CK_OBJECT_HANDLE hKey)
1995 {
1996         CK_RV rv;
1997         ST_SESSION_T rSession;
1998 
1999         if (API_Initialized() == FALSE) {
2000                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2001         }
2002         if (! pMechanism) {
2003                 return (CKR_MECHANISM_INVALID);
2004         }
2005         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2006                 return (CKR_SESSION_HANDLE_INVALID);
2007         }
2008         if (FuncList.ST_SignInit) {
2009                 rv = FuncList.ST_SignInit(rSession, pMechanism, hKey);
2010         } else {
2011                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2012         }
2013         return (rv);
2014 }
2015 
2016 CK_RV
2017 C_SignRecover(CK_SESSION_HANDLE hSession,
2018         CK_BYTE_PTR pData,
2019         CK_ULONG ulDataLen,
2020         CK_BYTE_PTR pSignature,
2021         CK_ULONG_PTR pulSignatureLen)
2022 {
2023         CK_RV rv;
2024         ST_SESSION_T rSession;
2025 
2026         if (API_Initialized() == FALSE) {
2027                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2028         }
2029         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2030                 return (CKR_SESSION_HANDLE_INVALID);
2031         }
2032         if (FuncList.ST_SignRecover) {
2033                 rv = FuncList.ST_SignRecover(rSession, pData,
2034                     ulDataLen, pSignature, pulSignatureLen);
2035         } else {
2036                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2037         }
2038         return (rv);
2039 }
2040 
2041 CK_RV
2042 C_SignRecoverInit(CK_SESSION_HANDLE hSession,
2043         CK_MECHANISM_PTR pMechanism,
2044         CK_OBJECT_HANDLE hKey)
2045 {
2046         CK_RV rv;
2047         ST_SESSION_T rSession;
2048 
2049         if (API_Initialized() == FALSE) {
2050                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2051         }
2052         if (! pMechanism) {
2053                 return (CKR_MECHANISM_INVALID);
2054         }
2055         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2056                 return (CKR_SESSION_HANDLE_INVALID);
2057         }
2058         if (FuncList.ST_SignRecoverInit) {
2059                 rv = FuncList.ST_SignRecoverInit(rSession, pMechanism, hKey);
2060         } else {
2061                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2062         }
2063         return (rv);
2064 }
2065 
2066 CK_RV
2067 C_SignUpdate(CK_SESSION_HANDLE hSession,
2068         CK_BYTE_PTR pPart,
2069         CK_ULONG ulPartLen)
2070 {
2071         CK_RV rv;
2072         ST_SESSION_T rSession;
2073 
2074         if (API_Initialized() == FALSE) {
2075                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2076         }
2077         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2078                 return (CKR_SESSION_HANDLE_INVALID);
2079         }
2080         if (FuncList.ST_SignUpdate) {
2081                 rv = FuncList.ST_SignUpdate(rSession, pPart, ulPartLen);
2082         } else {
2083                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2084         }
2085         return (rv);
2086 }
2087 
2088 CK_RV
2089 C_UnwrapKey(CK_SESSION_HANDLE hSession,
2090         CK_MECHANISM_PTR pMechanism,
2091         CK_OBJECT_HANDLE hUnwrappingKey,
2092         CK_BYTE_PTR pWrappedKey,
2093         CK_ULONG ulWrappedKeyLen,
2094         CK_ATTRIBUTE_PTR pTemplate,
2095         CK_ULONG ulAttributeCount,
2096         CK_OBJECT_HANDLE_PTR phKey)
2097 {
2098         CK_RV rv;
2099         ST_SESSION_T rSession;
2100 
2101         if (API_Initialized() == FALSE) {
2102                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2103         }
2104         if (!pMechanism) {
2105                 return (CKR_MECHANISM_INVALID);
2106         }
2107         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2108                 return (CKR_SESSION_HANDLE_INVALID);
2109         }
2110         if (FuncList.ST_UnwrapKey) {
2111                 rv = FuncList.ST_UnwrapKey(rSession, pMechanism,
2112                     hUnwrappingKey, pWrappedKey, ulWrappedKeyLen,
2113                     pTemplate, ulAttributeCount, phKey);
2114         } else {
2115                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2116         }
2117         return (rv);
2118 }
2119 
2120 CK_RV
2121 C_Verify(CK_SESSION_HANDLE hSession,
2122         CK_BYTE_PTR pData,
2123         CK_ULONG ulDataLen,
2124         CK_BYTE_PTR pSignature,
2125         CK_ULONG ulSignatureLen)
2126 {
2127         CK_RV rv;
2128         ST_SESSION_T rSession;
2129 
2130         if (API_Initialized() == FALSE) {
2131                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2132         }
2133         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2134                 return (CKR_SESSION_HANDLE_INVALID);
2135         }
2136         if (FuncList.ST_Verify) {
2137                 rv = FuncList.ST_Verify(rSession, pData, ulDataLen,
2138                     pSignature, ulSignatureLen);
2139         } else {
2140                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2141         }
2142         return (rv);
2143 }
2144 
2145 CK_RV
2146 C_VerifyFinal(CK_SESSION_HANDLE hSession,
2147         CK_BYTE_PTR pSignature,
2148         CK_ULONG ulSignatureLen)
2149 {
2150         CK_RV rv;
2151         ST_SESSION_T rSession;
2152 
2153         if (API_Initialized() == FALSE) {
2154                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2155         }
2156         if (! pSignature) {
2157                 return (CKR_ARGUMENTS_BAD);
2158         }
2159 
2160         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2161                 return (CKR_SESSION_HANDLE_INVALID);
2162         }
2163         if (FuncList.ST_VerifyFinal) {
2164                 rv = FuncList.ST_VerifyFinal(rSession, pSignature,
2165                     ulSignatureLen);
2166         } else {
2167                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2168         }
2169         return (rv);
2170 }
2171 
2172 CK_RV
2173 C_VerifyInit(CK_SESSION_HANDLE hSession,
2174         CK_MECHANISM_PTR pMechanism,
2175         CK_OBJECT_HANDLE hKey)
2176 {
2177         CK_RV rv;
2178         ST_SESSION_T rSession;
2179 
2180         if (API_Initialized() == FALSE) {
2181                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2182         }
2183         if (! pMechanism) {
2184                 return (CKR_MECHANISM_INVALID);
2185         }
2186         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2187                 return (CKR_SESSION_HANDLE_INVALID);
2188         }
2189 
2190         if (FuncList.ST_VerifyInit) {
2191                 rv = FuncList.ST_VerifyInit(rSession, pMechanism, hKey);
2192         } else {
2193                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2194         }
2195         return (rv);
2196 }
2197 
2198 CK_RV
2199 C_VerifyRecover(CK_SESSION_HANDLE hSession,
2200         CK_BYTE_PTR pSignature,
2201         CK_ULONG ulSignatureLen,
2202         CK_BYTE_PTR pData,
2203         CK_ULONG_PTR pulDataLen)
2204 {
2205         CK_RV rv;
2206         ST_SESSION_T rSession;
2207 
2208         if (API_Initialized() == FALSE) {
2209                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2210         }
2211         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2212                 return (CKR_SESSION_HANDLE_INVALID);
2213         }
2214         if (FuncList.ST_VerifyRecover) {
2215                 rv = FuncList.ST_VerifyRecover(rSession, pSignature,
2216                     ulSignatureLen, pData, pulDataLen);
2217         } else {
2218                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2219         }
2220         return (rv);
2221 }
2222 
2223 CK_RV
2224 C_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
2225         CK_MECHANISM_PTR pMechanism,
2226         CK_OBJECT_HANDLE hKey)
2227 {
2228         CK_RV rv;
2229         ST_SESSION_T rSession;
2230 
2231         if (API_Initialized() == FALSE) {
2232                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2233         }
2234         if (! pMechanism) {
2235                 return (CKR_MECHANISM_INVALID);
2236         }
2237         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2238                 return (CKR_SESSION_HANDLE_INVALID);
2239         }
2240         if (FuncList.ST_VerifyRecoverInit) {
2241                 rv = FuncList.ST_VerifyRecoverInit(rSession, pMechanism, hKey);
2242         } else {
2243                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2244         }
2245         return (rv);
2246 }
2247 
2248 CK_RV
2249 C_VerifyUpdate(CK_SESSION_HANDLE hSession,
2250         CK_BYTE_PTR pPart,
2251         CK_ULONG ulPartLen)
2252 {
2253         CK_RV rv;
2254         ST_SESSION_T rSession;
2255 
2256         if (API_Initialized() == FALSE) {
2257                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2258         }
2259         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2260                 return (CKR_SESSION_HANDLE_INVALID);
2261         }
2262         if (FuncList.ST_VerifyUpdate) {
2263                 rv = FuncList.ST_VerifyUpdate(rSession, pPart, ulPartLen);
2264         } else {
2265                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2266         }
2267         return (rv);
2268 }
2269 
2270 /*ARGSUSED*/
2271 CK_RV
2272 C_WaitForSlotEvent(CK_FLAGS flags,
2273         CK_SLOT_ID_PTR pSlot,
2274         CK_VOID_PTR pReserved)
2275 {
2276         if (API_Initialized() == FALSE) {
2277                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2278         }
2279         return (CKR_FUNCTION_NOT_SUPPORTED);
2280 }
2281 
2282 CK_RV
2283 C_WrapKey(CK_SESSION_HANDLE hSession,
2284         CK_MECHANISM_PTR pMechanism,
2285         CK_OBJECT_HANDLE hWrappingKey,
2286         CK_OBJECT_HANDLE hKey,
2287         CK_BYTE_PTR pWrappedKey,
2288         CK_ULONG_PTR pulWrappedKeyLen)
2289 {
2290         CK_RV rv;
2291         ST_SESSION_T rSession;
2292 
2293         if (API_Initialized() == FALSE) {
2294                 return (CKR_CRYPTOKI_NOT_INITIALIZED);
2295         }
2296         if (! pMechanism) {
2297                 return (CKR_MECHANISM_INVALID);
2298         }
2299         if (! Valid_Session((Session_Struct_t *)hSession, &rSession)) {
2300                 return (CKR_SESSION_HANDLE_INVALID);
2301         }
2302         if (FuncList.ST_WrapKey) {
2303                 rv = FuncList.ST_WrapKey(rSession, pMechanism, hWrappingKey,
2304                     hKey, pWrappedKey, pulWrappedKeyLen);
2305         } else {
2306                 rv = CKR_FUNCTION_NOT_SUPPORTED;
2307         }
2308         return (rv);
2309 }
2310 
2311 #pragma init(api_init)
2312 #pragma fini(api_fini)
2313 
2314 static void
2315 api_init(void)
2316 {
2317         loginit();
2318         if (! Initialized) {
2319                 (void) pthread_atfork(tpmtoken_fork_prepare,
2320                     tpmtoken_fork_parent, tpmtoken_fork_child);
2321                 Initialized = 1;
2322         }
2323 }
2324 
2325 static void
2326 api_fini()
2327 {
2328         logterm();
2329         if (API_Initialized() == TRUE) {
2330                 (void) do_finalize(NULL);
2331         }
2332 }