1 /*
   2  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
   3  * Use is subject to license terms.
   4  */
   5 
   6 /* crypto/engine/hw_pk11_pub.c */
   7 /*
   8  * This product includes software developed by the OpenSSL Project for
   9  * use in the OpenSSL Toolkit (http://www.openssl.org/).
  10  *
  11  * This project also referenced hw_pkcs11-0.9.7b.patch written by
  12  * Afchine Madjlessi.
  13  */
  14 /*
  15  * ====================================================================
  16  * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
  17  *
  18  * Redistribution and use in source and binary forms, with or without
  19  * modification, are permitted provided that the following conditions
  20  * are met:
  21  *
  22  * 1. Redistributions of source code must retain the above copyright
  23  *    notice, this list of conditions and the following disclaimer.
  24  *
  25  * 2. Redistributions in binary form must reproduce the above copyright
  26  *    notice, this list of conditions and the following disclaimer in
  27  *    the documentation and/or other materials provided with the
  28  *    distribution.
  29  *
  30  * 3. All advertising materials mentioning features or use of this
  31  *    software must display the following acknowledgment:
  32  *    "This product includes software developed by the OpenSSL Project
  33  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  34  *
  35  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  36  *    endorse or promote products derived from this software without
  37  *    prior written permission. For written permission, please contact
  38  *    licensing@OpenSSL.org.
  39  *
  40  * 5. Products derived from this software may not be called "OpenSSL"
  41  *    nor may "OpenSSL" appear in their names without prior written
  42  *    permission of the OpenSSL Project.
  43  *
  44  * 6. Redistributions of any form whatsoever must retain the following
  45  *    acknowledgment:
  46  *    "This product includes software developed by the OpenSSL Project
  47  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  48  *
  49  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  50  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  51  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  52  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
  53  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  54  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  55  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  56  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  57  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  58  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  59  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  60  * OF THE POSSIBILITY OF SUCH DAMAGE.
  61  * ====================================================================
  62  *
  63  * This product includes cryptographic software written by Eric Young
  64  * (eay@cryptsoft.com).  This product includes software written by Tim
  65  * Hudson (tjh@cryptsoft.com).
  66  *
  67  */
  68 
  69 #include <stdio.h>
  70 #include <stdlib.h>
  71 #include <string.h>
  72 #include <sys/types.h>
  73 #include <unistd.h>
  74 
  75 #include <openssl/e_os2.h>
  76 #include <openssl/crypto.h>
  77 #include <openssl/engine.h>
  78 #include <openssl/dso.h>
  79 #include <openssl/err.h>
  80 #include <openssl/bn.h>
  81 #include <openssl/pem.h>
  82 #ifndef OPENSSL_NO_RSA
  83 #include <openssl/rsa.h>
  84 #endif /* OPENSSL_NO_RSA */
  85 #ifndef OPENSSL_NO_DSA
  86 #include <openssl/dsa.h>
  87 #endif /* OPENSSL_NO_DSA */
  88 #ifndef OPENSSL_NO_DH
  89 #include <openssl/dh.h>
  90 #endif /* OPENSSL_NO_DH */
  91 #include <openssl/rand.h>
  92 #include <openssl/objects.h>
  93 #include <openssl/x509.h>
  94 #include <cryptlib.h>
  95 #include <pthread.h>
  96 
  97 #ifndef OPENSSL_NO_HW
  98 #ifndef OPENSSL_NO_HW_PK11
  99 
 100 #include "cryptoki.h"
 101 #include "pkcs11.h"
 102 #include "hw_pk11_err.h"
 103 
 104 #ifndef OPENSSL_NO_RSA
 105 /* RSA stuff */
 106 static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
 107         unsigned char *to, RSA *rsa, int padding);
 108 static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
 109         unsigned char *to, RSA *rsa, int padding);
 110 static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
 111         unsigned char *to, RSA *rsa, int padding);
 112 static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
 113         unsigned char *to, RSA *rsa, int padding);
 114 static int pk11_RSA_init(RSA *rsa);
 115 static int pk11_RSA_finish(RSA *rsa);
 116 static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
 117         unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
 118 static int pk11_RSA_verify(int dtype, const unsigned char *m,
 119         unsigned int m_len, const unsigned char *sigbuf, unsigned int siglen,
 120         const RSA *rsa);
 121 EVP_PKEY *pk11_load_privkey(ENGINE*, const char *pubkey_file,
 122         UI_METHOD *ui_method, void *callback_data);
 123 EVP_PKEY *pk11_load_pubkey(ENGINE*, const char *pubkey_file,
 124         UI_METHOD *ui_method, void *callback_data);
 125 
 126 static int pk11_RSA_public_encrypt_low(int flen, const unsigned char *from,
 127         unsigned char *to, RSA *rsa);
 128 static int pk11_RSA_private_encrypt_low(int flen, const unsigned char *from,
 129         unsigned char *to, RSA *rsa);
 130 static int pk11_RSA_public_decrypt_low(int flen, const unsigned char *from,
 131         unsigned char *to, RSA *rsa);
 132 static int pk11_RSA_private_decrypt_low(int flen, const unsigned char *from,
 133         unsigned char *to, RSA *rsa);
 134 
 135 static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA* rsa, RSA** key_ptr,
 136         BIGNUM **rsa_n_num, BIGNUM **rsa_e_num, CK_SESSION_HANDLE session);
 137 static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa, RSA** key_ptr,
 138         BIGNUM **rsa_d_num, CK_SESSION_HANDLE session);
 139 
 140 static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa);
 141 static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa);
 142 #endif
 143 
 144 /* DSA stuff */
 145 #ifndef OPENSSL_NO_DSA
 146 static int pk11_DSA_init(DSA *dsa);
 147 static int pk11_DSA_finish(DSA *dsa);
 148 static DSA_SIG *pk11_dsa_do_sign(const unsigned char *dgst, int dlen,
 149         DSA *dsa);
 150 static int pk11_dsa_do_verify(const unsigned char *dgst, int dgst_len,
 151         DSA_SIG *sig, DSA *dsa);
 152 
 153 static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa, DSA **key_ptr,
 154         BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session);
 155 static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa, DSA **key_ptr,
 156         BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session);
 157 
 158 static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa);
 159 static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa);
 160 #endif
 161 
 162 /* DH stuff */
 163 #ifndef OPENSSL_NO_DH
 164 static int pk11_DH_init(DH *dh);
 165 static int pk11_DH_finish(DH *dh);
 166 static int pk11_DH_generate_key(DH *dh);
 167 static int pk11_DH_compute_key(unsigned char *key,
 168         const BIGNUM *pub_key, DH *dh);
 169 
 170 static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh, DH **key_ptr,
 171         BIGNUM **priv_key, CK_SESSION_HANDLE session);
 172 
 173 static int check_new_dh_key(PK11_SESSION *sp, DH *dh);
 174 #endif
 175 
 176 static int init_template_value(BIGNUM *bn, CK_VOID_PTR *pValue,
 177         CK_ULONG *ulValueLen);
 178 
 179 /* Read mode string to be used for fopen() */
 180 #if SOLARIS_OPENSSL
 181 static char *read_mode_flags = "rF";
 182 #else
 183 static char *read_mode_flags = "r";
 184 #endif
 185 
 186 /*
 187  * increment/create reference for an asymmetric key handle via active list
 188  * manipulation. If active list operation fails, unlock (if locked), set error
 189  * variable and jump to the specified label.
 190  */
 191 #define KEY_HANDLE_REFHOLD(key_handle, alg_type, unlock, var, label)    \
 192         {                                                               \
 193         if (sunw_pk11_active_add(key_handle, alg_type) < 0)                  \
 194                 {                                                       \
 195                 var = TRUE;                                             \
 196                 if (unlock)                                             \
 197                         UNLOCK_OBJSTORE(alg_type);                      \
 198                 goto label;                                             \
 199                 }                                                       \
 200         }
 201 
 202 /*
 203  * Find active list entry according to object handle and return pointer to the
 204  * entry otherwise return NULL.
 205  *
 206  * This function presumes it is called with lock protecting the active list
 207  * held.
 208  */
 209 static PK11_active *pk11_active_find(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
 210         {
 211         PK11_active *entry;
 212 
 213         for (entry = active_list[type]; entry != NULL; entry = entry->next)
 214                 if (entry->h == h)
 215                         return (entry);
 216 
 217         return (NULL);
 218         }
 219 
 220 /*
 221  * Search for an entry in the active list using PKCS#11 object handle as a
 222  * search key and return refcnt of the found/created entry or -1 in case of
 223  * failure.
 224  *
 225  * This function presumes it is called with lock protecting the active list
 226  * held.
 227  */
 228 int
 229 sunw_pk11_active_add(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
 230         {
 231         PK11_active *entry = NULL;
 232 
 233         if (h == CK_INVALID_HANDLE)
 234                 {
 235                 PK11err(PK11_F_ACTIVE_ADD, PK11_R_INVALID_HANDLE);
 236                 return (-1);
 237                 }
 238 
 239         /* search for entry in the active list */
 240         if ((entry = pk11_active_find(h, type)) != NULL)
 241                 entry->refcnt++;
 242         else
 243                 {
 244                 /* not found, create new entry and add it to the list */
 245                 entry = OPENSSL_malloc(sizeof (PK11_active));
 246                 if (entry == NULL)
 247                         {
 248                         PK11err(PK11_F_ACTIVE_ADD, PK11_R_MALLOC_FAILURE);
 249                         return (-1);
 250                         }
 251                 entry->h = h;
 252                 entry->refcnt = 1;
 253                 entry->prev = NULL;
 254                 entry->next = NULL;
 255                 /* connect the newly created entry to the list */
 256                 if (active_list[type] == NULL)
 257                         active_list[type] = entry;
 258                 else /* make the entry first in the list */
 259                         {
 260                         entry->next = active_list[type];
 261                         active_list[type]->prev = entry;
 262                         active_list[type] = entry;
 263                         }
 264                 }
 265 
 266         return (entry->refcnt);
 267         }
 268 
 269 /*
 270  * Remove active list entry from the list and free it.
 271  *
 272  * This function presumes it is called with lock protecting the active list
 273  * held.
 274  */
 275 void
 276 sunw_pk11_active_remove(PK11_active *entry, PK11_OPTYPE type)
 277         {
 278         PK11_active *prev_entry;
 279 
 280         /* remove the entry from the list and free it */
 281         if ((prev_entry = entry->prev) != NULL)
 282                 {
 283                 prev_entry->next = entry->next;
 284                 if (entry->next != NULL)
 285                         entry->next->prev = prev_entry;
 286                 }
 287         else
 288                 {
 289                 active_list[type] = entry->next;
 290                 /* we were the first but not the only one */
 291                 if (entry->next != NULL)
 292                         entry->next->prev = NULL;
 293                 }
 294 
 295         /* sanitization */
 296         entry->h = CK_INVALID_HANDLE;
 297         entry->prev = NULL;
 298         entry->next = NULL;
 299         OPENSSL_free(entry);
 300         }
 301 
 302 /* Free all entries from the active list. */
 303 void
 304 sunw_pk11_free_active_list(PK11_OPTYPE type)
 305         {
 306         PK11_active *entry;
 307 
 308         /* only for asymmetric types since only they have C_Find* locks. */
 309         switch (type)
 310                 {
 311                 case OP_RSA:
 312                 case OP_DSA:
 313                 case OP_DH:
 314                         break;
 315                 default:
 316                         return;
 317                 }
 318 
 319         /* see find_lock array definition for more info on object locking */
 320         LOCK_OBJSTORE(type);
 321         while ((entry = active_list[type]) != NULL)
 322                 sunw_pk11_active_remove(entry, type);
 323         UNLOCK_OBJSTORE(type);
 324         }
 325 
 326 /*
 327  * Search for active list entry associated with given PKCS#11 object handle,
 328  * decrement its refcnt and if it drops to 0, disconnect the entry and free it.
 329  *
 330  * Return 1 if the PKCS#11 object associated with the entry has no references,
 331  * return 0 if there is at least one reference, -1 on error.
 332  *
 333  * This function presumes it is called with lock protecting the active list
 334  * held.
 335  */
 336 int
 337 sunw_pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
 338         {
 339         PK11_active *entry = NULL;
 340 
 341         if ((entry = pk11_active_find(h, type)) == NULL)
 342                 {
 343                 PK11err(PK11_F_ACTIVE_DELETE, PK11_R_INVALID_HANDLE);
 344                 return (-1);
 345                 }
 346 
 347         OPENSSL_assert(entry->refcnt > 0);
 348         entry->refcnt--;
 349         if (entry->refcnt == 0)
 350                 {
 351                 sunw_pk11_active_remove(entry, type);
 352                 return (1);
 353                 }
 354 
 355         return (0);
 356         }
 357 
 358 #ifndef OPENSSL_NO_RSA
 359 /* Our internal RSA_METHOD that we provide pointers to */
 360 static RSA_METHOD pk11_rsa =
 361         {
 362         "PKCS#11 RSA method",
 363         pk11_RSA_public_encrypt,                /* rsa_pub_encrypt */
 364         pk11_RSA_public_decrypt,                /* rsa_pub_decrypt */
 365         pk11_RSA_private_encrypt,               /* rsa_priv_encrypt */
 366         pk11_RSA_private_decrypt,               /* rsa_priv_decrypt */
 367         NULL,                                   /* rsa_mod_exp */
 368         NULL,                                   /* bn_mod_exp */
 369         pk11_RSA_init,                          /* init */
 370         pk11_RSA_finish,                        /* finish */
 371         RSA_FLAG_SIGN_VER,                      /* flags */
 372         NULL,                                   /* app_data */
 373         pk11_RSA_sign,                          /* rsa_sign */
 374         pk11_RSA_verify                         /* rsa_verify */
 375         };
 376 
 377 RSA_METHOD *
 378 PK11_RSA(void)
 379         {
 380         return (&pk11_rsa);
 381         }
 382 #endif
 383 
 384 #ifndef OPENSSL_NO_DSA
 385 /* Our internal DSA_METHOD that we provide pointers to */
 386 static DSA_METHOD pk11_dsa =
 387         {
 388         "PKCS#11 DSA method",
 389         pk11_dsa_do_sign,       /* dsa_do_sign */
 390         NULL,                   /* dsa_sign_setup */
 391         pk11_dsa_do_verify,     /* dsa_do_verify */
 392         NULL,                   /* dsa_mod_exp */
 393         NULL,                   /* bn_mod_exp */
 394         pk11_DSA_init,          /* init */
 395         pk11_DSA_finish,        /* finish */
 396         0,                      /* flags */
 397         NULL                    /* app_data */
 398         };
 399 
 400 DSA_METHOD *
 401 PK11_DSA(void)
 402         {
 403         return (&pk11_dsa);
 404         }
 405 #endif
 406 
 407 #ifndef OPENSSL_NO_DH
 408 /*
 409  * PKCS #11 V2.20, section 11.2 specifies that the number of bytes needed for
 410  * output buffer may somewhat exceed the precise number of bytes needed, but
 411  * should not exceed it by a large amount. That may be caused, for example, by
 412  * rounding it up to multiple of X in the underlying bignum library. 8 should be
 413  * enough.
 414  */
 415 #define DH_BUF_RESERVE  8
 416 
 417 /* Our internal DH_METHOD that we provide pointers to */
 418 static DH_METHOD pk11_dh =
 419         {
 420         "PKCS#11 DH method",
 421         pk11_DH_generate_key,   /* generate_key */
 422         pk11_DH_compute_key,    /* compute_key */
 423         NULL,                   /* bn_mod_exp */
 424         pk11_DH_init,           /* init */
 425         pk11_DH_finish,         /* finish */
 426         0,                      /* flags */
 427         NULL,                   /* app_data */
 428         NULL                    /* generate_params */
 429         };
 430 
 431 DH_METHOD *
 432 PK11_DH(void)
 433         {
 434         return (&pk11_dh);
 435         }
 436 #endif
 437 
 438 /* Size of an SSL signature: MD5+SHA1 */
 439 #define SSL_SIG_LENGTH          36
 440 
 441 /* Lengths of DSA data and signature */
 442 #define DSA_DATA_LEN            20
 443 #define DSA_SIGNATURE_LEN       40
 444 
 445 static CK_BBOOL true = TRUE;
 446 static CK_BBOOL false = FALSE;
 447 
 448 #ifndef OPENSSL_NO_RSA
 449 /*
 450  * Similiar to OpenSSL to take advantage of the paddings. The goal is to
 451  * support all paddings in this engine although PK11 library does not
 452  * support all the paddings used in OpenSSL.
 453  * The input errors should have been checked in the padding functions.
 454  */
 455 static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
 456                 unsigned char *to, RSA *rsa, int padding)
 457         {
 458         int i, num = 0, r = -1;
 459         unsigned char *buf = NULL;
 460 
 461         num = BN_num_bytes(rsa->n);
 462         if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
 463                 {
 464                 RSAerr(PK11_F_RSA_PUB_ENC, PK11_R_MALLOC_FAILURE);
 465                 goto err;
 466                 }
 467 
 468         switch (padding)
 469                 {
 470         case RSA_PKCS1_PADDING:
 471                 i = RSA_padding_add_PKCS1_type_2(buf, num, from, flen);
 472                 break;
 473 #ifndef OPENSSL_NO_SHA
 474         case RSA_PKCS1_OAEP_PADDING:
 475                 i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0);
 476                 break;
 477 #endif
 478         case RSA_SSLV23_PADDING:
 479                 i = RSA_padding_add_SSLv23(buf, num, from, flen);
 480                 break;
 481         case RSA_NO_PADDING:
 482                 i = RSA_padding_add_none(buf, num, from, flen);
 483                 break;
 484         default:
 485                 RSAerr(PK11_F_RSA_PUB_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
 486                 goto err;
 487                 }
 488         if (i <= 0) goto err;
 489 
 490         /* PK11 functions are called here */
 491         r = pk11_RSA_public_encrypt_low(num, buf, to, rsa);
 492 err:
 493         if (buf != NULL)
 494                 {
 495                 OPENSSL_cleanse(buf, num);
 496                 OPENSSL_free(buf);
 497                 }
 498         return (r);
 499         }
 500 
 501 
 502 /*
 503  * Similar to Openssl to take advantage of the paddings. The input errors
 504  * should be catched in the padding functions
 505  */
 506 static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
 507         unsigned char *to, RSA *rsa, int padding)
 508         {
 509         int i, num = 0, r = -1;
 510         unsigned char *buf = NULL;
 511 
 512         num = BN_num_bytes(rsa->n);
 513         if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
 514                 {
 515                 RSAerr(PK11_F_RSA_PRIV_ENC, PK11_R_MALLOC_FAILURE);
 516                 goto err;
 517                 }
 518 
 519         switch (padding)
 520                 {
 521         case RSA_PKCS1_PADDING:
 522                 i = RSA_padding_add_PKCS1_type_1(buf, num, from, flen);
 523                 break;
 524         case RSA_NO_PADDING:
 525                 i = RSA_padding_add_none(buf, num, from, flen);
 526                 break;
 527         case RSA_SSLV23_PADDING:
 528         default:
 529                 RSAerr(PK11_F_RSA_PRIV_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
 530                 goto err;
 531                 }
 532         if (i <= 0) goto err;
 533 
 534         /* PK11 functions are called here */
 535         r = pk11_RSA_private_encrypt_low(num, buf, to, rsa);
 536 err:
 537         if (buf != NULL)
 538                 {
 539                 OPENSSL_cleanse(buf, num);
 540                 OPENSSL_free(buf);
 541                 }
 542         return (r);
 543         }
 544 
 545 /* Similar to OpenSSL code. Input errors are also checked here */
 546 static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
 547         unsigned char *to, RSA *rsa, int padding)
 548         {
 549         BIGNUM f;
 550         int j, num = 0, r = -1;
 551         unsigned char *p;
 552         unsigned char *buf = NULL;
 553 
 554         BN_init(&f);
 555 
 556         num = BN_num_bytes(rsa->n);
 557 
 558         if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
 559                 {
 560                 RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_MALLOC_FAILURE);
 561                 goto err;
 562                 }
 563 
 564         /*
 565          * This check was for equality but PGP does evil things
 566          * and chops off the top '0' bytes
 567          */
 568         if (flen > num)
 569                 {
 570                 RSAerr(PK11_F_RSA_PRIV_DEC,
 571                         PK11_R_DATA_GREATER_THAN_MOD_LEN);
 572                 goto err;
 573                 }
 574 
 575         /* make data into a big number */
 576         if (BN_bin2bn(from, (int)flen, &f) == NULL)
 577                 goto err;
 578 
 579         if (BN_ucmp(&f, rsa->n) >= 0)
 580                 {
 581                 RSAerr(PK11_F_RSA_PRIV_DEC,
 582                         PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
 583                 goto err;
 584                 }
 585 
 586         /* PK11 functions are called here */
 587         r = pk11_RSA_private_decrypt_low(flen, from, buf, rsa);
 588 
 589         /*
 590          * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
 591          * Needs to skip these 0's paddings here.
 592          */
 593         for (j = 0; j < r; j++)
 594                 if (buf[j] != 0)
 595                         break;
 596 
 597         p = buf + j;
 598         j = r - j;  /* j is only used with no-padding mode */
 599 
 600         switch (padding)
 601                 {
 602         case RSA_PKCS1_PADDING:
 603                 r = RSA_padding_check_PKCS1_type_2(to, num, p, j, num);
 604                 break;
 605 #ifndef OPENSSL_NO_SHA
 606         case RSA_PKCS1_OAEP_PADDING:
 607                 r = RSA_padding_check_PKCS1_OAEP(to, num, p, j, num, NULL, 0);
 608                 break;
 609 #endif
 610         case RSA_SSLV23_PADDING:
 611                 r = RSA_padding_check_SSLv23(to, num, p, j, num);
 612                 break;
 613         case RSA_NO_PADDING:
 614                 r = RSA_padding_check_none(to, num, p, j, num);
 615                 break;
 616         default:
 617                 RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
 618                 goto err;
 619                 }
 620         if (r < 0)
 621                 RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_PADDING_CHECK_FAILED);
 622 
 623 err:
 624         BN_clear_free(&f);
 625         if (buf != NULL)
 626                 {
 627                 OPENSSL_cleanse(buf, num);
 628                 OPENSSL_free(buf);
 629                 }
 630         return (r);
 631         }
 632 
 633 /* Similar to OpenSSL code. Input errors are also checked here */
 634 static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
 635         unsigned char *to, RSA *rsa, int padding)
 636         {
 637         BIGNUM f;
 638         int i, num = 0, r = -1;
 639         unsigned char *p;
 640         unsigned char *buf = NULL;
 641 
 642         BN_init(&f);
 643         num = BN_num_bytes(rsa->n);
 644         buf = (unsigned char *)OPENSSL_malloc(num);
 645         if (buf == NULL)
 646                 {
 647                 RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_MALLOC_FAILURE);
 648                 goto err;
 649                 }
 650 
 651         /*
 652          * This check was for equality but PGP does evil things
 653          * and chops off the top '0' bytes
 654          */
 655         if (flen > num)
 656                 {
 657                 RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_DATA_GREATER_THAN_MOD_LEN);
 658                 goto err;
 659                 }
 660 
 661         if (BN_bin2bn(from, flen, &f) == NULL)
 662                 goto err;
 663 
 664         if (BN_ucmp(&f, rsa->n) >= 0)
 665                 {
 666                 RSAerr(PK11_F_RSA_PUB_DEC,
 667                         PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
 668                 goto err;
 669                 }
 670 
 671         /* PK11 functions are called here */
 672         r = pk11_RSA_public_decrypt_low(flen, from, buf, rsa);
 673 
 674         /*
 675          * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
 676          * Needs to skip these 0's here
 677          */
 678         for (i = 0; i < r; i++)
 679                 if (buf[i] != 0)
 680                         break;
 681 
 682         p = buf + i;
 683         i = r - i;  /* i is only used with no-padding mode */
 684 
 685         switch (padding)
 686                 {
 687         case RSA_PKCS1_PADDING:
 688                 r = RSA_padding_check_PKCS1_type_1(to, num, p, i, num);
 689                 break;
 690         case RSA_NO_PADDING:
 691                 r = RSA_padding_check_none(to, num, p, i, num);
 692                 break;
 693         default:
 694                 RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
 695                 goto err;
 696                 }
 697         if (r < 0)
 698                 RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_PADDING_CHECK_FAILED);
 699 
 700 err:
 701         BN_clear_free(&f);
 702         if (buf != NULL)
 703                 {
 704                 OPENSSL_cleanse(buf, num);
 705                 OPENSSL_free(buf);
 706                 }
 707         return (r);
 708         }
 709 
 710 /*
 711  * This function implements RSA public encryption using C_EncryptInit and
 712  * C_Encrypt pk11 interfaces. Note that the CKM_RSA_X_509 is used here.
 713  * The calling function allocated sufficient memory in "to" to store results.
 714  */
 715 static int pk11_RSA_public_encrypt_low(int flen,
 716         const unsigned char *from, unsigned char *to, RSA *rsa)
 717         {
 718         CK_ULONG bytes_encrypted = flen;
 719         int retval = -1;
 720         CK_RV rv;
 721         CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
 722         CK_MECHANISM *p_mech = &mech_rsa;
 723         CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
 724         PK11_SESSION *sp;
 725 
 726         if ((sp = pk11_get_session(OP_RSA)) == NULL)
 727                 return (-1);
 728 
 729         (void) check_new_rsa_key_pub(sp, rsa);
 730 
 731         h_pub_key = sp->opdata_rsa_pub_key;
 732         if (h_pub_key == CK_INVALID_HANDLE)
 733                 h_pub_key = sp->opdata_rsa_pub_key =
 734                         pk11_get_public_rsa_key(rsa, &sp->opdata_rsa_pub,
 735                             &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
 736                             sp->session);
 737 
 738         if (h_pub_key != CK_INVALID_HANDLE)
 739                 {
 740                 rv = pFuncList->C_EncryptInit(sp->session, p_mech,
 741                         h_pub_key);
 742 
 743                 if (rv != CKR_OK)
 744                         {
 745                         PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
 746                             PK11_R_ENCRYPTINIT, rv);
 747                         pk11_return_session(sp, OP_RSA);
 748                         return (-1);
 749                         }
 750 
 751                 rv = pFuncList->C_Encrypt(sp->session,
 752                         (unsigned char *)from, flen, to, &bytes_encrypted);
 753 
 754                 if (rv != CKR_OK)
 755                         {
 756                         PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
 757                             PK11_R_ENCRYPT, rv);
 758                         pk11_return_session(sp, OP_RSA);
 759                         return (-1);
 760                         }
 761                 retval = bytes_encrypted;
 762                 }
 763 
 764         pk11_return_session(sp, OP_RSA);
 765         return (retval);
 766         }
 767 
 768 
 769 /*
 770  * This function implements RSA private encryption using C_SignInit and
 771  * C_Sign pk11 APIs. Note that CKM_RSA_X_509 is used here.
 772  * The calling function allocated sufficient memory in "to" to store results.
 773  */
 774 static int pk11_RSA_private_encrypt_low(int flen,
 775         const unsigned char *from, unsigned char *to, RSA *rsa)
 776         {
 777         CK_ULONG ul_sig_len = flen;
 778         int retval = -1;
 779         CK_RV rv;
 780         CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
 781         CK_MECHANISM *p_mech = &mech_rsa;
 782         CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
 783         PK11_SESSION *sp;
 784 
 785         if ((sp = pk11_get_session(OP_RSA)) == NULL)
 786                 return (-1);
 787 
 788         (void) check_new_rsa_key_priv(sp, rsa);
 789 
 790         h_priv_key = sp->opdata_rsa_priv_key;
 791         if (h_priv_key == CK_INVALID_HANDLE)
 792                 h_priv_key = sp->opdata_rsa_priv_key =
 793                         pk11_get_private_rsa_key(rsa, &sp->opdata_rsa_priv,
 794                             &sp->opdata_rsa_d_num, sp->session);
 795 
 796         if (h_priv_key != CK_INVALID_HANDLE)
 797                 {
 798                 rv = pFuncList->C_SignInit(sp->session, p_mech,
 799                         h_priv_key);
 800 
 801                 if (rv != CKR_OK)
 802                         {
 803                         PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW,
 804                             PK11_R_SIGNINIT, rv);
 805                         pk11_return_session(sp, OP_RSA);
 806                         return (-1);
 807                         }
 808 
 809                 rv = pFuncList->C_Sign(sp->session,
 810                         (unsigned char *)from, flen, to, &ul_sig_len);
 811 
 812                 if (rv != CKR_OK)
 813                         {
 814                         PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW, PK11_R_SIGN,
 815                             rv);
 816                         pk11_return_session(sp, OP_RSA);
 817                         return (-1);
 818                         }
 819 
 820                 retval = ul_sig_len;
 821                 }
 822 
 823         pk11_return_session(sp, OP_RSA);
 824         return (retval);
 825         }
 826 
 827 
 828 /*
 829  * This function implements RSA private decryption using C_DecryptInit and
 830  * C_Decrypt pk11 APIs. Note that CKM_RSA_X_509 mechanism is used here.
 831  * The calling function allocated sufficient memory in "to" to store results.
 832  */
 833 static int pk11_RSA_private_decrypt_low(int flen,
 834         const unsigned char *from, unsigned char *to, RSA *rsa)
 835         {
 836         CK_ULONG bytes_decrypted = flen;
 837         int retval = -1;
 838         CK_RV rv;
 839         CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
 840         CK_MECHANISM *p_mech = &mech_rsa;
 841         CK_OBJECT_HANDLE h_priv_key;
 842         PK11_SESSION *sp;
 843 
 844         if ((sp = pk11_get_session(OP_RSA)) == NULL)
 845                 return (-1);
 846 
 847         (void) check_new_rsa_key_priv(sp, rsa);
 848 
 849         h_priv_key = sp->opdata_rsa_priv_key;
 850         if (h_priv_key == CK_INVALID_HANDLE)
 851                 h_priv_key = sp->opdata_rsa_priv_key =
 852                         pk11_get_private_rsa_key(rsa, &sp->opdata_rsa_priv,
 853                             &sp->opdata_rsa_d_num, sp->session);
 854 
 855         if (h_priv_key != CK_INVALID_HANDLE)
 856                 {
 857                 rv = pFuncList->C_DecryptInit(sp->session, p_mech,
 858                         h_priv_key);
 859 
 860                 if (rv != CKR_OK)
 861                         {
 862                         PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
 863                                 PK11_R_DECRYPTINIT, rv);
 864                         pk11_return_session(sp, OP_RSA);
 865                         return (-1);
 866                         }
 867 
 868                 rv = pFuncList->C_Decrypt(sp->session,
 869                         (unsigned char *)from, flen, to, &bytes_decrypted);
 870 
 871                 if (rv != CKR_OK)
 872                         {
 873                         PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
 874                             PK11_R_DECRYPT, rv);
 875                         pk11_return_session(sp, OP_RSA);
 876                         return (-1);
 877                         }
 878                 retval = bytes_decrypted;
 879                 }
 880 
 881         pk11_return_session(sp, OP_RSA);
 882         return (retval);
 883         }
 884 
 885 
 886 /*
 887  * This function implements RSA public decryption using C_VerifyRecoverInit
 888  * and C_VerifyRecover pk11 APIs. Note that CKM_RSA_X_509 is used here.
 889  * The calling function allocated sufficient memory in "to" to store results.
 890  */
 891 static int pk11_RSA_public_decrypt_low(int flen,
 892         const unsigned char *from, unsigned char *to, RSA *rsa)
 893         {
 894         CK_ULONG bytes_decrypted = flen;
 895         int retval = -1;
 896         CK_RV rv;
 897         CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
 898         CK_MECHANISM *p_mech = &mech_rsa;
 899         CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
 900         PK11_SESSION *sp;
 901 
 902         if ((sp = pk11_get_session(OP_RSA)) == NULL)
 903                 return (-1);
 904 
 905         (void) check_new_rsa_key_pub(sp, rsa);
 906 
 907         h_pub_key = sp->opdata_rsa_pub_key;
 908         if (h_pub_key == CK_INVALID_HANDLE)
 909                 h_pub_key = sp->opdata_rsa_pub_key =
 910                         pk11_get_public_rsa_key(rsa, &sp->opdata_rsa_pub,
 911                             &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
 912                             sp->session);
 913 
 914         if (h_pub_key != CK_INVALID_HANDLE)
 915                 {
 916                 rv = pFuncList->C_VerifyRecoverInit(sp->session,
 917                         p_mech, h_pub_key);
 918 
 919                 if (rv != CKR_OK)
 920                         {
 921                         PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
 922                                 PK11_R_VERIFYRECOVERINIT, rv);
 923                         pk11_return_session(sp, OP_RSA);
 924                         return (-1);
 925                         }
 926 
 927                 rv = pFuncList->C_VerifyRecover(sp->session,
 928                         (unsigned char *)from, flen, to, &bytes_decrypted);
 929 
 930                 if (rv != CKR_OK)
 931                         {
 932                         PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
 933                             PK11_R_VERIFYRECOVER, rv);
 934                         pk11_return_session(sp, OP_RSA);
 935                         return (-1);
 936                         }
 937                 retval = bytes_decrypted;
 938                 }
 939 
 940         pk11_return_session(sp, OP_RSA);
 941         return (retval);
 942         }
 943 
 944 static int pk11_RSA_init(RSA *rsa)
 945         {
 946         /*
 947          * This flag in the RSA_METHOD enables the new rsa_sign,
 948          * rsa_verify functions. See rsa.h for details.
 949          */
 950         rsa->flags |= RSA_FLAG_SIGN_VER;
 951 
 952         return (1);
 953         }
 954 
 955 static int pk11_RSA_finish(RSA *rsa)
 956         {
 957         /*
 958          * Since we are overloading OpenSSL's native RSA_eay_finish() we need
 959          * to do the same as in the original function, i.e. to free bignum
 960          * structures.
 961          */
 962         if (rsa->_method_mod_n != NULL)
 963                 BN_MONT_CTX_free(rsa->_method_mod_n);
 964         if (rsa->_method_mod_p != NULL)
 965                 BN_MONT_CTX_free(rsa->_method_mod_p);
 966         if (rsa->_method_mod_q != NULL)
 967                 BN_MONT_CTX_free(rsa->_method_mod_q);
 968 
 969         return (1);
 970         }
 971 
 972 /*
 973  * Standard engine interface function. Majority codes here are from
 974  * rsa/rsa_sign.c. We replaced the decrypt function call by C_Sign of PKCS#11.
 975  * See more details in rsa/rsa_sign.c
 976  */
 977 static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
 978         unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
 979         {
 980         X509_SIG sig;
 981         ASN1_TYPE parameter;
 982         int i, j=0;
 983         unsigned char *p, *s = NULL;
 984         X509_ALGOR algor;
 985         ASN1_OCTET_STRING digest;
 986         CK_RV rv;
 987         CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
 988         CK_MECHANISM *p_mech = &mech_rsa;
 989         CK_OBJECT_HANDLE h_priv_key;
 990         PK11_SESSION *sp = NULL;
 991         int ret = 0;
 992         unsigned long ulsiglen;
 993 
 994         /* Encode the digest */
 995         /* Special case: SSL signature, just check the length */
 996         if (type == NID_md5_sha1)
 997                 {
 998                 if (m_len != SSL_SIG_LENGTH)
 999                         {
1000                         PK11err(PK11_F_RSA_SIGN,
1001                                 PK11_R_INVALID_MESSAGE_LENGTH);
1002                         goto err;
1003                         }
1004                 i = SSL_SIG_LENGTH;
1005                 s = (unsigned char *)m;
1006                 }
1007         else
1008                 {
1009                 sig.algor = &algor;
1010                 sig.algor->algorithm = OBJ_nid2obj(type);
1011                 if (sig.algor->algorithm == NULL)
1012                         {
1013                         PK11err(PK11_F_RSA_SIGN,
1014                                 PK11_R_UNKNOWN_ALGORITHM_TYPE);
1015                         goto err;
1016                         }
1017                 if (sig.algor->algorithm->length == 0)
1018                         {
1019                         PK11err(PK11_F_RSA_SIGN,
1020                                 PK11_R_UNKNOWN_ASN1_OBJECT_ID);
1021                         goto err;
1022                         }
1023                 parameter.type = V_ASN1_NULL;
1024                 parameter.value.ptr = NULL;
1025                 sig.algor->parameter = &parameter;
1026 
1027                 sig.digest = &digest;
1028                 sig.digest->data = (unsigned char *)m;
1029                 sig.digest->length = m_len;
1030 
1031                 i = i2d_X509_SIG(&sig, NULL);
1032                 }
1033 
1034         j = RSA_size(rsa);
1035         if ((i - RSA_PKCS1_PADDING) > j)
1036                 {
1037                 PK11err(PK11_F_RSA_SIGN, PK11_R_DIGEST_TOO_BIG);
1038                 goto err;
1039                 }
1040 
1041         if (type != NID_md5_sha1)
1042                 {
1043                 s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
1044                 if (s == NULL)
1045                         {
1046                         PK11err(PK11_F_RSA_SIGN, PK11_R_MALLOC_FAILURE);
1047                         goto err;
1048                         }
1049                 p = s;
1050                 (void) i2d_X509_SIG(&sig, &p);
1051                 }
1052 
1053         if ((sp = pk11_get_session(OP_RSA)) == NULL)
1054                 goto err;
1055 
1056         (void) check_new_rsa_key_priv(sp, rsa);
1057 
1058         h_priv_key = sp->opdata_rsa_priv_key;
1059         if (h_priv_key == CK_INVALID_HANDLE)
1060                 h_priv_key = sp->opdata_rsa_priv_key =
1061                         pk11_get_private_rsa_key((RSA *)rsa,
1062                             &sp->opdata_rsa_priv,
1063                             &sp->opdata_rsa_d_num, sp->session);
1064 
1065         if (h_priv_key != CK_INVALID_HANDLE)
1066                 {
1067                 rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
1068 
1069                 if (rv != CKR_OK)
1070                         {
1071                         PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGNINIT, rv);
1072                         goto err;
1073                         }
1074 
1075                 ulsiglen = j;
1076                 rv = pFuncList->C_Sign(sp->session, s, i, sigret,
1077                         (CK_ULONG_PTR) &ulsiglen);
1078                 *siglen = ulsiglen;
1079 
1080                 if (rv != CKR_OK)
1081                         {
1082                         PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGN, rv);
1083                         goto err;
1084                         }
1085                 ret = 1;
1086                 }
1087 
1088 err:
1089         if (type != NID_md5_sha1)
1090                 {
1091                 (void) memset(s, 0, (unsigned int)(j + 1));
1092                 OPENSSL_free(s);
1093                 }
1094 
1095         pk11_return_session(sp, OP_RSA);
1096         return (ret);
1097         }
1098 
1099 static int pk11_RSA_verify(int type, const unsigned char *m,
1100         unsigned int m_len, const unsigned char *sigbuf, unsigned int siglen,
1101         const RSA *rsa)
1102         {
1103         X509_SIG sig;
1104         ASN1_TYPE parameter;
1105         int i, j;
1106         unsigned char *p, *s = NULL;
1107         X509_ALGOR algor;
1108         ASN1_OCTET_STRING digest;
1109         CK_RV rv;
1110         CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
1111         CK_MECHANISM *p_mech = &mech_rsa;
1112         CK_OBJECT_HANDLE h_pub_key;
1113         PK11_SESSION *sp = NULL;
1114         int ret = 0;
1115 
1116         /* Encode the digest    */
1117         /* Special case: SSL signature, just check the length */
1118         if (type == NID_md5_sha1)
1119                 {
1120                 if (m_len != SSL_SIG_LENGTH)
1121                         {
1122                         PK11err(PK11_F_RSA_VERIFY,
1123                                 PK11_R_INVALID_MESSAGE_LENGTH);
1124                         goto err;
1125                         }
1126                 i = SSL_SIG_LENGTH;
1127                 s = (unsigned char *)m;
1128                 }
1129         else
1130                 {
1131                 sig.algor = &algor;
1132                 sig.algor->algorithm = OBJ_nid2obj(type);
1133                 if (sig.algor->algorithm == NULL)
1134                         {
1135                         PK11err(PK11_F_RSA_VERIFY,
1136                                 PK11_R_UNKNOWN_ALGORITHM_TYPE);
1137                         goto err;
1138                         }
1139                 if (sig.algor->algorithm->length == 0)
1140                         {
1141                         PK11err(PK11_F_RSA_VERIFY,
1142                                 PK11_R_UNKNOWN_ASN1_OBJECT_ID);
1143                         goto err;
1144                         }
1145                 parameter.type = V_ASN1_NULL;
1146                 parameter.value.ptr = NULL;
1147                 sig.algor->parameter = &parameter;
1148                 sig.digest = &digest;
1149                 sig.digest->data = (unsigned char *)m;
1150                 sig.digest->length = m_len;
1151                 i = i2d_X509_SIG(&sig, NULL);
1152                 }
1153 
1154         j = RSA_size(rsa);
1155         if ((i - RSA_PKCS1_PADDING) > j)
1156                 {
1157                 PK11err(PK11_F_RSA_VERIFY, PK11_R_DIGEST_TOO_BIG);
1158                 goto err;
1159                 }
1160 
1161         if (type != NID_md5_sha1)
1162                 {
1163                 s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
1164                 if (s == NULL)
1165                         {
1166                         PK11err(PK11_F_RSA_VERIFY, PK11_R_MALLOC_FAILURE);
1167                         goto err;
1168                         }
1169                 p = s;
1170                 (void) i2d_X509_SIG(&sig, &p);
1171                 }
1172 
1173         if ((sp = pk11_get_session(OP_RSA)) == NULL)
1174                 goto err;
1175 
1176         (void) check_new_rsa_key_pub(sp, rsa);
1177 
1178         h_pub_key = sp->opdata_rsa_pub_key;
1179         if (h_pub_key == CK_INVALID_HANDLE)
1180                 h_pub_key = sp->opdata_rsa_pub_key =
1181                         pk11_get_public_rsa_key((RSA *)rsa, &sp->opdata_rsa_pub,
1182                             &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
1183                             sp->session);
1184 
1185         if (h_pub_key != CK_INVALID_HANDLE)
1186                 {
1187                 rv = pFuncList->C_VerifyInit(sp->session, p_mech,
1188                         h_pub_key);
1189 
1190                 if (rv != CKR_OK)
1191                         {
1192                         PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFYINIT,
1193                             rv);
1194                         goto err;
1195                         }
1196                 rv = pFuncList->C_Verify(sp->session, s, i, (CK_BYTE_PTR) sigbuf,
1197                         (CK_ULONG)siglen);
1198 
1199                 if (rv != CKR_OK)
1200                         {
1201                         PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFY, rv);
1202                         goto err;
1203                         }
1204                 ret = 1;
1205                 }
1206 
1207 err:
1208         if (type != NID_md5_sha1)
1209                 {
1210                 (void) memset(s, 0, (unsigned int)siglen);
1211                 OPENSSL_free(s);
1212                 }
1213 
1214         pk11_return_session(sp, OP_RSA);
1215         return (ret);
1216         }
1217 
1218 /* load RSA private key from a file */
1219 /* ARGSUSED */
1220 EVP_PKEY *pk11_load_privkey(ENGINE* e, const char *privkey_file,
1221         UI_METHOD *ui_method, void *callback_data)
1222         {
1223         EVP_PKEY *pkey = NULL;
1224         FILE *pubkey;
1225         CK_OBJECT_HANDLE  h_priv_key = CK_INVALID_HANDLE;
1226         RSA *rsa;
1227         PK11_SESSION *sp;
1228 
1229         if ((sp = pk11_get_session(OP_RSA)) == NULL)
1230                 return (NULL);
1231 
1232         if ((pubkey = fopen(privkey_file, read_mode_flags)) != NULL)
1233                 {
1234                 pkey = PEM_read_PrivateKey(pubkey, NULL, NULL, NULL);
1235                 (void) fclose(pubkey);
1236                 if (pkey != NULL)
1237                         {
1238                         rsa = EVP_PKEY_get1_RSA(pkey);
1239                         if (rsa != NULL)
1240                                 {
1241                                 (void) check_new_rsa_key_priv(sp, rsa);
1242 
1243                                 h_priv_key = sp->opdata_rsa_priv_key =
1244                                     pk11_get_private_rsa_key(rsa,
1245                                     &sp->opdata_rsa_priv, &sp->opdata_rsa_d_num,
1246                                     sp->session);
1247                                 if (h_priv_key == CK_INVALID_HANDLE)
1248                                         {
1249                                         EVP_PKEY_free(pkey);
1250                                         pkey = NULL;
1251                                         }
1252                                 }
1253                         else
1254                                 {
1255                                 EVP_PKEY_free(pkey);
1256                                 pkey = NULL;
1257                                 }
1258                         }
1259                 }
1260 
1261         pk11_return_session(sp, OP_RSA);
1262         return (pkey);
1263         }
1264 
1265 /* load RSA public key from a file */
1266 /* ARGSUSED */
1267 EVP_PKEY *pk11_load_pubkey(ENGINE* e, const char *pubkey_file,
1268         UI_METHOD *ui_method, void *callback_data)
1269         {
1270         EVP_PKEY *pkey = NULL;
1271         FILE *pubkey;
1272         CK_OBJECT_HANDLE  h_pub_key = CK_INVALID_HANDLE;
1273         RSA *rsa;
1274         PK11_SESSION *sp;
1275 
1276         if ((sp = pk11_get_session(OP_RSA)) == NULL)
1277                 return (NULL);
1278 
1279         if ((pubkey = fopen(pubkey_file, read_mode_flags)) != NULL)
1280                 {
1281                 pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL);
1282                 (void) fclose(pubkey);
1283                 if (pkey != NULL)
1284                         {
1285                         rsa = EVP_PKEY_get1_RSA(pkey);
1286                         if (rsa != NULL)
1287                                 {
1288                                 (void) check_new_rsa_key_pub(sp, rsa);
1289 
1290                                 h_pub_key = sp->opdata_rsa_pub_key =
1291                                     pk11_get_public_rsa_key(rsa,
1292                                     &sp->opdata_rsa_pub, &sp->opdata_rsa_n_num,
1293                                     &sp->opdata_rsa_e_num, sp->session);
1294                                 if (h_pub_key == CK_INVALID_HANDLE)
1295                                         {
1296                                         EVP_PKEY_free(pkey);
1297                                         pkey = NULL;
1298                                         }
1299                                 }
1300                         else
1301                                 {
1302                                 EVP_PKEY_free(pkey);
1303                                 pkey = NULL;
1304                                 }
1305                         }
1306                 }
1307 
1308         pk11_return_session(sp, OP_RSA);
1309         return (pkey);
1310         }
1311 
1312 /*
1313  * Create a public key object in a session from a given rsa structure.
1314  * The *rsa_n_num and *rsa_e_num pointers are non-NULL for RSA public keys.
1315  */
1316 static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA* rsa,
1317     RSA** key_ptr, BIGNUM **rsa_n_num, BIGNUM **rsa_e_num,
1318     CK_SESSION_HANDLE session)
1319         {
1320         CK_RV rv;
1321         CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
1322         CK_ULONG found;
1323         CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
1324         CK_KEY_TYPE k_type = CKK_RSA;
1325         CK_ULONG ul_key_attr_count = 7;
1326         CK_BBOOL rollback = FALSE;
1327 
1328         CK_ATTRIBUTE  a_key_template[] =
1329                 {
1330                 {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
1331                 {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
1332                 {CKA_TOKEN, &false, sizeof (true)},
1333                 {CKA_ENCRYPT, &true, sizeof (true)},
1334                 {CKA_VERIFY_RECOVER, &true, sizeof (true)},
1335                 {CKA_MODULUS, (void *)NULL, 0},
1336                 {CKA_PUBLIC_EXPONENT, (void *)NULL, 0}
1337                 };
1338 
1339         int i;
1340 
1341         a_key_template[0].pValue = &o_key;
1342         a_key_template[1].pValue = &k_type;
1343 
1344         a_key_template[5].ulValueLen = BN_num_bytes(rsa->n);
1345         a_key_template[5].pValue = (CK_VOID_PTR)OPENSSL_malloc(
1346                 (size_t)a_key_template[5].ulValueLen);
1347         if (a_key_template[5].pValue == NULL)
1348                 {
1349                 PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
1350                 goto malloc_err;
1351                 }
1352 
1353         BN_bn2bin(rsa->n, a_key_template[5].pValue);
1354 
1355         a_key_template[6].ulValueLen = BN_num_bytes(rsa->e);
1356         a_key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
1357                 (size_t)a_key_template[6].ulValueLen);
1358         if (a_key_template[6].pValue == NULL)
1359                 {
1360                 PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
1361                 goto malloc_err;
1362                 }
1363 
1364         BN_bn2bin(rsa->e, a_key_template[6].pValue);
1365 
1366         /* see find_lock array definition for more info on object locking */
1367         LOCK_OBJSTORE(OP_RSA);
1368         rv = pFuncList->C_FindObjectsInit(session, a_key_template,
1369                 ul_key_attr_count);
1370 
1371         if (rv != CKR_OK)
1372                 {
1373                 PK11err_add_data(PK11_F_GET_PUB_RSA_KEY, PK11_R_FINDOBJECTSINIT,
1374                     rv);
1375                 goto err;
1376                 }
1377 
1378         rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
1379 
1380         if (rv != CKR_OK)
1381                 {
1382                 PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
1383                     PK11_R_FINDOBJECTS, rv);
1384                 goto err;
1385                 }
1386 
1387         rv = pFuncList->C_FindObjectsFinal(session);
1388 
1389         if (rv != CKR_OK)
1390                 {
1391                 PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
1392                     PK11_R_FINDOBJECTSFINAL, rv);
1393                 goto err;
1394                 }
1395 
1396         if (found == 0)
1397                 {
1398                 rv = pFuncList->C_CreateObject(session,
1399                         a_key_template, ul_key_attr_count, &h_key);
1400                 if (rv != CKR_OK)
1401                         {
1402                         PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
1403                             PK11_R_CREATEOBJECT, rv);
1404                         goto err;
1405                         }
1406                 }
1407 
1408         if (rsa_n_num != NULL)
1409                 if ((*rsa_n_num = BN_dup(rsa->n)) == NULL)
1410                         {
1411                         PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
1412                         rollback = TRUE;
1413                         goto err;
1414                         }
1415         if (rsa_e_num != NULL)
1416                 if ((*rsa_e_num = BN_dup(rsa->e)) == NULL)
1417                         {
1418                         PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
1419                         BN_free(*rsa_n_num);
1420                         *rsa_n_num = NULL;
1421                         rollback = TRUE;
1422                         goto err;
1423                         }
1424 
1425         /* LINTED: E_CONSTANT_CONDITION */
1426         KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
1427         if (key_ptr != NULL)
1428                 *key_ptr = rsa;
1429 
1430 err:
1431         if (rollback)
1432                 {
1433                 /*
1434                  * We do not care about the return value from C_DestroyObject()
1435                  * since we are doing rollback.
1436                  */
1437                 if (found == 0)
1438                         (void) pFuncList->C_DestroyObject(session, h_key);
1439                 h_key = CK_INVALID_HANDLE;
1440                 }
1441 
1442         UNLOCK_OBJSTORE(OP_RSA);
1443 
1444 malloc_err:
1445         for (i = 5; i <= 6; i++)
1446                 {
1447                 if (a_key_template[i].pValue != NULL)
1448                         {
1449                         OPENSSL_free(a_key_template[i].pValue);
1450                         a_key_template[i].pValue = NULL;
1451                         }
1452                 }
1453 
1454         return (h_key);
1455         }
1456 
1457 /*
1458  * Create a private key object in the session from a given rsa structure.
1459  * The *rsa_d_num pointer is non-NULL for RSA private keys.
1460  */
1461 static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa,
1462     RSA** key_ptr, BIGNUM **rsa_d_num, CK_SESSION_HANDLE session)
1463         {
1464         CK_RV rv;
1465         CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
1466         int i;
1467         CK_ULONG found;
1468         CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
1469         CK_KEY_TYPE k_type = CKK_RSA;
1470         CK_ULONG ul_key_attr_count = 14;
1471         CK_BBOOL rollback = FALSE;
1472 
1473         /* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys */
1474         CK_ATTRIBUTE  a_key_template[] =
1475                 {
1476                 {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
1477                 {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
1478                 {CKA_TOKEN, &false, sizeof (true)},
1479                 {CKA_SENSITIVE, &false, sizeof (true)},
1480                 {CKA_DECRYPT, &true, sizeof (true)},
1481                 {CKA_SIGN, &true, sizeof (true)},
1482                 {CKA_MODULUS, (void *)NULL, 0},
1483                 {CKA_PUBLIC_EXPONENT, (void *)NULL, 0},
1484                 {CKA_PRIVATE_EXPONENT, (void *)NULL, 0},
1485                 {CKA_PRIME_1, (void *)NULL, 0},
1486                 {CKA_PRIME_2, (void *)NULL, 0},
1487                 {CKA_EXPONENT_1, (void *)NULL, 0},
1488                 {CKA_EXPONENT_2, (void *)NULL, 0},
1489                 {CKA_COEFFICIENT, (void *)NULL, 0}
1490                 };
1491 
1492         a_key_template[0].pValue = &o_key;
1493         a_key_template[1].pValue = &k_type;
1494 
1495         /* Put the private key components into the template */
1496         if (init_template_value(rsa->n, &a_key_template[6].pValue,
1497                 &a_key_template[6].ulValueLen) == 0 ||
1498             init_template_value(rsa->e, &a_key_template[7].pValue,
1499                 &a_key_template[7].ulValueLen) == 0 ||
1500             init_template_value(rsa->d, &a_key_template[8].pValue,
1501                 &a_key_template[8].ulValueLen) == 0 ||
1502             init_template_value(rsa->p, &a_key_template[9].pValue,
1503                 &a_key_template[9].ulValueLen) == 0 ||
1504             init_template_value(rsa->q, &a_key_template[10].pValue,
1505                 &a_key_template[10].ulValueLen) == 0 ||
1506             init_template_value(rsa->dmp1, &a_key_template[11].pValue,
1507                 &a_key_template[11].ulValueLen) == 0 ||
1508             init_template_value(rsa->dmq1, &a_key_template[12].pValue,
1509                 &a_key_template[12].ulValueLen) == 0 ||
1510             init_template_value(rsa->iqmp, &a_key_template[13].pValue,
1511                 &a_key_template[13].ulValueLen) == 0)
1512                 {
1513                 PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
1514                 goto malloc_err;
1515                 }
1516 
1517         /* see find_lock array definition for more info on object locking */
1518         LOCK_OBJSTORE(OP_RSA);
1519         rv = pFuncList->C_FindObjectsInit(session, a_key_template,
1520                 ul_key_attr_count);
1521 
1522         if (rv != CKR_OK)
1523                 {
1524                 PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
1525                     PK11_R_FINDOBJECTSINIT, rv);
1526                 goto err;
1527                 }
1528 
1529         rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
1530 
1531         if (rv != CKR_OK)
1532                 {
1533                 PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
1534                     PK11_R_FINDOBJECTS, rv);
1535                 goto err;
1536                 }
1537 
1538         rv = pFuncList->C_FindObjectsFinal(session);
1539 
1540         if (rv != CKR_OK)
1541                 {
1542                 PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
1543                     PK11_R_FINDOBJECTSFINAL, rv);
1544                 goto err;
1545                 }
1546 
1547         if (found == 0)
1548                 {
1549                 rv = pFuncList->C_CreateObject(session,
1550                         a_key_template, ul_key_attr_count, &h_key);
1551                 if (rv != CKR_OK)
1552                         {
1553                         PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
1554                                 PK11_R_CREATEOBJECT, rv);
1555                         goto err;
1556                         }
1557                 }
1558 
1559         if (rsa_d_num != NULL)
1560                 if ((*rsa_d_num = BN_dup(rsa->d)) == NULL)
1561                         {
1562                         PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
1563                         rollback = TRUE;
1564                         goto err;
1565                         }
1566 
1567         /* LINTED: E_CONSTANT_CONDITION */
1568         KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
1569         if (key_ptr != NULL)
1570                 *key_ptr = rsa;
1571 
1572 err:
1573         if (rollback)
1574                 {
1575                 /*
1576                  * We do not care about the return value from C_DestroyObject()
1577                  * since we are doing rollback.
1578                  */
1579                 if (found == 0)
1580                         (void) pFuncList->C_DestroyObject(session, h_key);
1581                 h_key = CK_INVALID_HANDLE;
1582                 }
1583 
1584         UNLOCK_OBJSTORE(OP_RSA);
1585 
1586 malloc_err:
1587         /*
1588          * 6 to 13 entries in the key template are key components.
1589          * They need to be freed apon exit or error.
1590          */
1591         for (i = 6; i <= 13; i++)
1592                 {
1593                 if (a_key_template[i].pValue != NULL)
1594                         {
1595                         (void) memset(a_key_template[i].pValue, 0,
1596                                 a_key_template[i].ulValueLen);
1597                         OPENSSL_free(a_key_template[i].pValue);
1598                         a_key_template[i].pValue = NULL;
1599                         }
1600                 }
1601 
1602         return (h_key);
1603         }
1604 
1605 /*
1606  * Check for cache miss and clean the object pointer and handle
1607  * in such case. Return 1 for cache hit, 0 for cache miss.
1608  */
1609 static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa)
1610         {
1611         /*
1612          * Provide protection against RSA structure reuse by making the
1613          * check for cache hit stronger. Only public components of RSA
1614          * key matter here so it is sufficient to compare them with values
1615          * cached in PK11_SESSION structure.
1616          */
1617         if ((sp->opdata_rsa_pub != rsa) ||
1618             (BN_cmp(sp->opdata_rsa_n_num, rsa->n) != 0) ||
1619             (BN_cmp(sp->opdata_rsa_e_num, rsa->e) != 0))
1620                 {
1621                 /*
1622                  * We do not check the return value because even in case of
1623                  * failure the sp structure will have both key pointer
1624                  * and object handle cleaned and pk11_destroy_object()
1625                  * reports the failure to the OpenSSL error message buffer.
1626                  */
1627                 (void) pk11_destroy_rsa_object_pub(sp, TRUE);
1628                 return (0);
1629                 }
1630         return (1);
1631         }
1632 
1633 /*
1634  * Check for cache miss and clean the object pointer and handle
1635  * in such case. Return 1 for cache hit, 0 for cache miss.
1636  */
1637 static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa)
1638         {
1639         /*
1640          * Provide protection against RSA structure reuse by making the
1641          * check for cache hit stronger. Comparing private exponent of RSA
1642          * key with value cached in PK11_SESSION structure should
1643          * be sufficient.
1644          */
1645         if ((sp->opdata_rsa_priv != rsa) ||
1646             (BN_cmp(sp->opdata_rsa_d_num, rsa->d) != 0))
1647                 {
1648                 /*
1649                  * We do not check the return value because even in case of
1650                  * failure the sp structure will have both key pointer
1651                  * and object handle cleaned and pk11_destroy_object()
1652                  * reports the failure to the OpenSSL error message buffer.
1653                  */
1654                 (void) pk11_destroy_rsa_object_priv(sp, TRUE);
1655                 return (0);
1656                 }
1657         return (1);
1658         }
1659 #endif
1660 
1661 #ifndef OPENSSL_NO_DSA
1662 /* The DSA function implementation */
1663 /* ARGSUSED */
1664 static int pk11_DSA_init(DSA *dsa)
1665         {
1666         return (1);
1667         }
1668 
1669 /* ARGSUSED */
1670 static int pk11_DSA_finish(DSA *dsa)
1671         {
1672         return (1);
1673         }
1674 
1675 
1676 static DSA_SIG *
1677 pk11_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
1678         {
1679         BIGNUM *r = NULL, *s = NULL;
1680         int i;
1681         DSA_SIG *dsa_sig = NULL;
1682 
1683         CK_RV rv;
1684         CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
1685         CK_MECHANISM *p_mech = &Mechanism_dsa;
1686         CK_OBJECT_HANDLE h_priv_key;
1687 
1688         /*
1689          * The signature is the concatenation of r and s,
1690          * each is 20 bytes long
1691          */
1692         unsigned char sigret[DSA_SIGNATURE_LEN];
1693         unsigned long siglen = DSA_SIGNATURE_LEN;
1694         unsigned int siglen2 = DSA_SIGNATURE_LEN / 2;
1695 
1696         PK11_SESSION *sp = NULL;
1697 
1698         if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
1699                 {
1700                 PK11err(PK11_F_DSA_SIGN, PK11_R_MISSING_KEY_COMPONENT);
1701                 goto ret;
1702                 }
1703 
1704         i = BN_num_bytes(dsa->q); /* should be 20 */
1705         if (dlen > i)
1706                 {
1707                 PK11err(PK11_F_DSA_SIGN, PK11_R_INVALID_SIGNATURE_LENGTH);
1708                 goto ret;
1709                 }
1710 
1711         if ((sp = pk11_get_session(OP_DSA)) == NULL)
1712                 goto ret;
1713 
1714         (void) check_new_dsa_key_priv(sp, dsa);
1715 
1716         h_priv_key = sp->opdata_dsa_priv_key;
1717         if (h_priv_key == CK_INVALID_HANDLE)
1718                 h_priv_key = sp->opdata_dsa_priv_key =
1719                         pk11_get_private_dsa_key((DSA *)dsa,
1720                             &sp->opdata_dsa_priv,
1721                             &sp->opdata_dsa_priv_num, sp->session);
1722 
1723         if (h_priv_key != CK_INVALID_HANDLE)
1724                 {
1725                 rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
1726 
1727                 if (rv != CKR_OK)
1728                         {
1729                         PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGNINIT, rv);
1730                         goto ret;
1731                         }
1732 
1733                         (void) memset(sigret, 0, siglen);
1734                         rv = pFuncList->C_Sign(sp->session,
1735                             (unsigned char *) dgst, dlen, sigret,
1736                             (CK_ULONG_PTR) &siglen);
1737 
1738                 if (rv != CKR_OK)
1739                         {
1740                         PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGN, rv);
1741                         goto ret;
1742                         }
1743                 }
1744 
1745 
1746         if ((s = BN_new()) == NULL)
1747                 {
1748                 PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
1749                 goto ret;
1750                 }
1751 
1752         if ((r = BN_new()) == NULL)
1753                 {
1754                 PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
1755                 goto ret;
1756                 }
1757 
1758         if ((dsa_sig = DSA_SIG_new()) == NULL)
1759                 {
1760                 PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
1761                 goto ret;
1762                 }
1763 
1764         if (BN_bin2bn(sigret, siglen2, r) == NULL ||
1765             BN_bin2bn(&sigret[siglen2], siglen2, s) == NULL)
1766                 {
1767                 PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
1768                 goto ret;
1769                 }
1770 
1771         dsa_sig->r = r;
1772         dsa_sig->s = s;
1773 
1774 ret:
1775         if (dsa_sig == NULL)
1776                 {
1777                 if (r != NULL)
1778                         BN_free(r);
1779                 if (s != NULL)
1780                         BN_free(s);
1781                 }
1782 
1783         pk11_return_session(sp, OP_DSA);
1784         return (dsa_sig);
1785         }
1786 
1787 static int
1788 pk11_dsa_do_verify(const unsigned char *dgst, int dlen, DSA_SIG *sig,
1789         DSA *dsa)
1790         {
1791         int i;
1792         CK_RV rv;
1793         int retval = 0;
1794         CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
1795         CK_MECHANISM *p_mech = &Mechanism_dsa;
1796         CK_OBJECT_HANDLE h_pub_key;
1797 
1798         unsigned char sigbuf[DSA_SIGNATURE_LEN];
1799         unsigned long siglen = DSA_SIGNATURE_LEN;
1800         unsigned long siglen2 = DSA_SIGNATURE_LEN/2;
1801 
1802         PK11_SESSION *sp = NULL;
1803 
1804         if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0)
1805                 {
1806                 PK11err(PK11_F_DSA_VERIFY,
1807                         PK11_R_INVALID_DSA_SIGNATURE_R);
1808                 goto ret;
1809                 }
1810 
1811         if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0)
1812                 {
1813                 PK11err(PK11_F_DSA_VERIFY,
1814                         PK11_R_INVALID_DSA_SIGNATURE_S);
1815                 goto ret;
1816                 }
1817 
1818         i = BN_num_bytes(dsa->q); /* should be 20 */
1819 
1820         if (dlen > i)
1821                 {
1822                 PK11err(PK11_F_DSA_VERIFY,
1823                         PK11_R_INVALID_SIGNATURE_LENGTH);
1824                 goto ret;
1825                 }
1826 
1827         if ((sp = pk11_get_session(OP_DSA)) == NULL)
1828                 goto ret;
1829 
1830         (void) check_new_dsa_key_pub(sp, dsa);
1831 
1832         h_pub_key = sp->opdata_dsa_pub_key;
1833         if (h_pub_key == CK_INVALID_HANDLE)
1834                 h_pub_key = sp->opdata_dsa_pub_key =
1835                         pk11_get_public_dsa_key((DSA *)dsa, &sp->opdata_dsa_pub,
1836                             &sp->opdata_dsa_pub_num, sp->session);
1837 
1838         if (h_pub_key != CK_INVALID_HANDLE)
1839                 {
1840                 rv = pFuncList->C_VerifyInit(sp->session, p_mech,
1841                         h_pub_key);
1842 
1843                 if (rv != CKR_OK)
1844                         {
1845                         PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFYINIT,
1846                             rv);
1847                         goto ret;
1848                         }
1849 
1850                 /*
1851                  * The representation of each of the two big numbers could
1852                  * be shorter than DSA_SIGNATURE_LEN/2 bytes so we need
1853                  * to act accordingly and shift if necessary.
1854                  */
1855                 (void) memset(sigbuf, 0, siglen);
1856                 BN_bn2bin(sig->r, sigbuf + siglen2 - BN_num_bytes(sig->r));
1857                 BN_bn2bin(sig->s, &sigbuf[siglen2] + siglen2 -
1858                     BN_num_bytes(sig->s));
1859 
1860                 rv = pFuncList->C_Verify(sp->session,
1861                         (unsigned char *) dgst, dlen, sigbuf, (CK_ULONG)siglen);
1862 
1863                 if (rv != CKR_OK)
1864                         {
1865                         PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFY, rv);
1866                         goto ret;
1867                         }
1868                 }
1869 
1870         retval = 1;
1871 ret:
1872 
1873         pk11_return_session(sp, OP_DSA);
1874         return (retval);
1875         }
1876 
1877 
1878 /*
1879  * Create a public key object in a session from a given dsa structure.
1880  * The *dsa_pub_num pointer is non-NULL for DSA public keys.
1881  */
1882 static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa,
1883     DSA **key_ptr, BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session)
1884         {
1885         CK_RV rv;
1886         CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
1887         CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
1888         CK_ULONG found;
1889         CK_KEY_TYPE k_type = CKK_DSA;
1890         CK_ULONG ul_key_attr_count = 8;
1891         CK_BBOOL rollback = FALSE;
1892         int i;
1893 
1894         CK_ATTRIBUTE  a_key_template[] =
1895                 {
1896                 {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
1897                 {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
1898                 {CKA_TOKEN, &false, sizeof (true)},
1899                 {CKA_VERIFY, &true, sizeof (true)},
1900                 {CKA_PRIME, (void *)NULL, 0},           /* p */
1901                 {CKA_SUBPRIME, (void *)NULL, 0},        /* q */
1902                 {CKA_BASE, (void *)NULL, 0},            /* g */
1903                 {CKA_VALUE, (void *)NULL, 0}            /* pub_key - y */
1904                 };
1905 
1906         a_key_template[0].pValue = &o_key;
1907         a_key_template[1].pValue = &k_type;
1908 
1909         if (init_template_value(dsa->p, &a_key_template[4].pValue,
1910                 &a_key_template[4].ulValueLen) == 0 ||
1911             init_template_value(dsa->q, &a_key_template[5].pValue,
1912                 &a_key_template[5].ulValueLen) == 0 ||
1913             init_template_value(dsa->g, &a_key_template[6].pValue,
1914                 &a_key_template[6].ulValueLen) == 0 ||
1915             init_template_value(dsa->pub_key, &a_key_template[7].pValue,
1916                 &a_key_template[7].ulValueLen) == 0)
1917                 {
1918                 PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
1919                 goto malloc_err;
1920                 }
1921 
1922         /* see find_lock array definition for more info on object locking */
1923         LOCK_OBJSTORE(OP_DSA);
1924         rv = pFuncList->C_FindObjectsInit(session, a_key_template,
1925                 ul_key_attr_count);
1926 
1927         if (rv != CKR_OK)
1928                 {
1929                 PK11err_add_data(PK11_F_GET_PUB_DSA_KEY, PK11_R_FINDOBJECTSINIT,
1930                     rv);
1931                 goto err;
1932                 }
1933 
1934         rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
1935 
1936         if (rv != CKR_OK)
1937                 {
1938                 PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
1939                     PK11_R_FINDOBJECTS, rv);
1940                 goto err;
1941                 }
1942 
1943         rv = pFuncList->C_FindObjectsFinal(session);
1944 
1945         if (rv != CKR_OK)
1946                 {
1947                 PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
1948                     PK11_R_FINDOBJECTSFINAL, rv);
1949                 goto err;
1950                 }
1951 
1952         if (found == 0)
1953                 {
1954                 rv = pFuncList->C_CreateObject(session,
1955                         a_key_template, ul_key_attr_count, &h_key);
1956                 if (rv != CKR_OK)
1957                         {
1958                         PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
1959                             PK11_R_CREATEOBJECT, rv);
1960                         goto err;
1961                         }
1962                 }
1963 
1964         if (dsa_pub_num != NULL)
1965                 if ((*dsa_pub_num = BN_dup(dsa->pub_key)) == NULL)
1966                         {
1967                         PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
1968                         rollback = TRUE;
1969                         goto err;
1970                         }
1971 
1972         /* LINTED: E_CONSTANT_CONDITION */
1973         KEY_HANDLE_REFHOLD(h_key, OP_DSA, FALSE, rollback, err);
1974         if (key_ptr != NULL)
1975                 *key_ptr = dsa;
1976 
1977 err:
1978         if (rollback)
1979                 {
1980                 /*
1981                  * We do not care about the return value from C_DestroyObject()
1982                  * since we are doing rollback.
1983                  */
1984                 if (found == 0)
1985                         (void) pFuncList->C_DestroyObject(session, h_key);
1986                 h_key = CK_INVALID_HANDLE;
1987                 }
1988 
1989         UNLOCK_OBJSTORE(OP_DSA);
1990 
1991 malloc_err:
1992         for (i = 4; i <= 7; i++)
1993                 {
1994                 if (a_key_template[i].pValue != NULL)
1995                         {
1996                         OPENSSL_free(a_key_template[i].pValue);
1997                         a_key_template[i].pValue = NULL;
1998                         }
1999                 }
2000 
2001         return (h_key);
2002         }
2003 
2004 /*
2005  * Create a private key object in the session from a given dsa structure
2006  * The *dsa_priv_num pointer is non-NULL for DSA private keys.
2007  */
2008 static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa,
2009     DSA **key_ptr, BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session)
2010         {
2011         CK_RV rv;
2012         CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
2013         CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
2014         int i;
2015         CK_ULONG found;
2016         CK_KEY_TYPE k_type = CKK_DSA;
2017         CK_ULONG ul_key_attr_count = 9;
2018         CK_BBOOL rollback = FALSE;
2019 
2020         /* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys */
2021         CK_ATTRIBUTE  a_key_template[] =
2022                 {
2023                 {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
2024                 {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
2025                 {CKA_TOKEN, &false, sizeof (true)},
2026                 {CKA_SENSITIVE, &false, sizeof (true)},
2027                 {CKA_SIGN, &true, sizeof (true)},
2028                 {CKA_PRIME, (void *)NULL, 0},           /* p */
2029                 {CKA_SUBPRIME, (void *)NULL, 0},        /* q */
2030                 {CKA_BASE, (void *)NULL, 0},            /* g */
2031                 {CKA_VALUE, (void *)NULL, 0}            /* priv_key - x */
2032                 };
2033 
2034         a_key_template[0].pValue = &o_key;
2035         a_key_template[1].pValue = &k_type;
2036 
2037         /* Put the private key components into the template */
2038         if (init_template_value(dsa->p, &a_key_template[5].pValue,
2039                 &a_key_template[5].ulValueLen) == 0 ||
2040             init_template_value(dsa->q, &a_key_template[6].pValue,
2041                 &a_key_template[6].ulValueLen) == 0 ||
2042             init_template_value(dsa->g, &a_key_template[7].pValue,
2043                 &a_key_template[7].ulValueLen) == 0 ||
2044             init_template_value(dsa->priv_key, &a_key_template[8].pValue,
2045                 &a_key_template[8].ulValueLen) == 0)
2046                 {
2047                 PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
2048                 goto malloc_err;
2049                 }
2050 
2051         /* see find_lock array definition for more info on object locking */
2052         LOCK_OBJSTORE(OP_DSA);
2053         rv = pFuncList->C_FindObjectsInit(session, a_key_template,
2054                 ul_key_attr_count);
2055 
2056         if (rv != CKR_OK)
2057                 {
2058                 PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
2059                     PK11_R_FINDOBJECTSINIT, rv);
2060                 goto err;
2061                 }
2062 
2063         rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
2064 
2065         if (rv != CKR_OK)
2066                 {
2067                 PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
2068                     PK11_R_FINDOBJECTS, rv);
2069                 goto err;
2070                 }
2071 
2072         rv = pFuncList->C_FindObjectsFinal(session);
2073 
2074         if (rv != CKR_OK)
2075                 {
2076                 PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
2077                     PK11_R_FINDOBJECTSFINAL, rv);
2078                 goto err;
2079                 }
2080 
2081         if (found == 0)
2082                 {
2083                 rv = pFuncList->C_CreateObject(session,
2084                         a_key_template, ul_key_attr_count, &h_key);
2085                 if (rv != CKR_OK)
2086                         {
2087                         PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
2088                             PK11_R_CREATEOBJECT, rv);
2089                         goto err;
2090                         }
2091                 }
2092 
2093         if (dsa_priv_num != NULL)
2094                 if ((*dsa_priv_num = BN_dup(dsa->priv_key)) == NULL)
2095                         {
2096                         PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
2097                         rollback = TRUE;
2098                         goto err;
2099                         }
2100 
2101         /* LINTED: E_CONSTANT_CONDITION */
2102         KEY_HANDLE_REFHOLD(h_key, OP_DSA, FALSE, rollback, err);
2103         if (key_ptr != NULL)
2104                 *key_ptr = dsa;
2105 
2106 err:
2107         if (rollback)
2108                 {
2109                 /*
2110                  * We do not care about the return value from C_DestroyObject()
2111                  * since we are doing rollback.
2112                  */
2113                 if (found == 0)
2114                         (void) pFuncList->C_DestroyObject(session, h_key);
2115                 h_key = CK_INVALID_HANDLE;
2116                 }
2117 
2118         UNLOCK_OBJSTORE(OP_DSA);
2119 
2120 malloc_err:
2121         /*
2122          * 5 to 8 entries in the key template are key components.
2123          * They need to be freed apon exit or error.
2124          */
2125         for (i = 5; i <= 8; i++)
2126                 {
2127                 if (a_key_template[i].pValue != NULL)
2128                         {
2129                         (void) memset(a_key_template[i].pValue, 0,
2130                                 a_key_template[i].ulValueLen);
2131                         OPENSSL_free(a_key_template[i].pValue);
2132                         a_key_template[i].pValue = NULL;
2133                         }
2134                 }
2135 
2136         return (h_key);
2137         }
2138 
2139 /*
2140  * Check for cache miss and clean the object pointer and handle
2141  * in such case. Return 1 for cache hit, 0 for cache miss.
2142  */
2143 static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa)
2144         {
2145         /*
2146          * Provide protection against DSA structure reuse by making the
2147          * check for cache hit stronger. Only public key component of DSA
2148          * key matters here so it is sufficient to compare it with value
2149          * cached in PK11_SESSION structure.
2150          */
2151         if ((sp->opdata_dsa_pub != dsa) ||
2152             (BN_cmp(sp->opdata_dsa_pub_num, dsa->pub_key) != 0))
2153                 {
2154                 /*
2155                  * We do not check the return value because even in case of
2156                  * failure the sp structure will have both key pointer
2157                  * and object handle cleaned and pk11_destroy_object()
2158                  * reports the failure to the OpenSSL error message buffer.
2159                  */
2160                 (void) pk11_destroy_dsa_object_pub(sp, TRUE);
2161                 return (0);
2162                 }
2163         return (1);
2164         }
2165 
2166 /*
2167  * Check for cache miss and clean the object pointer and handle
2168  * in such case. Return 1 for cache hit, 0 for cache miss.
2169  */
2170 static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa)
2171         {
2172         /*
2173          * Provide protection against DSA structure reuse by making the
2174          * check for cache hit stronger. Only private key component of DSA
2175          * key matters here so it is sufficient to compare it with value
2176          * cached in PK11_SESSION structure.
2177          */
2178         if ((sp->opdata_dsa_priv != dsa) ||
2179             (BN_cmp(sp->opdata_dsa_priv_num, dsa->priv_key) != 0))
2180                 {
2181                 /*
2182                  * We do not check the return value because even in case of
2183                  * failure the sp structure will have both key pointer
2184                  * and object handle cleaned and pk11_destroy_object()
2185                  * reports the failure to the OpenSSL error message buffer.
2186                  */
2187                 (void) pk11_destroy_dsa_object_priv(sp, TRUE);
2188                 return (0);
2189                 }
2190         return (1);
2191         }
2192 #endif
2193 
2194 
2195 #ifndef OPENSSL_NO_DH
2196 /* The DH function implementation */
2197 /* ARGSUSED */
2198 static int pk11_DH_init(DH *dh)
2199         {
2200         return (1);
2201         }
2202 
2203 /* ARGSUSED */
2204 static int pk11_DH_finish(DH *dh)
2205         {
2206         return (1);
2207         }
2208 
2209 /*
2210  * Generate DH key-pair.
2211  *
2212  * Warning: Unlike OpenSSL's DH_generate_key(3) we ignore dh->priv_key
2213  * and override it even if it is set. OpenSSL does not touch dh->priv_key
2214  * if set and just computes dh->pub_key. It looks like PKCS#11 standard
2215  * is not capable of providing this functionality. This could be a problem
2216  * for applications relying on OpenSSL's semantics.
2217  */
2218 static int pk11_DH_generate_key(DH *dh)
2219         {
2220         CK_ULONG i;
2221         CK_RV rv, rv1;
2222         int reuse_mem_len = 0, ret = 0;
2223         PK11_SESSION *sp = NULL;
2224         CK_BYTE_PTR reuse_mem;
2225 
2226         CK_MECHANISM mechanism = {CKM_DH_PKCS_KEY_PAIR_GEN, NULL_PTR, 0};
2227         CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
2228         CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
2229 
2230         CK_ULONG ul_pub_key_attr_count = 3;
2231         CK_ATTRIBUTE pub_key_template[] =
2232                 {
2233                 {CKA_PRIVATE, &false, sizeof (false)},
2234                 {CKA_PRIME, (void *)NULL, 0},
2235                 {CKA_BASE, (void *)NULL, 0}
2236                 };
2237 
2238         CK_ULONG ul_priv_key_attr_count = 3;
2239         CK_ATTRIBUTE priv_key_template[] =
2240                 {
2241                 {CKA_PRIVATE, &false, sizeof (false)},
2242                 {CKA_SENSITIVE, &false, sizeof (false)},
2243                 {CKA_DERIVE, &true, sizeof (true)}
2244                 };
2245 
2246         CK_ULONG pub_key_attr_result_count = 1;
2247         CK_ATTRIBUTE pub_key_result[] =
2248                 {
2249                 {CKA_VALUE, (void *)NULL, 0}
2250                 };
2251 
2252         CK_ULONG priv_key_attr_result_count = 1;
2253         CK_ATTRIBUTE priv_key_result[] =
2254                 {
2255                 {CKA_VALUE, (void *)NULL, 0}
2256                 };
2257 
2258         pub_key_template[1].ulValueLen = BN_num_bytes(dh->p);
2259         if (pub_key_template[1].ulValueLen > 0)
2260                 {
2261                 /*
2262                  * We must not increase ulValueLen by DH_BUF_RESERVE since that
2263                  * could cause the same rounding problem. See definition of
2264                  * DH_BUF_RESERVE above.
2265                  */
2266                 pub_key_template[1].pValue =
2267                         OPENSSL_malloc(pub_key_template[1].ulValueLen +
2268                         DH_BUF_RESERVE);
2269                 if (pub_key_template[1].pValue == NULL)
2270                         {
2271                         PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
2272                         goto err;
2273                         }
2274 
2275                 i = BN_bn2bin(dh->p, pub_key_template[1].pValue);
2276                 }
2277         else
2278                 goto err;
2279 
2280         pub_key_template[2].ulValueLen = BN_num_bytes(dh->g);
2281         if (pub_key_template[2].ulValueLen > 0)
2282                 {
2283                 pub_key_template[2].pValue =
2284                         OPENSSL_malloc(pub_key_template[2].ulValueLen +
2285                         DH_BUF_RESERVE);
2286                 if (pub_key_template[2].pValue == NULL)
2287                         {
2288                         PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
2289                         goto err;
2290                         }
2291 
2292                 i = BN_bn2bin(dh->g, pub_key_template[2].pValue);
2293                 }
2294         else
2295                 goto err;
2296 
2297         /*
2298          * Note: we are only using PK11_SESSION structure for getting
2299          *       a session handle. The objects created in this function are
2300          *       destroyed before return and thus not cached.
2301          */
2302         if ((sp = pk11_get_session(OP_DH)) == NULL)
2303                 goto err;
2304 
2305         rv = pFuncList->C_GenerateKeyPair(sp->session,
2306             &mechanism,
2307             pub_key_template,
2308             ul_pub_key_attr_count,
2309             priv_key_template,
2310             ul_priv_key_attr_count,
2311             &h_pub_key,
2312             &h_priv_key);
2313         if (rv != CKR_OK)
2314                 {
2315                 PK11err_add_data(PK11_F_DH_GEN_KEY, PK11_R_GEN_KEY, rv);
2316                 goto err;
2317                 }
2318 
2319         /*
2320          * Reuse the larger memory allocated. We know the larger memory
2321          * should be sufficient for reuse.
2322          */
2323         if (pub_key_template[1].ulValueLen > pub_key_template[2].ulValueLen)
2324                 {
2325                 reuse_mem = pub_key_template[1].pValue;
2326                 reuse_mem_len = pub_key_template[1].ulValueLen + DH_BUF_RESERVE;
2327                 }
2328         else
2329                 {
2330                 reuse_mem = pub_key_template[2].pValue;
2331                 reuse_mem_len = pub_key_template[2].ulValueLen + DH_BUF_RESERVE;
2332                 }
2333 
2334         rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
2335                 pub_key_result, pub_key_attr_result_count);
2336         rv1 = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
2337                 priv_key_result, priv_key_attr_result_count);
2338 
2339         if (rv != CKR_OK || rv1 != CKR_OK)
2340                 {
2341                 rv = (rv != CKR_OK) ? rv : rv1;
2342                 PK11err_add_data(PK11_F_DH_GEN_KEY,
2343                     PK11_R_GETATTRIBUTVALUE, rv);
2344                 goto err;
2345                 }
2346 
2347         if (((CK_LONG) pub_key_result[0].ulValueLen) <= 0 ||
2348                 ((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
2349                 {
2350                 PK11err(PK11_F_DH_GEN_KEY, PK11_R_GETATTRIBUTVALUE);
2351                 goto err;
2352                 }
2353 
2354         /* Reuse the memory allocated */
2355         pub_key_result[0].pValue = reuse_mem;
2356         pub_key_result[0].ulValueLen = reuse_mem_len;
2357 
2358         rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
2359                 pub_key_result, pub_key_attr_result_count);
2360 
2361         if (rv != CKR_OK)
2362                 {
2363                 PK11err_add_data(PK11_F_DH_GEN_KEY,
2364                     PK11_R_GETATTRIBUTVALUE, rv);
2365                 goto err;
2366                 }
2367 
2368         if (pub_key_result[0].type == CKA_VALUE)
2369                 {
2370                 if (dh->pub_key == NULL)
2371                         if ((dh->pub_key = BN_new()) == NULL)
2372                                 {
2373                                 PK11err(PK11_F_DH_GEN_KEY,
2374                                         PK11_R_MALLOC_FAILURE);
2375                                 goto err;
2376                                 }
2377                 dh->pub_key = BN_bin2bn(pub_key_result[0].pValue,
2378                         pub_key_result[0].ulValueLen, dh->pub_key);
2379                 if (dh->pub_key == NULL)
2380                         {
2381                         PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
2382                         goto err;
2383                         }
2384                 }
2385 
2386         /* Reuse the memory allocated */
2387         priv_key_result[0].pValue = reuse_mem;
2388         priv_key_result[0].ulValueLen = reuse_mem_len;
2389 
2390         rv = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
2391                 priv_key_result, priv_key_attr_result_count);
2392 
2393         if (rv != CKR_OK)
2394                 {
2395                 PK11err_add_data(PK11_F_DH_GEN_KEY,
2396                     PK11_R_GETATTRIBUTVALUE, rv);
2397                 goto err;
2398                 }
2399 
2400         if (priv_key_result[0].type == CKA_VALUE)
2401                 {
2402                 if (dh->priv_key == NULL)
2403                         if ((dh->priv_key = BN_new()) == NULL)
2404                                 {
2405                                 PK11err(PK11_F_DH_GEN_KEY,
2406                                         PK11_R_MALLOC_FAILURE);
2407                                 goto err;
2408                                 }
2409                 dh->priv_key = BN_bin2bn(priv_key_result[0].pValue,
2410                         priv_key_result[0].ulValueLen, dh->priv_key);
2411                 if (dh->priv_key == NULL)
2412                         {
2413                         PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
2414                         goto err;
2415                         }
2416                 }
2417 
2418         ret = 1;
2419 
2420 err:
2421 
2422         if (h_pub_key != CK_INVALID_HANDLE)
2423                 {
2424                 rv = pFuncList->C_DestroyObject(sp->session, h_pub_key);
2425                 if (rv != CKR_OK)
2426                         {
2427                         PK11err_add_data(PK11_F_DH_GEN_KEY,
2428                             PK11_R_DESTROYOBJECT, rv);
2429                         }
2430                 }
2431 
2432         if (h_priv_key != CK_INVALID_HANDLE)
2433                 {
2434                 rv = pFuncList->C_DestroyObject(sp->session, h_priv_key);
2435                 if (rv != CKR_OK)
2436                         {
2437                         PK11err_add_data(PK11_F_DH_GEN_KEY,
2438                             PK11_R_DESTROYOBJECT, rv);
2439                         }
2440                 }
2441 
2442         for (i = 1; i <= 2; i++)
2443                 {
2444                 if (pub_key_template[i].pValue != NULL)
2445                         {
2446                         OPENSSL_free(pub_key_template[i].pValue);
2447                         pub_key_template[i].pValue = NULL;
2448                         }
2449                 }
2450 
2451         pk11_return_session(sp, OP_DH);
2452         return (ret);
2453         }
2454 
2455 static int pk11_DH_compute_key(unsigned char *key, const BIGNUM *pub_key,
2456         DH *dh)
2457         {
2458         int i;
2459         CK_MECHANISM mechanism = {CKM_DH_PKCS_DERIVE, NULL_PTR, 0};
2460         CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
2461         CK_KEY_TYPE key_type = CKK_GENERIC_SECRET;
2462         CK_OBJECT_HANDLE h_derived_key = CK_INVALID_HANDLE;
2463         CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
2464 
2465         CK_ULONG ul_priv_key_attr_count = 2;
2466         CK_ATTRIBUTE priv_key_template[] =
2467                 {
2468                 {CKA_CLASS, (void*) NULL, sizeof (key_class)},
2469                 {CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
2470                 };
2471 
2472         CK_ULONG priv_key_attr_result_count = 1;
2473         CK_ATTRIBUTE priv_key_result[] =
2474                 {
2475                 {CKA_VALUE, (void *)NULL, 0}
2476                 };
2477 
2478         CK_RV rv;
2479         int ret = -1;
2480         PK11_SESSION *sp = NULL;
2481 
2482         if (dh->priv_key == NULL)
2483                 goto err;
2484 
2485         priv_key_template[0].pValue = &key_class;
2486         priv_key_template[1].pValue = &key_type;
2487 
2488         if ((sp = pk11_get_session(OP_DH)) == NULL)
2489                 goto err;
2490 
2491         mechanism.ulParameterLen = BN_num_bytes(pub_key);
2492         mechanism.pParameter = OPENSSL_malloc(mechanism.ulParameterLen);
2493         if (mechanism.pParameter == NULL)
2494                 {
2495                 PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
2496                 goto err;
2497                 }
2498         BN_bn2bin(pub_key, mechanism.pParameter);
2499 
2500         (void) check_new_dh_key(sp, dh);
2501 
2502         h_key = sp->opdata_dh_key;
2503         if (h_key == CK_INVALID_HANDLE)
2504                 h_key = sp->opdata_dh_key =
2505                         pk11_get_dh_key((DH*) dh, &sp->opdata_dh,
2506                             &sp->opdata_dh_priv_num, sp->session);
2507 
2508         if (h_key == CK_INVALID_HANDLE)
2509                 {
2510                 PK11err(PK11_F_DH_COMP_KEY, PK11_R_CREATEOBJECT);
2511                 goto err;
2512                 }
2513 
2514         rv = pFuncList->C_DeriveKey(sp->session,
2515             &mechanism,
2516             h_key,
2517             priv_key_template,
2518             ul_priv_key_attr_count,
2519             &h_derived_key);
2520         if (rv != CKR_OK)
2521                 {
2522                 PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_DERIVEKEY, rv);
2523                 goto err;
2524                 }
2525 
2526         rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
2527             priv_key_result, priv_key_attr_result_count);
2528 
2529         if (rv != CKR_OK)
2530                 {
2531                 PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
2532                     rv);
2533                 goto err;
2534                 }
2535 
2536         if (((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
2537                 {
2538                 PK11err(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE);
2539                 goto err;
2540                 }
2541         priv_key_result[0].pValue =
2542                 OPENSSL_malloc(priv_key_result[0].ulValueLen);
2543         if (!priv_key_result[0].pValue)
2544                 {
2545                 PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
2546                 goto err;
2547                 }
2548 
2549         rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
2550                 priv_key_result, priv_key_attr_result_count);
2551 
2552         if (rv != CKR_OK)
2553                 {
2554                 PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
2555                     rv);
2556                 goto err;
2557                 }
2558 
2559         /*
2560          * OpenSSL allocates the output buffer 'key' which is the same
2561          * length of the public key. It is long enough for the derived key
2562          */
2563         if (priv_key_result[0].type == CKA_VALUE)
2564                 {
2565                 /*
2566                  * CKM_DH_PKCS_DERIVE mechanism is not supposed to strip
2567                  * leading zeros from a computed shared secret. However,
2568                  * OpenSSL always did it so we must do the same here. The
2569                  * vagueness of the spec regarding leading zero bytes was
2570                  * finally cleared with TLS 1.1 (RFC 4346) saying that leading
2571                  * zeros are stripped before the computed data is used as the
2572                  * pre-master secret.
2573                  */
2574                 for (i = 0; i < priv_key_result[0].ulValueLen; ++i)
2575                         {
2576                         if (((char *)priv_key_result[0].pValue)[i] != 0)
2577                                 break;
2578                         }
2579 
2580                 (void) memcpy(key, ((char *)priv_key_result[0].pValue) + i,
2581                         priv_key_result[0].ulValueLen - i);
2582                 ret = priv_key_result[0].ulValueLen - i;
2583                 }
2584 
2585 err:
2586 
2587         if (h_derived_key != CK_INVALID_HANDLE)
2588                 {
2589                 rv = pFuncList->C_DestroyObject(sp->session, h_derived_key);
2590                 if (rv != CKR_OK)
2591                         {
2592                         PK11err_add_data(PK11_F_DH_COMP_KEY,
2593                             PK11_R_DESTROYOBJECT, rv);
2594                         }
2595                 }
2596         if (priv_key_result[0].pValue)
2597                 {
2598                 OPENSSL_free(priv_key_result[0].pValue);
2599                 priv_key_result[0].pValue = NULL;
2600                 }
2601 
2602         if (mechanism.pParameter)
2603                 {
2604                 OPENSSL_free(mechanism.pParameter);
2605                 mechanism.pParameter = NULL;
2606                 }
2607 
2608         pk11_return_session(sp, OP_DH);
2609         return (ret);
2610         }
2611 
2612 
2613 static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh,
2614         DH **key_ptr, BIGNUM **dh_priv_num, CK_SESSION_HANDLE session)
2615         {
2616         CK_RV rv;
2617         CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
2618         CK_OBJECT_CLASS class = CKO_PRIVATE_KEY;
2619         CK_KEY_TYPE key_type = CKK_DH;
2620         CK_ULONG found;
2621         CK_BBOOL rollback = FALSE;
2622         int i;
2623 
2624         CK_ULONG ul_key_attr_count = 7;
2625         CK_ATTRIBUTE key_template[] =
2626                 {
2627                 {CKA_CLASS, (void*) NULL, sizeof (class)},
2628                 {CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
2629                 {CKA_DERIVE, &true, sizeof (true)},
2630                 {CKA_PRIVATE, &false, sizeof (false)},
2631                 {CKA_PRIME, (void *) NULL, 0},
2632                 {CKA_BASE, (void *) NULL, 0},
2633                 {CKA_VALUE, (void *) NULL, 0},
2634                 };
2635 
2636         key_template[0].pValue = &class;
2637         key_template[1].pValue = &key_type;
2638 
2639         key_template[4].ulValueLen = BN_num_bytes(dh->p);
2640         key_template[4].pValue = (CK_VOID_PTR)OPENSSL_malloc(
2641                 (size_t)key_template[4].ulValueLen);
2642         if (key_template[4].pValue == NULL)
2643                 {
2644                 PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
2645                 goto malloc_err;
2646                 }
2647 
2648         BN_bn2bin(dh->p, key_template[4].pValue);
2649 
2650         key_template[5].ulValueLen = BN_num_bytes(dh->g);
2651         key_template[5].pValue = (CK_VOID_PTR)OPENSSL_malloc(
2652                 (size_t)key_template[5].ulValueLen);
2653         if (key_template[5].pValue == NULL)
2654                 {
2655                 PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
2656                 goto malloc_err;
2657                 }
2658 
2659         BN_bn2bin(dh->g, key_template[5].pValue);
2660 
2661         key_template[6].ulValueLen = BN_num_bytes(dh->priv_key);
2662         key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
2663                 (size_t)key_template[6].ulValueLen);
2664         if (key_template[6].pValue == NULL)
2665                 {
2666                 PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
2667                 goto malloc_err;
2668                 }
2669 
2670         BN_bn2bin(dh->priv_key, key_template[6].pValue);
2671 
2672         /* see find_lock array definition for more info on object locking */
2673         LOCK_OBJSTORE(OP_DH);
2674         rv = pFuncList->C_FindObjectsInit(session, key_template,
2675                 ul_key_attr_count);
2676 
2677         if (rv != CKR_OK)
2678                 {
2679                 PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSINIT, rv);
2680                 goto err;
2681                 }
2682 
2683         rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
2684 
2685         if (rv != CKR_OK)
2686                 {
2687                 PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTS, rv);
2688                 goto err;
2689                 }
2690 
2691         rv = pFuncList->C_FindObjectsFinal(session);
2692 
2693         if (rv != CKR_OK)
2694                 {
2695                 PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSFINAL,
2696                     rv);
2697                 goto err;
2698                 }
2699 
2700         if (found == 0)
2701                 {
2702                 rv = pFuncList->C_CreateObject(session,
2703                         key_template, ul_key_attr_count, &h_key);
2704                 if (rv != CKR_OK)
2705                         {
2706                         PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_CREATEOBJECT,
2707                             rv);
2708                         goto err;
2709                         }
2710                 }
2711 
2712         if (dh_priv_num != NULL)
2713                 if ((*dh_priv_num = BN_dup(dh->priv_key)) == NULL)
2714                         {
2715                         PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
2716                         rollback = TRUE;
2717                         goto err;
2718                         }
2719 
2720         /* LINTED: E_CONSTANT_CONDITION */
2721         KEY_HANDLE_REFHOLD(h_key, OP_DH, FALSE, rollback, err);
2722         if (key_ptr != NULL)
2723                 *key_ptr = dh;
2724 
2725 err:
2726         if (rollback)
2727                 {
2728                 /*
2729                  * We do not care about the return value from C_DestroyObject()
2730                  * since we are doing rollback.
2731                  */
2732                 if (found == 0)
2733                         (void) pFuncList->C_DestroyObject(session, h_key);
2734                 h_key = CK_INVALID_HANDLE;
2735                 }
2736 
2737         UNLOCK_OBJSTORE(OP_DH);
2738 
2739 malloc_err:
2740         for (i = 4; i <= 6; i++)
2741                 {
2742                 if (key_template[i].pValue != NULL)
2743                         {
2744                         OPENSSL_free(key_template[i].pValue);
2745                         key_template[i].pValue = NULL;
2746                         }
2747                 }
2748 
2749         return (h_key);
2750         }
2751 
2752 /*
2753  * Check for cache miss and clean the object pointer and handle
2754  * in such case. Return 1 for cache hit, 0 for cache miss.
2755  *
2756  * Note: we rely on pk11_destroy_dh_key_objects() to set sp->opdata_dh
2757  *       to CK_INVALID_HANDLE even when it fails to destroy the object.
2758  */
2759 static int check_new_dh_key(PK11_SESSION *sp, DH *dh)
2760         {
2761         /*
2762          * Provide protection against DH structure reuse by making the
2763          * check for cache hit stronger. Private key component of DH key
2764          * is unique so it is sufficient to compare it with value cached
2765          * in PK11_SESSION structure.
2766          */
2767         if ((sp->opdata_dh != dh) ||
2768             (BN_cmp(sp->opdata_dh_priv_num, dh->priv_key) != 0))
2769                 {
2770                 /*
2771                  * We do not check the return value because even in case of
2772                  * failure the sp structure will have both key pointer
2773                  * and object handle cleaned and pk11_destroy_object()
2774                  * reports the failure to the OpenSSL error message buffer.
2775                  */
2776                 (void) pk11_destroy_dh_object(sp, TRUE);
2777                 return (0);
2778                 }
2779         return (1);
2780         }
2781 #endif
2782 
2783 /*
2784  * Local function to simplify key template population
2785  * Return 0 -- error, 1 -- no error
2786  */
2787 static int init_template_value(BIGNUM *bn, CK_VOID_PTR *p_value,
2788         CK_ULONG *ul_value_len)
2789         {
2790         CK_ULONG len = BN_num_bytes(bn);
2791         if (len == 0)
2792                 return (1);
2793 
2794         *ul_value_len = len;
2795         *p_value = (CK_VOID_PTR)OPENSSL_malloc((size_t)*ul_value_len);
2796         if (*p_value == NULL)
2797                 return (0);
2798 
2799         BN_bn2bin(bn, *p_value);
2800 
2801         return (1);
2802         }
2803 
2804 #endif  /* OPENSSL_NO_HW_PK11 */
2805 #endif  /* OPENSSL_NO_HW */