1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2012 Milan Jurik. All rights reserved.
  25  * Copyright (c) 2018, Joyent. Inc.
  26  */
  27 
  28 #include <stdlib.h>
  29 #include <string.h>
  30 #include <strings.h>
  31 #include <lber.h>
  32 #include <security/cryptoki.h>
  33 #include "softDSA.h"
  34 #include "softDH.h"
  35 #include "softRSA.h"
  36 #include "softObject.h"
  37 #include "softASN1.h"
  38 
  39 #define OID_TAG                 0x06
  40 
  41 #define MAX_DH_KEY      MAX_DH_KEYLENGTH_IN_BYTES       /* bytes in DH key */
  42 static uchar_t  DH_OID[] = {
  43         /* DH key agreement OID:  1 . 2 . 840 . 113549 . 1 . 3 . 1 */
  44         0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x03, 0x01
  45 };
  46 
  47 #define MAX_DH942_KEY   MAX_DH_KEYLENGTH_IN_BYTES /* bytes in DH X9.42 key */
  48 static uchar_t  DH942_OID[] = {
  49         /* DH X9.42 OID:  1 . 2 . 840 . 10046 . 1  */
  50         0x2A, 0x86, 0x48, 0xCE, 0x3E, 0x01
  51 };
  52 
  53 #define MAX_DSA_KEY     MAX_DSA_KEY_LEN         /* bytes in DSA key */
  54 static uchar_t  DSA_OID[] = {
  55         /* DSA algorithm OID:  1 . 2 . 840 . 10040 . 4 . 1  */
  56         0x2A, 0x86, 0x48, 0xCE, 0x38, 0x04, 0x01
  57 };
  58 
  59 #define MAX_RSA_KEY     MAX_RSA_KEYLENGTH_IN_BYTES      /* bytes in RSA key */
  60 static uchar_t  RSA_OID[] = {
  61         /* RSA algorithm OID:  1 . 2 . 840 . 113549 . 1 . 1 . 1 */
  62         0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01
  63 };
  64 
  65 
  66 /*
  67  * If the first bit of big integer is non-zero (i.e, first byte is
  68  * 0x80 or greater), it may be interpreted as an ASN.1 negative number.
  69  * Add one leading byte of zero-padding only in these cases to ensure
  70  * it is treated as an unsigned integer.
  71  */
  72 static CK_RV
  73 pad_bigint_attr(biginteger_t *src, biginteger_t *dst)
  74 {
  75         int     padding;
  76 
  77         /* Src and dst must already by previously allocated. */
  78         if (src == NULL || dst == NULL)
  79                 return (CKR_HOST_MEMORY);
  80 
  81         if (src->big_value_len == 0) {
  82                 dst->big_value = NULL;
  83                 dst->big_value_len = 0;
  84                 return (CKR_OK);
  85         }
  86         /*
  87          * Realloc() may free() or shrink previous memory location, so
  88          * clear out potentially sensitive data before that happens.
  89          */
  90         if (dst->big_value != NULL)
  91                 explicit_bzero(dst->big_value, dst->big_value_len);
  92 
  93         padding = (src->big_value[0] < 0x80) ? 0 : 1;
  94         dst->big_value_len = src->big_value_len + padding;
  95 
  96         dst->big_value = realloc(dst->big_value, dst->big_value_len);
  97         if (dst->big_value == NULL)
  98                 return (CKR_HOST_MEMORY);
  99 
 100         /* Set zero-pad at first byte, then append actual big_value. */
 101         dst->big_value[0] = 0x0;
 102         (void) memcpy(&(dst->big_value[padding]), src->big_value,
 103             src->big_value_len);
 104         return (CKR_OK);
 105 }
 106 
 107 /*
 108  * Sometimes there is one bytes of zero-padding, if a big integer may
 109  * be interpreted as an ASN.1 negative number (i.e, the first bit is
 110  * non-zero, the first byte is 0x80 or greater).  Remove first byte
 111  * of zero-padding in those cases from the decoded octet strings.
 112  */
 113 static CK_RV
 114 unpad_bigint_attr(biginteger_t src, biginteger_t *dst)
 115 {
 116         int     offset;
 117 
 118         if (dst == NULL)
 119                 return (CKR_HOST_MEMORY);
 120 
 121         if (src.big_value_len == 0) {
 122                 dst->big_value = NULL;
 123                 dst->big_value_len = 0;
 124                 return (CKR_OK);
 125         }
 126 
 127         offset = (src.big_value[0] == 0x00) ? 1 : 0;
 128         dst->big_value_len = src.big_value_len - offset;
 129 
 130         /*
 131          * Must allocate memory here because subsequent calls to
 132          * copy_bigint_attr() just redirect pointer; it doesn't
 133          * really copy the bigint like the function name implies.
 134          */
 135         dst->big_value = malloc(dst->big_value_len);
 136         if (dst->big_value == NULL)
 137                 return (CKR_HOST_MEMORY);
 138 
 139         (void) memcpy(dst->big_value, &(src.big_value[offset]),
 140             dst->big_value_len);
 141         return (CKR_OK);
 142 }
 143 
 144 
 145 /* Encode RSA private key in ASN.1 BER syntax. */
 146 static CK_RV
 147 rsa_pri_to_asn1(soft_object_t *objp, uchar_t *buf, ulong_t *buf_len)
 148 {
 149         CK_RV           rv = CKR_OK;
 150         BerElement      *key_asn = NULLBER, *p8obj_asn = NULLBER;
 151         BerValue        *key_octs = NULL, *p8obj_octs = NULL;
 152         int             version = SOFT_ASN_VERSION;
 153         biginteger_t    tmp_pad = { NULL, 0 };
 154 
 155         /*
 156          * The ASN.1 syntax for an RSA private key is:
 157          *
 158          * PKCS#8       \* PrivateKeyInfo *\
 159          * ---------------------------------
 160          * Sequence {
 161          *      version         INTEGER;
 162          *      Sequence {      \* PrivateKeyAlgorithm *\
 163          *              OID     0x06,   \* RSA algorithm OID *\
 164          *              param(NULL)
 165          *      }
 166          *      RSAPrivateKey   OCTETSTRING =
 167          *              PKCS#1  \* RSAPrivateKey *\
 168          *              ---------------------------
 169          *              Sequence {
 170          *                      version         INTEGER,
 171          *                      modulus         INTEGER,
 172          *                      publicExponent  INTEGER,
 173          *                      privateExponent INTEGER,
 174          *                      prime1          INTEGER,
 175          *                      prime2          INTEGER,
 176          *                      exponent1       INTEGER,
 177          *                      exponent2       INTEGER,
 178          *                      coefficient     INTEGER
 179          *              }
 180          * }
 181          *
 182          * The code below starts building the innermost octets
 183          * RSAPrivateKey, and then builds the PrivateKeyInfo
 184          * sequence around that octet string.  The BER syntax
 185          * used in this function is (others may be possible):
 186          *      { i { to n } { i to  to  to  to  to  to  to  to } }
 187          * where "i" is for integers with fixed size
 188          * where "to" is for integers that vary in size (length + value)
 189          * where "n" is for nulls
 190          * where "{}" delimit sequences
 191          */
 192 
 193         /* RSAPrivateKey ... */
 194         if ((key_asn = ber_alloc()) == NULLBER)
 195                 return (CKR_HOST_MEMORY);
 196 
 197         /* ... begin-sequence { version, */
 198         if (ber_printf(key_asn, "{i", version) == -1) {
 199                 rv = CKR_GENERAL_ERROR;
 200                 goto cleanup_rsapri2asn;
 201         }
 202 
 203         /* ... modulus, */
 204         if ((rv = pad_bigint_attr(OBJ_PRI_RSA_MOD(objp), &tmp_pad)) != CKR_OK)
 205                 goto cleanup_rsapri2asn;
 206         if (ber_printf(key_asn, "to", LBER_INTEGER,
 207             tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 208                 rv = CKR_GENERAL_ERROR;
 209                 goto cleanup_rsapri2asn;
 210         }
 211 
 212         /* ... public exponent, */
 213         if ((rv = pad_bigint_attr(OBJ_PRI_RSA_PUBEXPO(objp), &tmp_pad)) !=
 214             CKR_OK)
 215                 goto cleanup_rsapri2asn;
 216 
 217         else if (ber_printf(key_asn, "to", LBER_INTEGER, tmp_pad.big_value,
 218             tmp_pad.big_value_len) == -1) {
 219                 rv = CKR_GENERAL_ERROR;
 220                 goto cleanup_rsapri2asn;
 221         }
 222 
 223         /* ... private exponent, */
 224         if ((rv = pad_bigint_attr(OBJ_PRI_RSA_PRIEXPO(objp), &tmp_pad)) !=
 225             CKR_OK)
 226                 goto cleanup_rsapri2asn;
 227         if (ber_printf(key_asn, "to", LBER_INTEGER,
 228             tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 229                 rv = CKR_GENERAL_ERROR;
 230                 goto cleanup_rsapri2asn;
 231         }
 232 
 233         /* ... prime 1, */
 234         if ((rv = pad_bigint_attr(OBJ_PRI_RSA_PRIME1(objp), &tmp_pad)) !=
 235             CKR_OK)
 236                 goto cleanup_rsapri2asn;
 237         else if (ber_printf(key_asn, "to", LBER_INTEGER,
 238             tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 239                 rv = CKR_GENERAL_ERROR;
 240                 goto cleanup_rsapri2asn;
 241         }
 242 
 243         /* ... prime 2, */
 244         if ((rv = pad_bigint_attr(OBJ_PRI_RSA_PRIME2(objp), &tmp_pad)) !=
 245             CKR_OK)
 246                 goto cleanup_rsapri2asn;
 247         else if (ber_printf(key_asn, "to", LBER_INTEGER,
 248             tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 249                 rv = CKR_GENERAL_ERROR;
 250                 goto cleanup_rsapri2asn;
 251         }
 252 
 253         /* ... exponent 1, */
 254         if ((rv = pad_bigint_attr(OBJ_PRI_RSA_EXPO1(objp), &tmp_pad)) != CKR_OK)
 255                 goto cleanup_rsapri2asn;
 256         else if (ber_printf(key_asn, "to", LBER_INTEGER,
 257             tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 258                 rv = CKR_GENERAL_ERROR;
 259                 goto cleanup_rsapri2asn;
 260         }
 261 
 262         /* ... exponent 2, */
 263         if ((rv = pad_bigint_attr(OBJ_PRI_RSA_EXPO2(objp), &tmp_pad)) != CKR_OK)
 264                 goto cleanup_rsapri2asn;
 265         else if (ber_printf(key_asn, "to", LBER_INTEGER,
 266             tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 267                 rv = CKR_GENERAL_ERROR;
 268                 goto cleanup_rsapri2asn;
 269         }
 270 
 271         /* ... coefficient } end-sequence */
 272         if ((rv = pad_bigint_attr(OBJ_PRI_RSA_COEF(objp), &tmp_pad)) != CKR_OK)
 273                 goto cleanup_rsapri2asn;
 274         else if (ber_printf(key_asn, "to}", LBER_INTEGER,
 275             tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 276                 rv = CKR_GENERAL_ERROR;
 277                 goto cleanup_rsapri2asn;
 278         }
 279 
 280         /* Convert key ASN.1 to octet string. */
 281         if (ber_flatten(key_asn, &key_octs) == -1) {
 282                 rv = CKR_GENERAL_ERROR;
 283                 goto cleanup_rsapri2asn;
 284         }
 285 
 286         /* PKCS#8 PrivateKeyInfo ... */
 287         if ((p8obj_asn = ber_alloc()) == NULLBER) {
 288                 rv = CKR_HOST_MEMORY;
 289                 goto cleanup_rsapri2asn;
 290         }
 291 
 292         /*
 293          * Embed key octet string into PKCS#8 object ASN.1:
 294          * begin-sequence {
 295          *      version
 296          *      begin-sequence {
 297          *              OID,
 298          *              NULL
 299          *      } end-sequence
 300          *      RSAPrivateKey
 301          * } end-sequence
 302          */
 303         if (ber_printf(p8obj_asn, "{i{ton}o}", version,
 304             OID_TAG, RSA_OID, sizeof (RSA_OID), /* NULL parameter, */
 305             key_octs->bv_val, key_octs->bv_len) == -1) {
 306                 rv = CKR_GENERAL_ERROR;
 307                 goto cleanup_rsapri2asn;
 308         }
 309 
 310         /* Convert PKCS#8 object ASN.1 to octet string. */
 311         if (ber_flatten(p8obj_asn, &p8obj_octs) == -1) {
 312                 rv = CKR_GENERAL_ERROR;
 313                 goto cleanup_rsapri2asn;
 314         }
 315 
 316         /* Ship out the PKCS#8 object ASN.1 octet string, if possible. */
 317         /*
 318          * If the user passes in a null buf, then buf_len is set.
 319          * If the user passes in a value with buf_len, then it can
 320          * be checked to see if the accompanying buf is big enough.
 321          * If it is, the octet string is copied into a pre-malloc'd
 322          * buf; otherwise the user must resize buf and call again.
 323          * In either case, buf_len is reset to the corrected size.
 324          * See PKCS#11 section 11.2.
 325          */
 326 #ifdef _LP64
 327         /* LINTED E_CAST_INT_TO_SMALL_INT */
 328         if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
 329 #else
 330         if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
 331 #endif
 332                 *buf_len = p8obj_octs->bv_len;
 333                 rv = (buf == NULL) ? CKR_OK : CKR_BUFFER_TOO_SMALL;
 334                 goto cleanup_rsapri2asn;
 335         }
 336 
 337         *buf_len = p8obj_octs->bv_len;
 338         (void) memcpy(buf, p8obj_octs->bv_val, *buf_len);
 339 
 340 cleanup_rsapri2asn:
 341 
 342         freezero(tmp_pad.big_value, tmp_pad.big_value_len);
 343 
 344         if (key_asn != NULLBER)
 345                 ber_free(key_asn, 1);
 346 
 347         if (key_octs != NULL)
 348                 ber_bvfree(key_octs);
 349 
 350         if (p8obj_asn != NULLBER)
 351                 ber_free(p8obj_asn, 1);
 352 
 353         if (p8obj_octs != NULL)
 354                 ber_bvfree(p8obj_octs);
 355 
 356         return (rv);
 357 }
 358 
 359 /* Encode DSA private key in ASN.1 BER syntax. */
 360 static CK_RV
 361 dsa_pri_to_asn1(soft_object_t *objp, uchar_t *buf, ulong_t *buf_len)
 362 {
 363         CK_RV           rv = CKR_OK;
 364         BerElement      *key_asn = NULLBER, *p8obj_asn = NULLBER;
 365         BerValue        *key_octs = NULL, *p8obj_octs = NULL;
 366         int             version = SOFT_ASN_VERSION;
 367         biginteger_t    tmp_pad = { NULL, 0 };
 368 
 369         /*
 370          * The ASN.1 syntax for a DSA private key is:
 371          *
 372          * PKCS#8       \* PrivateKeyInfo *\
 373          * ---------------------------------
 374          * Sequence {
 375          *      version         INTEGER;
 376          *      Sequence {      \* PrivateKeyAlgorithm *\
 377          *              OID     0x06,   \* DSA algorithm OID *\
 378          *              param(DSS-params)       OCTETSTRING =
 379          *                      PKCS#?  \* DSSParameter *\
 380          *                      ----------------------------------
 381          *                      Sequence {
 382          *                              prime   INTEGER,
 383          *                              subprime INTEGER,
 384          *                              base    INTEGER,
 385          *              }
 386          *      }
 387          *      DSAPrivateKey   OCTETSTRING =
 388          *              PKCS#1  \* DSAPrivateKey *\
 389          *              ---------------------------
 390          *              value           INTEGER
 391          * }
 392          *
 393          * The code below starts building the innermost octets
 394          * DSAPrivateKey, and then builds the PrivateKeyInfo
 395          * sequence around that octet string.  The BER syntax
 396          * used in this function is (others may be possible):
 397          *      { i { to { to to to } } to }
 398          * where "i" is for integers with fixed size
 399          * where "to" is for integers that vary in size (length + value)
 400          * where "{}" delimit sequences
 401          */
 402 
 403         /* DSAPrivateKey ... */
 404         if ((key_asn = ber_alloc()) == NULLBER)
 405                 return (CKR_HOST_MEMORY);
 406 
 407         /* ... value */
 408         if ((rv = pad_bigint_attr(OBJ_PRI_DSA_VALUE(objp), &tmp_pad)) != CKR_OK)
 409                 goto cleanup_dsapri2asn;
 410         if (ber_printf(key_asn, "to", LBER_INTEGER,
 411             tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 412                 rv = CKR_GENERAL_ERROR;
 413                 goto cleanup_dsapri2asn;
 414         }
 415 
 416         /* Convert key ASN.1 to octet string. */
 417         if (ber_flatten(key_asn, &key_octs) == -1) {
 418                 rv = CKR_GENERAL_ERROR;
 419                 goto cleanup_dsapri2asn;
 420         }
 421 
 422         /* PKCS#8 PrivateKeyInfo ... */
 423         if ((p8obj_asn = ber_alloc()) == NULLBER) {
 424                 rv = CKR_HOST_MEMORY;
 425                 goto cleanup_dsapri2asn;
 426         }
 427 
 428         /*
 429          * Start off the PKCS#8 object ASN.1:
 430          * begin-sequence {
 431          *      version
 432          *      begin-sequence {
 433          *              OID,
 434          * ...
 435          */
 436         if (ber_printf(p8obj_asn, "{i{to", version,
 437             OID_TAG, DSA_OID, sizeof (DSA_OID)) == -1) {
 438                 rv = CKR_GENERAL_ERROR;
 439                 goto cleanup_dsapri2asn;
 440         }
 441 
 442         /*
 443          * Add DSS parameters:
 444          * ...
 445          *              begin-sequence {
 446          *                      prime,
 447          * ...
 448          */
 449         if ((rv = pad_bigint_attr(OBJ_PRI_DSA_PRIME(objp), &tmp_pad)) != CKR_OK)
 450                 goto cleanup_dsapri2asn;
 451         if (ber_printf(p8obj_asn, "{to", LBER_INTEGER,
 452             tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 453                 rv = CKR_GENERAL_ERROR;
 454                 goto cleanup_dsapri2asn;
 455         }
 456 
 457         /*
 458          * ...
 459          *                      subprime,
 460          * ...
 461          */
 462         if ((rv = pad_bigint_attr(OBJ_PRI_DSA_SUBPRIME(objp), &tmp_pad)) !=
 463             CKR_OK)
 464                 goto cleanup_dsapri2asn;
 465         if (ber_printf(p8obj_asn, "to", LBER_INTEGER,
 466             tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 467                 rv = CKR_GENERAL_ERROR;
 468                 goto cleanup_dsapri2asn;
 469         }
 470 
 471         /*
 472          * ...
 473          *                      base
 474          *              } end-sequence
 475          */
 476         if ((rv = pad_bigint_attr(OBJ_PRI_DSA_BASE(objp), &tmp_pad)) != CKR_OK)
 477                 goto cleanup_dsapri2asn;
 478         if (ber_printf(p8obj_asn, "to}", LBER_INTEGER,
 479             tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 480                 rv = CKR_GENERAL_ERROR;
 481                 goto cleanup_dsapri2asn;
 482         }
 483 
 484         /*
 485          * Add the key octet string:
 486          *      } end-sequence
 487          *      DSAPrivateKey
 488          * } end-sequence
 489          */
 490         if (ber_printf(p8obj_asn, "}o}",
 491             key_octs->bv_val, key_octs->bv_len) == -1) {
 492                 rv = CKR_GENERAL_ERROR;
 493                 goto cleanup_dsapri2asn;
 494         }
 495 
 496         /* Convert PKCS#8 object ASN.1 to octet string. */
 497         if (ber_flatten(p8obj_asn, &p8obj_octs) == -1) {
 498                 rv = CKR_GENERAL_ERROR;
 499                 goto cleanup_dsapri2asn;
 500         }
 501 
 502         /* Ship out the PKCS#8 object ASN.1 octet string, if possible. */
 503         /*
 504          * If the user passes in a null buf, then buf_len is set.
 505          * If the user passes in a value with buf_len, then it can
 506          * be checked to see if the accompanying buf is big enough.
 507          * If it is, the octet string is copied into a pre-malloc'd
 508          * buf; otherwise the user must resize buf and call again.
 509          * In either case, buf_len is reset to the corrected size.
 510          * See PKCS#11 section 11.2.
 511          */
 512 #ifdef _LP64
 513         /* LINTED E_CAST_INT_TO_SMALL_INT */
 514         if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
 515 #else
 516         if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
 517 #endif
 518                 *buf_len = p8obj_octs->bv_len;
 519                 rv = (buf == NULL) ? CKR_OK : CKR_BUFFER_TOO_SMALL;
 520                 goto cleanup_dsapri2asn;
 521         }
 522 
 523         *buf_len = p8obj_octs->bv_len;
 524         (void) memcpy(buf, p8obj_octs->bv_val, *buf_len);
 525 
 526 cleanup_dsapri2asn:
 527 
 528         freezero(tmp_pad.big_value, tmp_pad.big_value_len);
 529 
 530         if (key_asn != NULLBER)
 531                 ber_free(key_asn, 1);
 532 
 533         if (key_octs != NULL)
 534                 ber_bvfree(key_octs);
 535 
 536         if (p8obj_asn != NULLBER)
 537                 ber_free(p8obj_asn, 1);
 538 
 539         if (p8obj_octs != NULL)
 540                 ber_bvfree(p8obj_octs);
 541 
 542         return (rv);
 543 }
 544 
 545 /* Encode DH private key in ASN.1 BER syntax. */
 546 static CK_RV
 547 dh_pri_to_asn1(soft_object_t *objp, uchar_t *buf, ulong_t *buf_len)
 548 {
 549         CK_RV           rv = CKR_OK;
 550         BerElement      *key_asn = NULLBER, *p8obj_asn = NULLBER;
 551         BerValue        *key_octs = NULL, *p8obj_octs = NULL;
 552         int             version = SOFT_ASN_VERSION;
 553         biginteger_t    tmp_pad = { NULL, 0 };
 554 
 555         /*
 556          * The ASN.1 syntax for a DH private key is:
 557          *
 558          * PKCS#8       \* PrivateKeyInfo *\
 559          * ---------------------------------
 560          * Sequence {
 561          *      version         INTEGER;
 562          *      Sequence {      \* PrivateKeyAlgorithm *\
 563          *              OID     0x06,   \* DH algorithm OID *\
 564          *              param(DH-params) OCTETSTRING =
 565          *                      PKCS#3  \* DHParameter *\
 566          *                      -------------------------
 567          *                      Sequence {
 568          *                              prime   INTEGER,
 569          *                              base    INTEGER
 570          *                      }
 571          *      }
 572          *      DHPrivateKey    OCTETSTRING =
 573          *              PKCS#1  \* DHPrivateKey *\
 574          *              --------------------------
 575          *              value           INTEGER
 576          * }
 577          *
 578          * The code below starts building the innermost octets
 579          * DHPrivateKey, and then builds the PrivateKeyInfo
 580          * sequence around that octet string.  The BER syntax
 581          * used in this function is (others may be possible):
 582          *      { i { to { to to } } to }
 583          * where "i" is for integers with fixed size
 584          * where "to" is for integers that vary in size (length + value)
 585          * where "{}" delimit sequences
 586          */
 587 
 588         /* DHPrivateKey ... */
 589         if ((key_asn = ber_alloc()) == NULLBER)
 590                 return (CKR_HOST_MEMORY);
 591 
 592         /* ... value */
 593         if ((rv = pad_bigint_attr(OBJ_PRI_DH_VALUE(objp), &tmp_pad)) != CKR_OK)
 594                 goto cleanup_dhpri2asn;
 595         if (ber_printf(key_asn, "to", LBER_INTEGER,
 596             tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 597                 rv = CKR_GENERAL_ERROR;
 598                 goto cleanup_dhpri2asn;
 599         }
 600 
 601         /* Convert key ASN.1 to octet string. */
 602         if (ber_flatten(key_asn, &key_octs) == -1) {
 603                 rv = CKR_GENERAL_ERROR;
 604                 goto cleanup_dhpri2asn;
 605         }
 606 
 607         /* PKCS#8 PrivateKeyInfo ... */
 608         if ((p8obj_asn = ber_alloc()) == NULLBER) {
 609                 rv = CKR_HOST_MEMORY;
 610                 goto cleanup_dhpri2asn;
 611         }
 612 
 613         /*
 614          * Start off the PKCS#8 object ASN.1:
 615          * begin-sequence {
 616          *      version
 617          *      begin-sequence {
 618          *              OID,
 619          * ...
 620          */
 621         if (ber_printf(p8obj_asn, "{i{to", version,
 622             OID_TAG, DH_OID, sizeof (DH_OID)) == -1) {
 623                 rv = CKR_GENERAL_ERROR;
 624                 goto cleanup_dhpri2asn;
 625         }
 626 
 627         /*
 628          * Add DH parameters:
 629          * ...
 630          *              begin-sequence {
 631          *                      prime,
 632          * ...
 633          */
 634         if ((rv = pad_bigint_attr(OBJ_PRI_DH_PRIME(objp), &tmp_pad)) != CKR_OK)
 635                 goto cleanup_dhpri2asn;
 636         if (ber_printf(p8obj_asn, "{to", LBER_INTEGER,
 637             tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 638                 rv = CKR_GENERAL_ERROR;
 639                 goto cleanup_dhpri2asn;
 640         }
 641 
 642         /*
 643          * ...
 644          *                      base
 645          *              } end-sequence
 646          */
 647         if ((rv = pad_bigint_attr(OBJ_PRI_DH_BASE(objp), &tmp_pad)) != CKR_OK)
 648                 goto cleanup_dhpri2asn;
 649         if (ber_printf(p8obj_asn, "to}", LBER_INTEGER,
 650             tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 651                 rv = CKR_GENERAL_ERROR;
 652                 goto cleanup_dhpri2asn;
 653         }
 654 
 655         /*
 656          * Add the key octet string:
 657          *      } end-sequence
 658          *      DSAPrivateKey
 659          * } end-sequence
 660          */
 661         if (ber_printf(p8obj_asn, "}o}",
 662             key_octs->bv_val, key_octs->bv_len) == -1) {
 663                 rv = CKR_GENERAL_ERROR;
 664                 goto cleanup_dhpri2asn;
 665         }
 666 
 667         /* Convert PKCS#8 object ASN.1 to octet string. */
 668         if (ber_flatten(p8obj_asn, &p8obj_octs) == -1) {
 669                 rv = CKR_GENERAL_ERROR;
 670                 goto cleanup_dhpri2asn;
 671         }
 672 
 673         /* Ship out the PKCS#8 object ASN.1 octet string, if possible. */
 674         /*
 675          * If the user passes in a null buf, then buf_len is set.
 676          * If the user passes in a value with buf_len, then it can
 677          * be checked to see if the accompanying buf is big enough.
 678          * If it is, the octet string is copied into a pre-malloc'd
 679          * buf; otherwise the user must resize buf and call again.
 680          * In either case, buf_len is reset to the corrected size.
 681          * See PKCS#11 section 11.2.
 682          */
 683 #ifdef _LP64
 684         /* LINTED E_CAST_INT_TO_SMALL_INT */
 685         if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
 686 #else
 687         if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
 688 #endif
 689                 *buf_len = p8obj_octs->bv_len;
 690                 rv = (buf == NULL) ? CKR_OK : CKR_BUFFER_TOO_SMALL;
 691                 goto cleanup_dhpri2asn;
 692         }
 693 
 694         *buf_len = p8obj_octs->bv_len;
 695         (void) memcpy(buf, p8obj_octs->bv_val, *buf_len);
 696 
 697 cleanup_dhpri2asn:
 698 
 699         freezero(tmp_pad.big_value, tmp_pad.big_value_len);
 700 
 701         if (key_asn != NULLBER)
 702                 ber_free(key_asn, 1);
 703 
 704         if (key_octs != NULL)
 705                 ber_bvfree(key_octs);
 706 
 707         if (p8obj_asn != NULLBER)
 708                 ber_free(p8obj_asn, 1);
 709 
 710         if (p8obj_octs != NULL)
 711                 ber_bvfree(p8obj_octs);
 712 
 713         return (rv);
 714 }
 715 
 716 /* Encode DH X9.42 private key in ASN.1 BER syntax. */
 717 static CK_RV
 718 x942_dh_pri_to_asn1(soft_object_t *objp, uchar_t *buf, ulong_t *buf_len)
 719 {
 720         CK_RV           rv = CKR_OK;
 721         BerElement      *key_asn = NULLBER, *p8obj_asn = NULLBER;
 722         BerValue        *key_octs = NULL, *p8obj_octs = NULL;
 723         int             version = SOFT_ASN_VERSION;
 724         biginteger_t    tmp_pad = { NULL, 0 };
 725 
 726         /*
 727          * The ASN.1 syntax for a X9.42 DH private key is:
 728          *
 729          * PKCS#8       \* PrivateKeyInfo *\
 730          * ---------------------------------
 731          * Sequence {
 732          *      version         INTEGER;
 733          *      Sequence {      \* PrivateKeyAlgorithm *\
 734          *              OID     0x06,   \* DH X9.42 algorithm OID *\
 735          *              param(DH-params) OCTETSTRING =
 736          *                      PKCS#3  \* DHParameter *\
 737          *                      -------------------------
 738          *                      Sequence {
 739          *                              prime   INTEGER,
 740          *                              base    INTEGER,
 741          *                              subprime INTEGER \* for X9.42 *\
 742          *                      }
 743          *      }
 744          *      DHPrivateKey    OCTETSTRING =
 745          *              PKCS#1  \* DHPrivateKey *\
 746          *              --------------------------
 747          *              value           INTEGER
 748          * }
 749          *
 750          * The code below starts building the innermost octets
 751          * DHPrivateKey, and then builds the PrivateKeyInfo
 752          * sequence around that octet string.  The BER syntax
 753          * used in this function is (others may be possible):
 754          *      { i { to { to to } } to }
 755          * where "i" is for integers with fixed size
 756          * where "to" is for integers that vary in size (length + value)
 757          * where "{}" delimit sequences
 758          */
 759 
 760         /* DHPrivateKey ... */
 761         if ((key_asn = ber_alloc()) == NULLBER)
 762                 return (CKR_HOST_MEMORY);
 763 
 764         /* ... value */
 765         if ((rv = pad_bigint_attr(OBJ_PRI_DH942_VALUE(objp), &tmp_pad)) !=
 766             CKR_OK)
 767                 goto cleanup_x942dhpri2asn;
 768         if (ber_printf(key_asn, "to", LBER_INTEGER,
 769             tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 770                 rv = CKR_GENERAL_ERROR;
 771                 goto cleanup_x942dhpri2asn;
 772         }
 773 
 774         /* Convert key ASN.1 to octet string. */
 775         if (ber_flatten(key_asn, &key_octs) == -1) {
 776                 rv = CKR_GENERAL_ERROR;
 777                 goto cleanup_x942dhpri2asn;
 778         }
 779 
 780         /* PKCS#8 PrivateKeyInfo ... */
 781         if ((p8obj_asn = ber_alloc()) == NULLBER) {
 782                 rv = CKR_HOST_MEMORY;
 783                 goto cleanup_x942dhpri2asn;
 784         }
 785 
 786         /*
 787          * Start off the PKCS#8 object ASN.1:
 788          * begin-sequence {
 789          *      version
 790          *      begin-sequence {
 791          *              OID,
 792          * ...
 793          */
 794         if (ber_printf(p8obj_asn, "{i{to", version,
 795             OID_TAG, DH942_OID, sizeof (DH942_OID)) == -1) {
 796                 rv = CKR_GENERAL_ERROR;
 797                 goto cleanup_x942dhpri2asn;
 798         }
 799 
 800         /*
 801          * Add DH parameters:
 802          * ...
 803          *              begin-sequence {
 804          *                      prime,
 805          * ...
 806          */
 807         if ((rv = pad_bigint_attr(OBJ_PRI_DH942_PRIME(objp), &tmp_pad)) !=
 808             CKR_OK)
 809                 goto cleanup_x942dhpri2asn;
 810         if (ber_printf(p8obj_asn, "{to", LBER_INTEGER,
 811             tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 812                 rv = CKR_GENERAL_ERROR;
 813                 goto cleanup_x942dhpri2asn;
 814         }
 815 
 816         /*
 817          * ...
 818          *                      base,
 819          * ...
 820          */
 821         if ((rv = pad_bigint_attr(OBJ_PRI_DH942_BASE(objp), &tmp_pad)) !=
 822             CKR_OK)
 823                 goto cleanup_x942dhpri2asn;
 824         if (ber_printf(p8obj_asn, "to", LBER_INTEGER,
 825             tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 826                 rv = CKR_GENERAL_ERROR;
 827                 goto cleanup_x942dhpri2asn;
 828         }
 829 
 830         /*
 831          * ...
 832          *                      subprime
 833          *              } end-sequence
 834          */
 835         if ((rv = pad_bigint_attr(OBJ_PRI_DH942_SUBPRIME(objp), &tmp_pad)) !=
 836             CKR_OK)
 837                 goto cleanup_x942dhpri2asn;
 838         if (ber_printf(p8obj_asn, "to}", LBER_INTEGER,
 839             tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 840                 rv = CKR_GENERAL_ERROR;
 841                 goto cleanup_x942dhpri2asn;
 842         }
 843 
 844         /*
 845          * Add the key octet string:
 846          *      } end-sequence
 847          *      DHPrivateKey
 848          * } end-sequence
 849          */
 850         if (ber_printf(p8obj_asn, "}o}",
 851             key_octs->bv_val, key_octs->bv_len) == -1) {
 852                 rv = CKR_GENERAL_ERROR;
 853                 goto cleanup_x942dhpri2asn;
 854         }
 855 
 856         /* Convert PKCS#8 object ASN.1 to octet string. */
 857         if (ber_flatten(p8obj_asn, &p8obj_octs) == -1) {
 858                 rv = CKR_GENERAL_ERROR;
 859                 goto cleanup_x942dhpri2asn;
 860         }
 861 
 862         /* Ship out the PKCS#8 object ASN.1 octet string, if possible. */
 863         /*
 864          * If the user passes in a null buf, then buf_len is set.
 865          * If the user passes in a value with buf_len, then it can
 866          * be checked to see if the accompanying buf is big enough.
 867          * If it is, the octet string is copied into a pre-malloc'd
 868          * buf; otherwise the user must resize buf and call again.
 869          * In either case, buf_len is reset to the corrected size.
 870          * See PKCS#11 section 11.2.
 871          */
 872 #ifdef _LP64
 873         /* LINTED E_CAST_INT_TO_SMALL_INT */
 874         if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
 875 #else
 876         if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
 877 #endif
 878                 *buf_len = p8obj_octs->bv_len;
 879                 rv = (buf == NULL) ? CKR_OK : CKR_BUFFER_TOO_SMALL;
 880                 goto cleanup_x942dhpri2asn;
 881         }
 882 
 883         *buf_len = p8obj_octs->bv_len;
 884         (void) memcpy(buf, p8obj_octs->bv_val, *buf_len);
 885 
 886 cleanup_x942dhpri2asn:
 887 
 888         freezero(tmp_pad.big_value, tmp_pad.big_value_len);
 889 
 890         if (key_asn != NULLBER)
 891                 ber_free(key_asn, 1);
 892 
 893         if (key_octs != NULL)
 894                 ber_bvfree(key_octs);
 895 
 896         if (p8obj_asn != NULLBER)
 897                 ber_free(p8obj_asn, 1);
 898 
 899         if (p8obj_octs != NULL)
 900                 ber_bvfree(p8obj_octs);
 901 
 902         return (rv);
 903 }
 904 
 905 /*
 906  * Encode the object key from the soft_object_t into ASN.1 format.
 907  */
 908 CK_RV
 909 soft_object_to_asn1(soft_object_t *objp, uchar_t *buf, ulong_t *buf_len)
 910 {
 911         CK_OBJECT_CLASS class = objp->class;
 912         CK_KEY_TYPE     keytype = objp->key_type;
 913 
 914         switch (class) {
 915 
 916         case CKO_PRIVATE_KEY:
 917                 switch (keytype) {
 918                 case CKK_RSA:
 919                         return (rsa_pri_to_asn1(objp, buf, buf_len));
 920 
 921                 case CKK_DSA:
 922                         return (dsa_pri_to_asn1(objp, buf, buf_len));
 923 
 924                 case CKK_DH:
 925                         return (dh_pri_to_asn1(objp, buf, buf_len));
 926 
 927                 case CKK_X9_42_DH:
 928                         return (x942_dh_pri_to_asn1(objp, buf, buf_len));
 929 
 930                 default:
 931                         return (CKR_FUNCTION_NOT_SUPPORTED);
 932                 } /* keytype */
 933 
 934         default:
 935                 return (CKR_FUNCTION_NOT_SUPPORTED);
 936 
 937         } /* class */
 938 }
 939 
 940 /* Decode ASN.1 BER syntax into RSA private key. */
 941 static CK_RV
 942 asn1_to_rsa_pri(private_key_obj_t *keyp, uchar_t *buf, ulong_t buf_len)
 943 {
 944         CK_RV           rv = CKR_OK;
 945         BerValue        p8obj_octs, key_octs;
 946         BerElement      *p8obj_asn = NULLBER, *key_asn = NULLBER;
 947         ber_len_t       size, tmplen;
 948         char            *cookie;
 949         int             version;
 950         uchar_t         oid[sizeof (RSA_OID) + 1];
 951         biginteger_t    tmp, tmp_nopad = { NULL, 0 };
 952 
 953         p8obj_octs.bv_val = (char *)buf;
 954 #ifdef _LP64
 955         /* LINTED E_CAST_INT_TO_SMALL_INT */
 956         p8obj_octs.bv_len = (ber_len_t)buf_len;
 957 #else
 958         p8obj_octs.bv_len = (ber_len_t)buf_len;
 959 #endif
 960 
 961         key_octs.bv_val = NULL;
 962         key_octs.bv_len = 0;
 963 
 964         /* Decode PKCS#8 object ASN.1, verifying it is RSA private key. */
 965         if ((p8obj_asn = ber_init(&p8obj_octs)) == NULLBER)
 966                 return (CKR_GENERAL_ERROR);
 967 
 968         /* PKCS#8 PrivateKeyInfo ... */
 969         if (ber_first_element(p8obj_asn, &size, &cookie) != LBER_INTEGER) {
 970                 rv = CKR_WRAPPED_KEY_INVALID;
 971                 goto cleanup_asn2rsapri;
 972         }
 973         /* ... begin-sequence { version, */
 974         (void) ber_scanf(p8obj_asn, "i", &version); /* "{i" ? */
 975 
 976         if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
 977                 rv = CKR_WRAPPED_KEY_INVALID;
 978                 goto cleanup_asn2rsapri;
 979         }
 980         /* ... begin-sequence { */
 981         (void) ber_scanf(p8obj_asn, "{");
 982 
 983         if (ber_next_element(p8obj_asn, &size, cookie) != OID_TAG) {
 984                 rv = CKR_WRAPPED_KEY_INVALID;
 985                 goto cleanup_asn2rsapri;
 986         }
 987         /* ... OID, \* RSA algorithm OID *\ */
 988         if (size != sizeof (RSA_OID)) {
 989                 rv = CKR_FUNCTION_NOT_SUPPORTED;
 990                 goto cleanup_asn2rsapri;
 991         }
 992         size = sizeof (oid);
 993         (void) ber_scanf(p8obj_asn, "s", oid, &size);
 994         if (memcmp(oid, RSA_OID, size) != 0) {
 995                 rv = CKR_FUNCTION_NOT_SUPPORTED;
 996                 goto cleanup_asn2rsapri;
 997         }
 998 
 999         if (ber_next_element(p8obj_asn, &size, cookie) != LBER_NULL) {
1000                 rv = CKR_WRAPPED_KEY_INVALID;
1001                 goto cleanup_asn2rsapri;
1002         }
1003         /* ... param(NULL) } end-sequence */
1004         (void) ber_scanf(p8obj_asn, "n");               /* "n}" ? */
1005 
1006         if (ber_next_element(p8obj_asn, &size, cookie) != LBER_OCTETSTRING) {
1007                 rv = CKR_WRAPPED_KEY_INVALID;
1008                 goto cleanup_asn2rsapri;
1009         }
1010         /* ... RSAPrivateKey } end-sequence */
1011         key_octs.bv_len = size + 1;
1012         if ((key_octs.bv_val = malloc(size + 1)) == NULL) {
1013                 rv = CKR_HOST_MEMORY;
1014                 goto cleanup_asn2rsapri;
1015         }
1016         (void) ber_scanf(p8obj_asn, "s",                /* "s}" ? */
1017             key_octs.bv_val, &key_octs.bv_len);
1018 
1019         /* Decode key octet string into softtoken key object. */
1020         if ((key_asn = ber_init(&key_octs)) == NULLBER) {
1021                 rv = CKR_GENERAL_ERROR;
1022                 goto cleanup_asn2rsapri;
1023         }
1024 
1025         /* ... begin-sequence { version, */
1026         if (ber_first_element(key_asn, &size, &cookie) != LBER_INTEGER) {
1027                 rv = CKR_WRAPPED_KEY_INVALID;
1028                 goto cleanup_asn2rsapri;
1029         }
1030         (void) ber_scanf(key_asn, "i", &version);   /* "{i" ? */
1031 
1032         /* ... modulus, */
1033         if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1034                 rv = CKR_WRAPPED_KEY_INVALID;
1035                 goto cleanup_asn2rsapri;
1036         }
1037         if (size > MAX_RSA_KEY) {
1038                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1039                 goto cleanup_asn2rsapri;
1040         }
1041         tmplen = size + 1;
1042         if ((tmp.big_value = malloc(tmplen)) == NULL) {
1043                 rv = CKR_HOST_MEMORY;
1044                 goto cleanup_asn2rsapri;
1045         }
1046         (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
1047         tmp.big_value_len = tmplen;
1048         if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1049                 free(tmp.big_value);
1050                 goto cleanup_asn2rsapri;
1051         }
1052         free(tmp.big_value);
1053         copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_MOD(keyp));
1054 
1055         /* ... public exponent, */
1056         if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1057                 rv = CKR_WRAPPED_KEY_INVALID;
1058                 goto error_asn2rsapri;
1059         }
1060         if (size > MAX_RSA_KEY) {
1061                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1062                 goto error_asn2rsapri;
1063         }
1064         tmplen = size + 1;
1065         if ((tmp.big_value = malloc(tmplen)) == NULL) {
1066                 rv = CKR_HOST_MEMORY;
1067                 goto error_asn2rsapri;
1068         }
1069         (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
1070         tmp.big_value_len = tmplen;
1071         if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1072                 free(tmp.big_value);
1073                 goto error_asn2rsapri;
1074         }
1075         free(tmp.big_value);
1076         copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_PUBEXPO(keyp));
1077 
1078         /* ... private exponent, */
1079         if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1080                 rv = CKR_WRAPPED_KEY_INVALID;
1081                 goto error_asn2rsapri;
1082         }
1083         if (size > MAX_RSA_KEY) {
1084                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1085                 goto error_asn2rsapri;
1086         }
1087         tmplen = size + 1;
1088         if ((tmp.big_value = malloc(tmplen)) == NULL) {
1089                 rv = CKR_HOST_MEMORY;
1090                 goto error_asn2rsapri;
1091         }
1092         (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
1093         tmp.big_value_len = tmplen;
1094         if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1095                 free(tmp.big_value);
1096                 goto error_asn2rsapri;
1097         }
1098         free(tmp.big_value);
1099         copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_PRIEXPO(keyp));
1100 
1101         /* ... prime 1, */
1102         if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1103                 rv = CKR_WRAPPED_KEY_INVALID;
1104                 goto error_asn2rsapri;
1105         }
1106         if (size > MAX_RSA_KEY) {
1107                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1108                 goto error_asn2rsapri;
1109         }
1110         tmplen = size + 1;
1111         if ((tmp.big_value = malloc(tmplen)) == NULL) {
1112                 rv = CKR_HOST_MEMORY;
1113                 goto error_asn2rsapri;
1114         }
1115         (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
1116         tmp.big_value_len = tmplen;
1117         if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1118                 free(tmp.big_value);
1119                 goto error_asn2rsapri;
1120         }
1121         free(tmp.big_value);
1122         copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_PRIME1(keyp));
1123 
1124         /* ... prime 2, */
1125         if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1126                 rv = CKR_WRAPPED_KEY_INVALID;
1127                 goto error_asn2rsapri;
1128         }
1129         if (size > MAX_RSA_KEY) {
1130                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1131                 goto error_asn2rsapri;
1132         }
1133         tmplen = size + 1;
1134         if ((tmp.big_value = malloc(tmplen)) == NULL) {
1135                 rv = CKR_HOST_MEMORY;
1136                 goto error_asn2rsapri;
1137         }
1138         (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
1139         tmp.big_value_len = tmplen;
1140         if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1141                 free(tmp.big_value);
1142                 goto error_asn2rsapri;
1143         }
1144         free(tmp.big_value);
1145         copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_PRIME2(keyp));
1146 
1147         /* ... exponent 1, */
1148         if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1149                 rv = CKR_WRAPPED_KEY_INVALID;
1150                 goto error_asn2rsapri;
1151         }
1152         if (size > MAX_RSA_KEY) {
1153                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1154                 goto error_asn2rsapri;
1155         }
1156         tmplen = size + 1;
1157         if ((tmp.big_value = malloc(tmplen)) == NULL) {
1158                 rv = CKR_HOST_MEMORY;
1159                 goto error_asn2rsapri;
1160         }
1161         (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
1162         tmp.big_value_len = tmplen;
1163         if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1164                 free(tmp.big_value);
1165                 goto error_asn2rsapri;
1166         }
1167         free(tmp.big_value);
1168         copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_EXPO1(keyp));
1169 
1170         /* ... exponent 2, */
1171         if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1172                 rv = CKR_WRAPPED_KEY_INVALID;
1173                 goto error_asn2rsapri;
1174         }
1175         if (size > MAX_RSA_KEY) {
1176                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1177                 goto error_asn2rsapri;
1178         }
1179         tmplen = size + 1;
1180         if ((tmp.big_value = malloc(tmplen)) == NULL) {
1181                 rv = CKR_HOST_MEMORY;
1182                 goto error_asn2rsapri;
1183         }
1184         (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
1185         tmp.big_value_len = tmplen;
1186         if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1187                 free(tmp.big_value);
1188                 goto error_asn2rsapri;
1189         }
1190         free(tmp.big_value);
1191         copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_EXPO2(keyp));
1192 
1193         /* ... coefficient } end-sequence */
1194         if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1195                 rv = CKR_WRAPPED_KEY_INVALID;
1196                 goto error_asn2rsapri;
1197         }
1198         if (size > MAX_RSA_KEY) {
1199                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1200                 goto error_asn2rsapri;
1201         }
1202         tmplen = size + 1;
1203         if ((tmp.big_value = malloc(tmplen)) == NULL) {
1204                 rv = CKR_HOST_MEMORY;
1205                 goto error_asn2rsapri;
1206         }
1207         (void) ber_scanf(key_asn, "s",          /* "s}" ? */
1208             tmp.big_value, &tmplen);
1209         tmp.big_value_len = tmplen;
1210         if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1211                 free(tmp.big_value);
1212                 goto error_asn2rsapri;
1213         }
1214         free(tmp.big_value);
1215         copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_COEF(keyp));
1216 
1217         goto cleanup_asn2rsapri;
1218 
1219 error_asn2rsapri:
1220 
1221         bigint_attr_cleanup(KEY_PRI_RSA_MOD(keyp));
1222         bigint_attr_cleanup(KEY_PRI_RSA_PUBEXPO(keyp));
1223         bigint_attr_cleanup(KEY_PRI_RSA_PRIEXPO(keyp));
1224         bigint_attr_cleanup(KEY_PRI_RSA_PRIME1(keyp));
1225         bigint_attr_cleanup(KEY_PRI_RSA_PRIME2(keyp));
1226         bigint_attr_cleanup(KEY_PRI_RSA_EXPO1(keyp));
1227         bigint_attr_cleanup(KEY_PRI_RSA_EXPO2(keyp));
1228         bigint_attr_cleanup(KEY_PRI_RSA_COEF(keyp));
1229 
1230 cleanup_asn2rsapri:
1231 
1232         freezero(tmp_nopad.big_value, tmp_nopad.big_value_len);
1233 
1234         if (p8obj_asn != NULLBER)
1235                 ber_free(p8obj_asn, 1);
1236 
1237         if (key_octs.bv_val != NULL)
1238                 free(key_octs.bv_val);
1239 
1240         if (key_asn != NULLBER)
1241                 ber_free(key_asn, 1);
1242 
1243         return (rv);
1244 }
1245 
1246 /* Decode ASN.1 BER syntax into DSA private key. */
1247 static CK_RV
1248 asn1_to_dsa_pri(private_key_obj_t *keyp, uchar_t *buf, ulong_t buf_len)
1249 {
1250         CK_RV           rv = CKR_OK;
1251         BerValue        p8obj_octs, key_octs;
1252         BerElement      *p8obj_asn = NULLBER, *key_asn = NULLBER;
1253         ber_len_t       size, tmplen;
1254         char            *cookie;
1255         int             version;
1256         uchar_t         oid[sizeof (DSA_OID) + 1];
1257         biginteger_t    tmp, tmp_nopad = { NULL, 0 };
1258 
1259         p8obj_octs.bv_val = (char *)buf;
1260 #ifdef _LP64
1261         /* LINTED E_CAST_INT_TO_SMALL_INT */
1262         p8obj_octs.bv_len = (ber_len_t)buf_len;
1263 #else
1264         p8obj_octs.bv_len = (ber_len_t)buf_len;
1265 #endif
1266 
1267         key_octs.bv_val = NULL;
1268         key_octs.bv_len = 0;
1269 
1270         /* Decode PKCS#8 object ASN.1, verifying it is DSA private key. */
1271         if ((p8obj_asn = ber_init(&p8obj_octs)) == NULLBER)
1272                 return (CKR_GENERAL_ERROR);
1273 
1274         /* PKCS#8 PrivateKeyInfo ... */
1275         if (ber_first_element(p8obj_asn, &size, &cookie) != LBER_INTEGER) {
1276                 rv = CKR_WRAPPED_KEY_INVALID;
1277                 goto cleanup_asn2dsapri;
1278         }
1279         /* ... begin-sequence { version, */
1280         (void) ber_scanf(p8obj_asn, "i", &version); /* "{i" ? */
1281 
1282         if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
1283                 rv = CKR_WRAPPED_KEY_INVALID;
1284                 goto cleanup_asn2dsapri;
1285         }
1286         /* ... begin-sequence { */
1287         (void) ber_scanf(p8obj_asn, "{");
1288 
1289         if (ber_next_element(p8obj_asn, &size, cookie) != OID_TAG) {
1290                 rv = CKR_WRAPPED_KEY_INVALID;
1291                 goto cleanup_asn2dsapri;
1292         }
1293         /* ... OID, \* DSA algorithm OID *\ */
1294         if (size != sizeof (DSA_OID)) {
1295                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1296                 goto cleanup_asn2dsapri;
1297         }
1298         size = sizeof (oid);
1299         (void) ber_scanf(p8obj_asn, "s", oid, &size);
1300         if (memcmp(oid, DSA_OID, size) != 0) {
1301                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1302                 goto cleanup_asn2dsapri;
1303         }
1304 
1305         if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
1306                 rv = CKR_WRAPPED_KEY_INVALID;
1307                 goto cleanup_asn2dsapri;
1308         }
1309         /* ... begin-sequence { */
1310         (void) ber_scanf(p8obj_asn, "{");
1311 
1312         if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1313                 rv = CKR_WRAPPED_KEY_INVALID;
1314                 goto cleanup_asn2dsapri;
1315         }
1316         /* ... prime, */
1317         if (size > MAX_DSA_KEY) {
1318                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1319                 goto cleanup_asn2dsapri;
1320         }
1321         tmplen = size + 1;
1322         if ((tmp.big_value = malloc(tmplen)) == NULL) {
1323                 rv = CKR_HOST_MEMORY;
1324                 goto cleanup_asn2dsapri;
1325         }
1326         (void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen);
1327         tmp.big_value_len = tmplen;
1328         if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1329                 free(tmp.big_value);
1330                 goto cleanup_asn2dsapri;
1331         }
1332         free(tmp.big_value);
1333         copy_bigint_attr(&tmp_nopad, KEY_PRI_DSA_PRIME(keyp));
1334 
1335         if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1336                 rv = CKR_WRAPPED_KEY_INVALID;
1337                 goto error_asn2dsapri;
1338         }
1339         /* ... subprime, */
1340         if (size > MAX_DSA_KEY) {
1341                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1342                 goto error_asn2dsapri;
1343         }
1344         tmplen = size + 1;
1345         if ((tmp.big_value = malloc(tmplen)) == NULL) {
1346                 rv = CKR_HOST_MEMORY;
1347                 goto error_asn2dsapri;
1348         }
1349         (void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen);
1350         tmp.big_value_len = tmplen;
1351         if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1352                 free(tmp.big_value);
1353                 goto error_asn2dsapri;
1354         }
1355         free(tmp.big_value);
1356         copy_bigint_attr(&tmp_nopad, KEY_PRI_DSA_SUBPRIME(keyp));
1357 
1358         if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1359                 rv = CKR_WRAPPED_KEY_INVALID;
1360                 goto error_asn2dsapri;
1361         }
1362         /* ... base } end-sequence } end-sequence */
1363         if (size > MAX_DSA_KEY) {
1364                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1365                 goto error_asn2dsapri;
1366         }
1367         tmplen = size + 1;
1368         if ((tmp.big_value = malloc(tmplen)) == NULL) {
1369                 rv = CKR_HOST_MEMORY;
1370                 goto error_asn2dsapri;
1371         }
1372         (void) ber_scanf(p8obj_asn, "s",                /* "s}}" ? */
1373             tmp.big_value, &tmplen);
1374         tmp.big_value_len = tmplen;
1375         if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1376                 free(tmp.big_value);
1377                 goto error_asn2dsapri;
1378         }
1379         free(tmp.big_value);
1380         copy_bigint_attr(&tmp_nopad, KEY_PRI_DSA_BASE(keyp));
1381 
1382         if (ber_next_element(p8obj_asn, &size, cookie) != LBER_OCTETSTRING) {
1383                 rv = CKR_WRAPPED_KEY_INVALID;
1384                 goto error_asn2dsapri;
1385         }
1386         /* ... DSAPrivateKey } end-sequence */
1387         key_octs.bv_len = size + 1;
1388         if ((key_octs.bv_val = malloc(size + 1)) == NULL) {
1389                 rv = CKR_HOST_MEMORY;
1390                 goto error_asn2dsapri;
1391         }
1392         (void) ber_scanf(p8obj_asn, "s",                /* "s}" ? */
1393             key_octs.bv_val, &key_octs.bv_len);
1394 
1395         /* Decode key octet string into softtoken key object. */
1396         if ((key_asn = ber_init(&key_octs)) == NULLBER) {
1397                 rv = CKR_GENERAL_ERROR;
1398                 goto error_asn2dsapri;
1399         }
1400 
1401         if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1402                 rv = CKR_WRAPPED_KEY_INVALID;
1403                 goto error_asn2dsapri;
1404         }
1405         /* ... value } end-sequence */
1406         if (size > MAX_DSA_KEY) {
1407                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1408                 goto error_asn2dsapri;
1409         }
1410         tmplen = size + 1;
1411         if ((tmp.big_value = malloc(tmplen)) == NULL) {
1412                 rv = CKR_HOST_MEMORY;
1413                 goto error_asn2dsapri;
1414         }
1415         (void) ber_scanf(key_asn, "s",          /* "s}" ? */
1416             tmp.big_value, &tmplen);
1417         tmp.big_value_len = tmplen;
1418         if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1419                 free(tmp.big_value);
1420                 goto error_asn2dsapri;
1421         }
1422         free(tmp.big_value);
1423         copy_bigint_attr(&tmp_nopad, KEY_PRI_DSA_VALUE(keyp));
1424 
1425         goto cleanup_asn2dsapri;
1426 
1427 error_asn2dsapri:
1428 
1429         bigint_attr_cleanup(KEY_PRI_DSA_PRIME(keyp));
1430         bigint_attr_cleanup(KEY_PRI_DSA_SUBPRIME(keyp));
1431         bigint_attr_cleanup(KEY_PRI_DSA_BASE(keyp));
1432         bigint_attr_cleanup(KEY_PRI_DSA_VALUE(keyp));
1433 
1434 cleanup_asn2dsapri:
1435 
1436         freezero(tmp_nopad.big_value, tmp_nopad.big_value_len);
1437 
1438         if (p8obj_asn != NULLBER)
1439                 ber_free(p8obj_asn, 1);
1440 
1441         if (key_octs.bv_val != NULL)
1442                 free(key_octs.bv_val);
1443 
1444         if (key_asn != NULLBER)
1445                 ber_free(key_asn, 1);
1446 
1447         return (rv);
1448 }
1449 
1450 /* Decode ASN.1 BER syntax into DH private key. */
1451 static CK_RV
1452 asn1_to_dh_pri(private_key_obj_t *keyp, uchar_t *buf, ulong_t buf_len)
1453 {
1454         CK_RV           rv = CKR_OK;
1455         BerValue        p8obj_octs, key_octs;
1456         BerElement      *p8obj_asn = NULLBER, *key_asn = NULLBER;
1457         ber_len_t       size, tmplen;
1458         char            *cookie;
1459         int             version;
1460         uchar_t         oid[sizeof (DH_OID) + 1];
1461         biginteger_t    tmp, tmp_nopad = { NULL, 0 };
1462 
1463         p8obj_octs.bv_val = (char *)buf;
1464 #ifdef _LP64
1465         /* LINTED E_CAST_INT_TO_SMALL_INT */
1466         p8obj_octs.bv_len = (ber_len_t)buf_len;
1467 #else
1468         p8obj_octs.bv_len = (ber_len_t)buf_len;
1469 #endif
1470 
1471         key_octs.bv_val = NULL;
1472         key_octs.bv_len = 0;
1473 
1474         /* Decode PKCS#8 object ASN.1, verifying it is DH private key. */
1475         if ((p8obj_asn = ber_init(&p8obj_octs)) == NULLBER)
1476                 return (CKR_GENERAL_ERROR);
1477 
1478         /* PKCS#8 PrivateKeyInfo ... */
1479         if (ber_first_element(p8obj_asn, &size, &cookie) != LBER_INTEGER) {
1480                 rv = CKR_WRAPPED_KEY_INVALID;
1481                 goto cleanup_asn2dhpri;
1482         }
1483         /* ... begin-sequence { version, */
1484         (void) ber_scanf(p8obj_asn, "i", &version); /* "{i" ? */
1485 
1486         if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
1487                 rv = CKR_WRAPPED_KEY_INVALID;
1488                 goto cleanup_asn2dhpri;
1489         }
1490         /* ... begin-sequence { */
1491         (void) ber_scanf(p8obj_asn, "{");
1492 
1493         if (ber_next_element(p8obj_asn, &size, cookie) != OID_TAG) {
1494                 rv = CKR_WRAPPED_KEY_INVALID;
1495                 goto cleanup_asn2dhpri;
1496         }
1497         /* ... OID, \* DH algorithm OID *\ */
1498         if (size != sizeof (DH_OID)) {
1499                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1500                 goto cleanup_asn2dhpri;
1501         }
1502         size = sizeof (oid);
1503         (void) ber_scanf(p8obj_asn, "s", oid, &size);
1504         if (memcmp(oid, DH_OID, size) != 0) {
1505                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1506                 goto cleanup_asn2dhpri;
1507         }
1508 
1509         if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
1510                 rv = CKR_WRAPPED_KEY_INVALID;
1511                 goto cleanup_asn2dhpri;
1512         }
1513         /* ... begin-sequence { */
1514         (void) ber_scanf(p8obj_asn, "{");
1515 
1516         if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1517                 rv = CKR_WRAPPED_KEY_INVALID;
1518                 goto cleanup_asn2dhpri;
1519         }
1520         /* ... prime, */
1521         if (size > MAX_DH_KEY) {
1522                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1523                 goto cleanup_asn2dhpri;
1524         }
1525         tmplen = size + 1;
1526         if ((tmp.big_value = malloc(tmplen)) == NULL) {
1527                 rv = CKR_HOST_MEMORY;
1528                 goto cleanup_asn2dhpri;
1529         }
1530         (void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen);
1531         tmp.big_value_len = tmplen;
1532         if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1533                 free(tmp.big_value);
1534                 goto cleanup_asn2dhpri;
1535         }
1536         free(tmp.big_value);
1537         copy_bigint_attr(&tmp_nopad, KEY_PRI_DH_PRIME(keyp));
1538 
1539         if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1540                 rv = CKR_WRAPPED_KEY_INVALID;
1541                 goto error_asn2dhpri;
1542         }
1543         /* ... base } end-sequence } end-sequence */
1544         if (size > MAX_DH_KEY) {
1545                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1546                 goto error_asn2dhpri;
1547         }
1548         tmplen = size + 1;
1549         if ((tmp.big_value = malloc(tmplen)) == NULL) {
1550                 rv = CKR_HOST_MEMORY;
1551                 goto error_asn2dhpri;
1552         }
1553         (void) ber_scanf(p8obj_asn, "s",                /* "s}}" ? */
1554             tmp.big_value, &tmplen);
1555         tmp.big_value_len = tmplen;
1556         if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1557                 free(tmp.big_value);
1558                 goto error_asn2dhpri;
1559         }
1560         free(tmp.big_value);
1561         copy_bigint_attr(&tmp_nopad, KEY_PRI_DH_BASE(keyp));
1562 
1563         if (ber_next_element(p8obj_asn, &size, cookie) != LBER_OCTETSTRING) {
1564                 rv = CKR_WRAPPED_KEY_INVALID;
1565                 goto error_asn2dhpri;
1566         }
1567         /* ... DHPrivateKey } end-sequence */
1568         key_octs.bv_len = size + 1;
1569         if ((key_octs.bv_val = malloc(size + 1)) == NULL) {
1570                 rv = CKR_HOST_MEMORY;
1571                 goto error_asn2dhpri;
1572         }
1573         (void) ber_scanf(p8obj_asn, "s",                /* "s}" ? */
1574             key_octs.bv_val, &key_octs.bv_len);
1575 
1576         /* Decode key octet string into softtoken key object. */
1577         if ((key_asn = ber_init(&key_octs)) == NULLBER) {
1578                 rv = CKR_GENERAL_ERROR;
1579                 goto error_asn2dhpri;
1580         }
1581 
1582         if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1583                 rv = CKR_WRAPPED_KEY_INVALID;
1584                 goto error_asn2dhpri;
1585         }
1586         /* ... value } end-sequence */
1587         if (size > MAX_DH_KEY) {
1588                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1589                 goto error_asn2dhpri;
1590         }
1591         tmplen = size + 1;
1592         if ((tmp.big_value = malloc(tmplen)) == NULL) {
1593                 rv = CKR_HOST_MEMORY;
1594                 goto error_asn2dhpri;
1595         }
1596         (void) ber_scanf(key_asn, "s",          /* "s}" ? */
1597             tmp.big_value, &tmplen);
1598         tmp.big_value_len = tmplen;
1599         if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1600                 free(tmp.big_value);
1601                 goto error_asn2dhpri;
1602         }
1603         free(tmp.big_value);
1604         copy_bigint_attr(&tmp_nopad, KEY_PRI_DH_VALUE(keyp));
1605 
1606         goto cleanup_asn2dhpri;
1607 
1608 error_asn2dhpri:
1609 
1610         bigint_attr_cleanup(KEY_PRI_DH_PRIME(keyp));
1611         bigint_attr_cleanup(KEY_PRI_DH_BASE(keyp));
1612         bigint_attr_cleanup(KEY_PRI_DH_VALUE(keyp));
1613 
1614 cleanup_asn2dhpri:
1615 
1616         freezero(tmp_nopad.big_value, tmp_nopad.big_value_len);
1617 
1618         if (p8obj_asn != NULLBER)
1619                 ber_free(p8obj_asn, 1);
1620 
1621         if (key_octs.bv_val != NULL)
1622                 free(key_octs.bv_val);
1623 
1624         if (key_asn != NULLBER)
1625                 ber_free(key_asn, 1);
1626 
1627         return (rv);
1628 }
1629 
1630 /* Decode ASN.1 BER syntax into DH X9.42 private key. */
1631 static CK_RV
1632 asn1_to_x942_dh_pri(private_key_obj_t *keyp, uchar_t *buf, ulong_t buf_len)
1633 {
1634         CK_RV           rv = CKR_OK;
1635         BerValue        p8obj_octs, key_octs;
1636         BerElement      *p8obj_asn = NULLBER, *key_asn = NULLBER;
1637         ber_len_t       size, tmplen;
1638         char            *cookie;
1639         int             version;
1640         uchar_t         oid[sizeof (DH942_OID) + 1];
1641         biginteger_t    tmp, tmp_nopad = { NULL, 0 };
1642 
1643         p8obj_octs.bv_val = (char *)buf;
1644 #ifdef _LP64
1645         /* LINTED E_CAST_INT_TO_SMALL_INT */
1646         p8obj_octs.bv_len = (ber_len_t)buf_len;
1647 #else
1648         p8obj_octs.bv_len = (ber_len_t)buf_len;
1649 #endif
1650 
1651         key_octs.bv_val = NULL;
1652         key_octs.bv_len = 0;
1653 
1654         /* Decode PKCS#8 object ASN.1, verifying it is DH X9.42 private key. */
1655         if ((p8obj_asn = ber_init(&p8obj_octs)) == NULLBER)
1656                 return (CKR_GENERAL_ERROR);
1657 
1658         /* PKCS#8 PrivateKeyInfo ... */
1659         if (ber_first_element(p8obj_asn, &size, &cookie) != LBER_INTEGER) {
1660                 rv = CKR_WRAPPED_KEY_INVALID;
1661                 goto cleanup_asn2x942dhpri;
1662         }
1663         /* ... begin-sequence { version, */
1664         (void) ber_scanf(p8obj_asn, "i", &version); /* "{i" ? */
1665 
1666         if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
1667                 rv = CKR_WRAPPED_KEY_INVALID;
1668                 goto cleanup_asn2x942dhpri;
1669         }
1670         /* ... begin-sequence { */
1671         (void) ber_scanf(p8obj_asn, "{");
1672 
1673         if (ber_next_element(p8obj_asn, &size, cookie) != OID_TAG) {
1674                 rv = CKR_WRAPPED_KEY_INVALID;
1675                 goto cleanup_asn2x942dhpri;
1676         }
1677         /* ... OID, \* DH X9.42 algorithm OID *\ */
1678         if (size != sizeof (DH942_OID)) {
1679                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1680                 goto cleanup_asn2x942dhpri;
1681         }
1682         size = sizeof (oid);
1683         (void) ber_scanf(p8obj_asn, "s", oid, &size);
1684         if (memcmp(oid, DH942_OID, size) != 0) {
1685                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1686                 goto cleanup_asn2x942dhpri;
1687         }
1688 
1689         if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
1690                 rv = CKR_WRAPPED_KEY_INVALID;
1691                 goto cleanup_asn2x942dhpri;
1692         }
1693         /* ... begin-sequence { */
1694         (void) ber_scanf(p8obj_asn, "{");
1695 
1696         if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1697                 rv = CKR_WRAPPED_KEY_INVALID;
1698                 goto cleanup_asn2x942dhpri;
1699         }
1700         /* ... prime, */
1701         if (size > MAX_DH942_KEY) {
1702                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1703                 goto cleanup_asn2x942dhpri;
1704         }
1705         tmplen = size + 1;
1706         if ((tmp.big_value = malloc(tmplen)) == NULL) {
1707                 rv = CKR_HOST_MEMORY;
1708                 goto cleanup_asn2x942dhpri;
1709         }
1710         (void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen);
1711         tmp.big_value_len = tmplen;
1712         if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1713                 free(tmp.big_value);
1714                 goto cleanup_asn2x942dhpri;
1715         }
1716         free(tmp.big_value);
1717         copy_bigint_attr(&tmp_nopad, KEY_PRI_DH942_PRIME(keyp));
1718 
1719         if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1720                 rv = CKR_WRAPPED_KEY_INVALID;
1721                 goto error_asn2x942dhpri;
1722         }
1723         /* ... base, */
1724         if (size > MAX_DH942_KEY) {
1725                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1726                 goto error_asn2x942dhpri;
1727         }
1728         tmplen = size + 1;
1729         if ((tmp.big_value = malloc(tmplen)) == NULL) {
1730                 rv = CKR_HOST_MEMORY;
1731                 goto error_asn2x942dhpri;
1732         }
1733         (void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen);
1734         tmp.big_value_len = tmplen;
1735         if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1736                 free(tmp.big_value);
1737                 goto error_asn2x942dhpri;
1738         }
1739         free(tmp.big_value);
1740         copy_bigint_attr(&tmp_nopad, KEY_PRI_DH942_BASE(keyp));
1741 
1742         if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1743                 rv = CKR_WRAPPED_KEY_INVALID;
1744                 goto error_asn2x942dhpri;
1745         }
1746         /* ... subprime } end-sequence } end-sequence */
1747         if (size > MAX_DH942_KEY) {
1748                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1749                 goto error_asn2x942dhpri;
1750         }
1751         tmplen = size + 1;
1752         if ((tmp.big_value = malloc(tmplen)) == NULL) {
1753                 rv = CKR_HOST_MEMORY;
1754                 goto error_asn2x942dhpri;
1755         }
1756         (void) ber_scanf(p8obj_asn, "s",                /* "s}}" ? */
1757             tmp.big_value, &tmplen);
1758         tmp.big_value_len = tmplen;
1759         if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1760                 free(tmp.big_value);
1761                 goto error_asn2x942dhpri;
1762         }
1763         free(tmp.big_value);
1764         copy_bigint_attr(&tmp_nopad, KEY_PRI_DH942_SUBPRIME(keyp));
1765 
1766         if (ber_next_element(p8obj_asn, &size, cookie) != LBER_OCTETSTRING) {
1767                 rv = CKR_WRAPPED_KEY_INVALID;
1768                 goto error_asn2x942dhpri;
1769         }
1770         /* ... DHPrivateKey } end-sequence */
1771         key_octs.bv_len = size + 1;
1772         if ((key_octs.bv_val = malloc(size + 1)) == NULL) {
1773                 rv = CKR_HOST_MEMORY;
1774                 goto error_asn2x942dhpri;
1775         }
1776         (void) ber_scanf(p8obj_asn, "s",                /* "s}" ? */
1777             key_octs.bv_val, &key_octs.bv_len);
1778 
1779         /* Decode key octet string into softtoken key object. */
1780         if ((key_asn = ber_init(&key_octs)) == NULLBER) {
1781                 rv = CKR_GENERAL_ERROR;
1782                 goto error_asn2x942dhpri;
1783         }
1784 
1785         if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1786                 rv = CKR_WRAPPED_KEY_INVALID;
1787                 goto error_asn2x942dhpri;
1788         }
1789         /* ... value } end-sequence */
1790         if (size > MAX_DH942_KEY) {
1791                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1792                 goto error_asn2x942dhpri;
1793         }
1794         tmplen = size + 1;
1795         if ((tmp.big_value = malloc(tmplen)) == NULL) {
1796                 rv = CKR_HOST_MEMORY;
1797                 goto error_asn2x942dhpri;
1798         }
1799         (void) ber_scanf(key_asn, "s",          /* "s}" ? */
1800             tmp.big_value, &tmplen);
1801         tmp.big_value_len = tmplen;
1802         if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1803                 free(tmp.big_value);
1804                 goto error_asn2x942dhpri;
1805         }
1806         free(tmp.big_value);
1807         copy_bigint_attr(&tmp_nopad, KEY_PRI_DH942_VALUE(keyp));
1808 
1809         goto cleanup_asn2x942dhpri;
1810 
1811 error_asn2x942dhpri:
1812 
1813         bigint_attr_cleanup(KEY_PRI_DH942_PRIME(keyp));
1814         bigint_attr_cleanup(KEY_PRI_DH942_BASE(keyp));
1815         bigint_attr_cleanup(KEY_PRI_DH942_SUBPRIME(keyp));
1816         bigint_attr_cleanup(KEY_PRI_DH942_VALUE(keyp));
1817 
1818 cleanup_asn2x942dhpri:
1819 
1820         freezero(tmp_nopad.big_value, tmp_nopad.big_value_len);
1821 
1822         if (p8obj_asn != NULLBER)
1823                 ber_free(p8obj_asn, 1);
1824 
1825         if (key_octs.bv_val != NULL)
1826                 free(key_octs.bv_val);
1827 
1828         if (key_asn != NULLBER)
1829                 ber_free(key_asn, 1);
1830 
1831         return (rv);
1832 }
1833 
1834 /*
1835  * Decode the object key from ASN.1 format into soft_object_t.
1836  */
1837 CK_RV
1838 soft_asn1_to_object(soft_object_t *objp, uchar_t *buf, ulong_t buf_len)
1839 {
1840         CK_RV           rv = CKR_OK;
1841         CK_OBJECT_CLASS class = objp->class;
1842         CK_KEY_TYPE     keytype = objp->key_type;
1843         private_key_obj_t *pvk;
1844 
1845         switch (class) {
1846 
1847         case CKO_PRIVATE_KEY:
1848                 /* Allocate storage for Private Key Object. */
1849                 if ((pvk = calloc(1, sizeof (private_key_obj_t))) == NULL) {
1850                         rv = CKR_HOST_MEMORY;
1851                         return (rv);
1852                 }
1853 
1854                 switch (keytype) {
1855                 case CKK_RSA:
1856                         rv = asn1_to_rsa_pri(pvk, buf, buf_len);
1857                         break;
1858 
1859                 case CKK_DSA:
1860                         rv = asn1_to_dsa_pri(pvk, buf, buf_len);
1861                         break;
1862 
1863                 case CKK_DH:
1864                         rv = asn1_to_dh_pri(pvk, buf, buf_len);
1865                         break;
1866 
1867                 case CKK_X9_42_DH:
1868                         rv = asn1_to_x942_dh_pri(pvk, buf, buf_len);
1869                         break;
1870 
1871                 default:
1872                         rv = CKR_FUNCTION_NOT_SUPPORTED;
1873                         break;
1874 
1875                 } /* keytype */
1876 
1877                 if (rv != CKR_OK)
1878                         free(pvk);
1879                 else
1880                         objp->object_class_u.private_key = pvk;
1881                 break;
1882 
1883         default:
1884                 rv = CKR_FUNCTION_NOT_SUPPORTED;
1885                 break;
1886 
1887         } /* class */
1888 
1889         return (rv);
1890 }