PageRenderTime 98ms CodeModel.GetById 11ms app.highlight 76ms RepoModel.GetById 1ms app.codeStats 0ms

/security/nss/lib/pk11wrap/pk11mech.c

http://github.com/zpao/v8monkey
C | 1906 lines | 1690 code | 84 blank | 132 comment | 164 complexity | 81028665778a4b0cc91fab47a39fc011 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/* ***** BEGIN LICENSE BLOCK *****
   2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
   3 *
   4 * The contents of this file are subject to the Mozilla Public License Version
   5 * 1.1 (the "License"); you may not use this file except in compliance with
   6 * the License. You may obtain a copy of the License at
   7 * http://www.mozilla.org/MPL/
   8 *
   9 * Software distributed under the License is distributed on an "AS IS" basis,
  10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11 * for the specific language governing rights and limitations under the
  12 * License.
  13 *
  14 * The Original Code is the Netscape security libraries.
  15 *
  16 * The Initial Developer of the Original Code is
  17 * Netscape Communications Corporation.
  18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
  19 * the Initial Developer. All Rights Reserved.
  20 *
  21 * Contributor(s):
  22 *   Dr Stephen Henson <stephen.henson@gemplus.com>
  23 *   Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
  24 *
  25 * Alternatively, the contents of this file may be used under the terms of
  26 * either the GNU General Public License Version 2 or later (the "GPL"), or
  27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  28 * in which case the provisions of the GPL or the LGPL are applicable instead
  29 * of those above. If you wish to allow use of your version of this file only
  30 * under the terms of either the GPL or the LGPL, and not to allow others to
  31 * use your version of this file under the terms of the MPL, indicate your
  32 * decision by deleting the provisions above and replace them with the notice
  33 * and other provisions required by the GPL or the LGPL. If you do not delete
  34 * the provisions above, a recipient may use your version of this file under
  35 * the terms of any one of the MPL, the GPL or the LGPL.
  36 *
  37 * ***** END LICENSE BLOCK ***** */
  38/*
  39 * This file maps various PKCS #11 Mechanisms to related mechanisms, key
  40 * types, and ASN.1 encodings.
  41 */
  42#include "seccomon.h"
  43#include "secmod.h"
  44#include "secmodi.h"
  45#include "pkcs11t.h"
  46#include "pk11func.h"
  47#include "secitem.h"
  48#include "secder.h"
  49#include "secasn1.h" 
  50#include "secoid.h"
  51#include "secerr.h"
  52
  53/*************************************************************
  54 * local static and global data
  55 *************************************************************/
  56
  57/*
  58 * Tables used for Extended mechanism mapping (currently not used)
  59 */
  60typedef struct {
  61	CK_MECHANISM_TYPE keyGen;
  62	CK_KEY_TYPE keyType;
  63	CK_MECHANISM_TYPE type;
  64	CK_MECHANISM_TYPE padType;
  65	int blockSize;
  66	int iv;
  67} pk11MechanismData;
  68	
  69static pk11MechanismData pk11_default = 
  70  { CKM_GENERIC_SECRET_KEY_GEN, CKK_GENERIC_SECRET, 
  71	CKM_FAKE_RANDOM, CKM_FAKE_RANDOM, 8, 8 };
  72static pk11MechanismData *pk11_MechanismTable = NULL;
  73static int pk11_MechTableSize = 0;
  74static int pk11_MechEntrySize = 0;
  75
  76/*
  77 * list of mechanisms we're willing to wrap secret keys with.
  78 * This list is ordered by preference.
  79 */
  80CK_MECHANISM_TYPE wrapMechanismList[] = {
  81    CKM_DES3_ECB,
  82    CKM_CAST5_ECB,
  83    CKM_AES_ECB,
  84    CKM_CAMELLIA_ECB,
  85    CKM_SEED_ECB,
  86    CKM_CAST5_ECB,
  87    CKM_DES_ECB,
  88    CKM_KEY_WRAP_LYNKS,
  89    CKM_IDEA_ECB,
  90    CKM_CAST3_ECB,
  91    CKM_CAST_ECB,
  92    CKM_RC5_ECB,
  93    CKM_RC2_ECB,
  94    CKM_CDMF_ECB,
  95    CKM_SKIPJACK_WRAP,
  96};
  97
  98int wrapMechanismCount = sizeof(wrapMechanismList)/sizeof(wrapMechanismList[0]);
  99
 100/*********************************************************************
 101 *       Mechanism Mapping functions
 102 *********************************************************************/
 103
 104/*
 105 * lookup an entry in the mechanism table. If none found, return the
 106 * default structure.
 107 */
 108static pk11MechanismData *
 109pk11_lookup(CK_MECHANISM_TYPE type)
 110{
 111    int i;
 112    for (i=0; i < pk11_MechEntrySize; i++) {
 113	if (pk11_MechanismTable[i].type == type) {
 114	     return (&pk11_MechanismTable[i]);
 115	}
 116    }
 117    return &pk11_default;
 118}
 119
 120/*
 121 * find the best key wrap mechanism for this slot.
 122 */
 123CK_MECHANISM_TYPE
 124PK11_GetBestWrapMechanism(PK11SlotInfo *slot)
 125{
 126    int i;
 127    for (i=0; i < wrapMechanismCount; i++) {
 128	if (PK11_DoesMechanism(slot,wrapMechanismList[i])) {
 129	    return wrapMechanismList[i];
 130	}
 131    }
 132    return CKM_INVALID_MECHANISM;
 133}
 134
 135/*
 136 * NOTE: This is not thread safe. Called at init time, and when loading
 137 * a new Entry. It is reasonably safe as long as it is not re-entered
 138 * (readers will always see a consistant table)
 139 *
 140 * This routine is called to add entries to the mechanism table, once there,
 141 * they can not be removed.
 142 */
 143void
 144PK11_AddMechanismEntry(CK_MECHANISM_TYPE type, CK_KEY_TYPE key,
 145		 	CK_MECHANISM_TYPE keyGen, 
 146			CK_MECHANISM_TYPE padType,
 147			int ivLen, int blockSize)
 148{
 149    int tableSize = pk11_MechTableSize;
 150    int size = pk11_MechEntrySize;
 151    int entry = size++;
 152    pk11MechanismData *old = pk11_MechanismTable;
 153    pk11MechanismData *newt = pk11_MechanismTable;
 154
 155	
 156    if (size > tableSize) {
 157	int oldTableSize = tableSize;
 158	tableSize += 10;
 159	newt = PORT_NewArray(pk11MechanismData, tableSize);
 160	if (newt == NULL) return;
 161
 162	if (old) PORT_Memcpy(newt, old, oldTableSize*sizeof(*newt));
 163    } else old = NULL;
 164
 165    newt[entry].type = type;
 166    newt[entry].keyType = key;
 167    newt[entry].keyGen = keyGen;
 168    newt[entry].padType = padType;
 169    newt[entry].iv = ivLen;
 170    newt[entry].blockSize = blockSize;
 171
 172    pk11_MechanismTable = newt;
 173    pk11_MechTableSize = tableSize;
 174    pk11_MechEntrySize = size;
 175    if (old) PORT_Free(old);
 176}
 177
 178/*
 179 * Get the key type needed for the given mechanism
 180 */
 181CK_MECHANISM_TYPE
 182PK11_GetKeyMechanism(CK_KEY_TYPE type)
 183{
 184    switch (type) {
 185    case CKK_SEED:
 186	return CKM_SEED_CBC;
 187    case CKK_CAMELLIA:
 188	return CKM_CAMELLIA_CBC;
 189    case CKK_AES:
 190	return CKM_AES_CBC;
 191    case CKK_DES:
 192	return CKM_DES_CBC;
 193    case CKK_DES3:
 194	return CKM_DES3_KEY_GEN;
 195    case CKK_DES2:
 196	return CKM_DES2_KEY_GEN;
 197    case CKK_CDMF:
 198	return CKM_CDMF_CBC;
 199    case CKK_RC2:
 200	return CKM_RC2_CBC;
 201    case CKK_RC4:
 202	return CKM_RC4;
 203    case CKK_RC5:
 204	return CKM_RC5_CBC;
 205    case CKK_SKIPJACK:
 206	return CKM_SKIPJACK_CBC64;
 207    case CKK_BATON:
 208	return CKM_BATON_CBC128;
 209    case CKK_JUNIPER:
 210	return CKM_JUNIPER_CBC128;
 211    case CKK_IDEA:
 212	return CKM_IDEA_CBC;
 213    case CKK_CAST:
 214	return CKM_CAST_CBC;
 215    case CKK_CAST3:
 216	return CKM_CAST3_CBC;
 217    case CKK_CAST5:
 218	return CKM_CAST5_CBC;
 219    case CKK_RSA:
 220	return CKM_RSA_PKCS;
 221    case CKK_DSA:
 222	return CKM_DSA;
 223    case CKK_DH:
 224	return CKM_DH_PKCS_DERIVE;
 225    case CKK_KEA:
 226	return CKM_KEA_KEY_DERIVE;
 227    case CKK_EC:  /* CKK_ECDSA is deprecated */
 228	return CKM_ECDSA;
 229    case CKK_GENERIC_SECRET:
 230    default:
 231	return CKM_SHA_1_HMAC;
 232    }
 233}
 234
 235/*
 236 * Get the key type needed for the given mechanism
 237 */
 238CK_MECHANISM_TYPE
 239PK11_GetKeyType(CK_MECHANISM_TYPE type,unsigned long len)
 240{
 241    switch (type) {
 242    case CKM_SEED_ECB:
 243    case CKM_SEED_CBC:
 244    case CKM_SEED_MAC:
 245    case CKM_SEED_MAC_GENERAL:
 246    case CKM_SEED_CBC_PAD:
 247    case CKM_SEED_KEY_GEN:
 248	return CKK_SEED;
 249    case CKM_CAMELLIA_ECB:
 250    case CKM_CAMELLIA_CBC:
 251    case CKM_CAMELLIA_MAC:
 252    case CKM_CAMELLIA_MAC_GENERAL:
 253    case CKM_CAMELLIA_CBC_PAD:
 254    case CKM_CAMELLIA_KEY_GEN:
 255	return CKK_CAMELLIA;
 256    case CKM_AES_ECB:
 257    case CKM_AES_CBC:
 258    case CKM_AES_MAC:
 259    case CKM_AES_MAC_GENERAL:
 260    case CKM_AES_CBC_PAD:
 261    case CKM_AES_KEY_GEN:
 262    case CKM_NETSCAPE_AES_KEY_WRAP:
 263    case CKM_NETSCAPE_AES_KEY_WRAP_PAD:
 264	return CKK_AES;
 265    case CKM_DES_ECB:
 266    case CKM_DES_CBC:
 267    case CKM_DES_MAC:
 268    case CKM_DES_MAC_GENERAL:
 269    case CKM_DES_CBC_PAD:
 270    case CKM_DES_KEY_GEN:
 271    case CKM_KEY_WRAP_LYNKS:
 272    case CKM_PBE_MD2_DES_CBC:
 273    case CKM_PBE_MD5_DES_CBC:
 274	return CKK_DES;
 275    case CKM_DES3_ECB:
 276    case CKM_DES3_CBC:
 277    case CKM_DES3_MAC:
 278    case CKM_DES3_MAC_GENERAL:
 279    case CKM_DES3_CBC_PAD:
 280	return (len == 16) ? CKK_DES2 : CKK_DES3;
 281    case CKM_DES2_KEY_GEN:
 282    case CKM_PBE_SHA1_DES2_EDE_CBC:
 283	return CKK_DES2;
 284    case CKM_PBE_SHA1_DES3_EDE_CBC:
 285    case CKM_DES3_KEY_GEN:
 286	return CKK_DES3;
 287    case CKM_CDMF_ECB:
 288    case CKM_CDMF_CBC:
 289    case CKM_CDMF_MAC:
 290    case CKM_CDMF_MAC_GENERAL:
 291    case CKM_CDMF_CBC_PAD:
 292    case CKM_CDMF_KEY_GEN:
 293	return CKK_CDMF;
 294    case CKM_RC2_ECB:
 295    case CKM_RC2_CBC:
 296    case CKM_RC2_MAC:
 297    case CKM_RC2_MAC_GENERAL:
 298    case CKM_RC2_CBC_PAD:
 299    case CKM_RC2_KEY_GEN:
 300    case CKM_PBE_SHA1_RC2_128_CBC:
 301    case CKM_PBE_SHA1_RC2_40_CBC:
 302	return CKK_RC2;
 303    case CKM_RC4:
 304    case CKM_RC4_KEY_GEN:
 305	return CKK_RC4;
 306    case CKM_RC5_ECB:
 307    case CKM_RC5_CBC:
 308    case CKM_RC5_MAC:
 309    case CKM_RC5_MAC_GENERAL:
 310    case CKM_RC5_CBC_PAD:
 311    case CKM_RC5_KEY_GEN:
 312	return CKK_RC5;
 313    case CKM_SKIPJACK_CBC64:
 314    case CKM_SKIPJACK_ECB64:
 315    case CKM_SKIPJACK_OFB64:
 316    case CKM_SKIPJACK_CFB64:
 317    case CKM_SKIPJACK_CFB32:
 318    case CKM_SKIPJACK_CFB16:
 319    case CKM_SKIPJACK_CFB8:
 320    case CKM_SKIPJACK_KEY_GEN:
 321    case CKM_SKIPJACK_WRAP:
 322    case CKM_SKIPJACK_PRIVATE_WRAP:
 323	return CKK_SKIPJACK;
 324    case CKM_BATON_ECB128:
 325    case CKM_BATON_ECB96:
 326    case CKM_BATON_CBC128:
 327    case CKM_BATON_COUNTER:
 328    case CKM_BATON_SHUFFLE:
 329    case CKM_BATON_WRAP:
 330    case CKM_BATON_KEY_GEN:
 331	return CKK_BATON;
 332    case CKM_JUNIPER_ECB128:
 333    case CKM_JUNIPER_CBC128:
 334    case CKM_JUNIPER_COUNTER:
 335    case CKM_JUNIPER_SHUFFLE:
 336    case CKM_JUNIPER_WRAP:
 337    case CKM_JUNIPER_KEY_GEN:
 338	return CKK_JUNIPER;
 339    case CKM_IDEA_CBC:
 340    case CKM_IDEA_ECB:
 341    case CKM_IDEA_MAC:
 342    case CKM_IDEA_MAC_GENERAL:
 343    case CKM_IDEA_CBC_PAD:
 344    case CKM_IDEA_KEY_GEN:
 345	return CKK_IDEA;
 346    case CKM_CAST_ECB:
 347    case CKM_CAST_CBC:
 348    case CKM_CAST_MAC:
 349    case CKM_CAST_MAC_GENERAL:
 350    case CKM_CAST_CBC_PAD:
 351    case CKM_CAST_KEY_GEN:
 352    case CKM_PBE_MD5_CAST_CBC:
 353	return CKK_CAST;
 354    case CKM_CAST3_ECB:
 355    case CKM_CAST3_CBC:
 356    case CKM_CAST3_MAC:
 357    case CKM_CAST3_MAC_GENERAL:
 358    case CKM_CAST3_CBC_PAD:
 359    case CKM_CAST3_KEY_GEN:
 360    case CKM_PBE_MD5_CAST3_CBC:
 361	return CKK_CAST3;
 362    case CKM_CAST5_ECB:
 363    case CKM_CAST5_CBC:
 364    case CKM_CAST5_MAC:
 365    case CKM_CAST5_MAC_GENERAL:
 366    case CKM_CAST5_CBC_PAD:
 367    case CKM_CAST5_KEY_GEN:
 368    case CKM_PBE_MD5_CAST5_CBC:
 369	return CKK_CAST5;
 370    case CKM_RSA_PKCS:
 371    case CKM_RSA_9796:
 372    case CKM_RSA_X_509:
 373    case CKM_MD2_RSA_PKCS:
 374    case CKM_MD5_RSA_PKCS:
 375    case CKM_SHA1_RSA_PKCS:
 376    case CKM_SHA224_RSA_PKCS:
 377    case CKM_SHA256_RSA_PKCS:
 378    case CKM_SHA384_RSA_PKCS:
 379    case CKM_SHA512_RSA_PKCS:
 380    case CKM_KEY_WRAP_SET_OAEP:
 381    case CKM_RSA_PKCS_KEY_PAIR_GEN:
 382    case CKM_RSA_X9_31_KEY_PAIR_GEN:
 383	return CKK_RSA;
 384    case CKM_DSA:
 385    case CKM_DSA_SHA1:
 386    case CKM_DSA_KEY_PAIR_GEN:
 387	return CKK_DSA;
 388    case CKM_DH_PKCS_DERIVE:
 389    case CKM_DH_PKCS_KEY_PAIR_GEN:
 390	return CKK_DH;
 391    case CKM_KEA_KEY_DERIVE:
 392    case CKM_KEA_KEY_PAIR_GEN:
 393	return CKK_KEA;
 394    case CKM_ECDSA:
 395    case CKM_ECDSA_SHA1:
 396    case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */
 397    case CKM_ECDH1_DERIVE:
 398	return CKK_EC;  /* CKK_ECDSA is deprecated */
 399    case CKM_SSL3_PRE_MASTER_KEY_GEN:
 400    case CKM_GENERIC_SECRET_KEY_GEN:
 401    case CKM_SSL3_MASTER_KEY_DERIVE:
 402    case CKM_SSL3_MASTER_KEY_DERIVE_DH:
 403    case CKM_SSL3_KEY_AND_MAC_DERIVE:
 404    case CKM_SSL3_SHA1_MAC:
 405    case CKM_SSL3_MD5_MAC:
 406    case CKM_TLS_MASTER_KEY_DERIVE:
 407    case CKM_TLS_MASTER_KEY_DERIVE_DH:
 408    case CKM_TLS_KEY_AND_MAC_DERIVE:
 409    case CKM_SHA_1_HMAC:
 410    case CKM_SHA_1_HMAC_GENERAL:
 411    case CKM_SHA224_HMAC:
 412    case CKM_SHA224_HMAC_GENERAL:
 413    case CKM_SHA256_HMAC:
 414    case CKM_SHA256_HMAC_GENERAL:
 415    case CKM_SHA384_HMAC:
 416    case CKM_SHA384_HMAC_GENERAL:
 417    case CKM_SHA512_HMAC:
 418    case CKM_SHA512_HMAC_GENERAL:
 419    case CKM_MD2_HMAC:
 420    case CKM_MD2_HMAC_GENERAL:
 421    case CKM_MD5_HMAC:
 422    case CKM_MD5_HMAC_GENERAL:
 423    case CKM_TLS_PRF_GENERAL:
 424	return CKK_GENERIC_SECRET;
 425    default:
 426	return pk11_lookup(type)->keyType;
 427    }
 428}
 429
 430/*
 431 * Get the Key Gen Mechanism needed for the given 
 432 * crypto mechanism
 433 */
 434CK_MECHANISM_TYPE
 435PK11_GetKeyGen(CK_MECHANISM_TYPE type)
 436{
 437    return PK11_GetKeyGenWithSize(type, 0);
 438}
 439
 440CK_MECHANISM_TYPE
 441PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size)
 442{
 443    switch (type) {
 444    case CKM_SEED_ECB:
 445    case CKM_SEED_CBC:
 446    case CKM_SEED_MAC:
 447    case CKM_SEED_MAC_GENERAL:
 448    case CKM_SEED_CBC_PAD:
 449    case CKM_SEED_KEY_GEN:
 450	return CKM_SEED_KEY_GEN;
 451    case CKM_CAMELLIA_ECB:
 452    case CKM_CAMELLIA_CBC:
 453    case CKM_CAMELLIA_MAC:
 454    case CKM_CAMELLIA_MAC_GENERAL:
 455    case CKM_CAMELLIA_CBC_PAD:
 456    case CKM_CAMELLIA_KEY_GEN:
 457	return CKM_CAMELLIA_KEY_GEN;
 458    case CKM_AES_ECB:
 459    case CKM_AES_CBC:
 460    case CKM_AES_MAC:
 461    case CKM_AES_MAC_GENERAL:
 462    case CKM_AES_CBC_PAD:
 463    case CKM_AES_KEY_GEN:
 464	return CKM_AES_KEY_GEN;
 465    case CKM_DES_ECB:
 466    case CKM_DES_CBC:
 467    case CKM_DES_MAC:
 468    case CKM_DES_MAC_GENERAL:
 469    case CKM_KEY_WRAP_LYNKS:
 470    case CKM_DES_CBC_PAD:
 471    case CKM_DES_KEY_GEN:
 472	return CKM_DES_KEY_GEN;
 473    case CKM_DES3_ECB:
 474    case CKM_DES3_CBC:
 475    case CKM_DES3_MAC:
 476    case CKM_DES3_MAC_GENERAL:
 477    case CKM_DES3_CBC_PAD:
 478	return (size == 16) ? CKM_DES2_KEY_GEN : CKM_DES3_KEY_GEN;
 479    case CKM_DES3_KEY_GEN:
 480	return CKM_DES3_KEY_GEN;
 481    case CKM_DES2_KEY_GEN:
 482	return CKM_DES2_KEY_GEN;
 483    case CKM_CDMF_ECB:
 484    case CKM_CDMF_CBC:
 485    case CKM_CDMF_MAC:
 486    case CKM_CDMF_MAC_GENERAL:
 487    case CKM_CDMF_CBC_PAD:
 488    case CKM_CDMF_KEY_GEN:
 489	return CKM_CDMF_KEY_GEN;
 490    case CKM_RC2_ECB:
 491    case CKM_RC2_CBC:
 492    case CKM_RC2_MAC:
 493    case CKM_RC2_MAC_GENERAL:
 494    case CKM_RC2_CBC_PAD:
 495    case CKM_RC2_KEY_GEN:
 496	return CKM_RC2_KEY_GEN;
 497    case CKM_RC4:
 498    case CKM_RC4_KEY_GEN:
 499	return CKM_RC4_KEY_GEN;
 500    case CKM_RC5_ECB:
 501    case CKM_RC5_CBC:
 502    case CKM_RC5_MAC:
 503    case CKM_RC5_MAC_GENERAL:
 504    case CKM_RC5_CBC_PAD:
 505    case CKM_RC5_KEY_GEN:
 506	return CKM_RC5_KEY_GEN;
 507    case CKM_SKIPJACK_CBC64:
 508    case CKM_SKIPJACK_ECB64:
 509    case CKM_SKIPJACK_OFB64:
 510    case CKM_SKIPJACK_CFB64:
 511    case CKM_SKIPJACK_CFB32:
 512    case CKM_SKIPJACK_CFB16:
 513    case CKM_SKIPJACK_CFB8:
 514    case CKM_SKIPJACK_WRAP:
 515    case CKM_SKIPJACK_KEY_GEN:
 516	return CKM_SKIPJACK_KEY_GEN;
 517    case CKM_BATON_ECB128:
 518    case CKM_BATON_ECB96:
 519    case CKM_BATON_CBC128:
 520    case CKM_BATON_COUNTER:
 521    case CKM_BATON_SHUFFLE:
 522    case CKM_BATON_WRAP:
 523    case CKM_BATON_KEY_GEN:
 524	return CKM_BATON_KEY_GEN;
 525    case CKM_JUNIPER_ECB128:
 526    case CKM_JUNIPER_CBC128:
 527    case CKM_JUNIPER_COUNTER:
 528    case CKM_JUNIPER_SHUFFLE:
 529    case CKM_JUNIPER_WRAP:
 530    case CKM_JUNIPER_KEY_GEN:
 531	return CKM_JUNIPER_KEY_GEN;
 532    case CKM_IDEA_CBC:
 533    case CKM_IDEA_ECB:
 534    case CKM_IDEA_MAC:
 535    case CKM_IDEA_MAC_GENERAL:
 536    case CKM_IDEA_CBC_PAD:
 537    case CKM_IDEA_KEY_GEN:
 538	return CKM_IDEA_KEY_GEN;
 539    case CKM_CAST_ECB:
 540    case CKM_CAST_CBC:
 541    case CKM_CAST_MAC:
 542    case CKM_CAST_MAC_GENERAL:
 543    case CKM_CAST_CBC_PAD:
 544    case CKM_CAST_KEY_GEN:
 545	return CKM_CAST_KEY_GEN;
 546    case CKM_CAST3_ECB:
 547    case CKM_CAST3_CBC:
 548    case CKM_CAST3_MAC:
 549    case CKM_CAST3_MAC_GENERAL:
 550    case CKM_CAST3_CBC_PAD:
 551    case CKM_CAST3_KEY_GEN:
 552	return CKM_CAST3_KEY_GEN;
 553    case CKM_CAST5_ECB:
 554    case CKM_CAST5_CBC:
 555    case CKM_CAST5_MAC:
 556    case CKM_CAST5_MAC_GENERAL:
 557    case CKM_CAST5_CBC_PAD:
 558    case CKM_CAST5_KEY_GEN:
 559	return CKM_CAST5_KEY_GEN;
 560    case CKM_RSA_PKCS:
 561    case CKM_RSA_9796:
 562    case CKM_RSA_X_509:
 563    case CKM_MD2_RSA_PKCS:
 564    case CKM_MD5_RSA_PKCS:
 565    case CKM_SHA1_RSA_PKCS:
 566    case CKM_SHA224_RSA_PKCS:
 567    case CKM_SHA256_RSA_PKCS:
 568    case CKM_SHA384_RSA_PKCS:
 569    case CKM_SHA512_RSA_PKCS:
 570    case CKM_KEY_WRAP_SET_OAEP:
 571    case CKM_RSA_PKCS_KEY_PAIR_GEN:
 572	return CKM_RSA_PKCS_KEY_PAIR_GEN;
 573    case CKM_RSA_X9_31_KEY_PAIR_GEN:
 574	return CKM_RSA_X9_31_KEY_PAIR_GEN;
 575    case CKM_DSA:
 576    case CKM_DSA_SHA1:
 577    case CKM_DSA_KEY_PAIR_GEN:
 578	return CKM_DSA_KEY_PAIR_GEN;
 579    case CKM_DH_PKCS_DERIVE:
 580    case CKM_DH_PKCS_KEY_PAIR_GEN:
 581	return CKM_DH_PKCS_KEY_PAIR_GEN;
 582    case CKM_KEA_KEY_DERIVE:
 583    case CKM_KEA_KEY_PAIR_GEN:
 584	return CKM_KEA_KEY_PAIR_GEN;
 585    case CKM_ECDSA:
 586    case CKM_ECDSA_SHA1:
 587    case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */
 588    case CKM_ECDH1_DERIVE:
 589        return CKM_EC_KEY_PAIR_GEN; 
 590    case CKM_SSL3_PRE_MASTER_KEY_GEN:
 591    case CKM_SSL3_MASTER_KEY_DERIVE:
 592    case CKM_SSL3_KEY_AND_MAC_DERIVE:
 593    case CKM_SSL3_SHA1_MAC:
 594    case CKM_SSL3_MD5_MAC:
 595    case CKM_TLS_MASTER_KEY_DERIVE:
 596    case CKM_TLS_KEY_AND_MAC_DERIVE:
 597	return CKM_SSL3_PRE_MASTER_KEY_GEN;
 598    case CKM_SHA_1_HMAC:
 599    case CKM_SHA_1_HMAC_GENERAL:
 600    case CKM_SHA224_HMAC:
 601    case CKM_SHA224_HMAC_GENERAL:
 602    case CKM_SHA256_HMAC:
 603    case CKM_SHA256_HMAC_GENERAL:
 604    case CKM_SHA384_HMAC:
 605    case CKM_SHA384_HMAC_GENERAL:
 606    case CKM_SHA512_HMAC:
 607    case CKM_SHA512_HMAC_GENERAL:
 608    case CKM_MD2_HMAC:
 609    case CKM_MD2_HMAC_GENERAL:
 610    case CKM_MD5_HMAC:
 611    case CKM_MD5_HMAC_GENERAL:
 612    case CKM_TLS_PRF_GENERAL:
 613    case CKM_GENERIC_SECRET_KEY_GEN:
 614	return CKM_GENERIC_SECRET_KEY_GEN;
 615    case CKM_PBE_MD2_DES_CBC:
 616    case CKM_PBE_MD5_DES_CBC:
 617    case CKM_PBA_SHA1_WITH_SHA1_HMAC:
 618    case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
 619    case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
 620    case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
 621    case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
 622    case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
 623    case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
 624    case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
 625    case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
 626    case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
 627    case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
 628    case CKM_PBE_SHA1_RC2_40_CBC:
 629    case CKM_PBE_SHA1_RC2_128_CBC:
 630    case CKM_PBE_SHA1_RC4_40:
 631    case CKM_PBE_SHA1_RC4_128:
 632    case CKM_PBE_SHA1_DES3_EDE_CBC:
 633    case CKM_PBE_SHA1_DES2_EDE_CBC:
 634    case CKM_PKCS5_PBKD2:
 635    	return type;
 636    default:
 637	return pk11_lookup(type)->keyGen;
 638    }
 639}
 640
 641/*
 642 * get the mechanism block size
 643 */
 644int
 645PK11_GetBlockSize(CK_MECHANISM_TYPE type,SECItem *params)
 646{
 647    CK_RC5_PARAMS *rc5_params;
 648    CK_RC5_CBC_PARAMS *rc5_cbc_params;
 649    switch (type) {
 650    case CKM_RC5_ECB:
 651	if ((params) && (params->data)) {
 652	    rc5_params = (CK_RC5_PARAMS *) params->data;
 653	    return (rc5_params->ulWordsize)*2;
 654	}
 655	return 8;
 656    case CKM_RC5_CBC:
 657    case CKM_RC5_CBC_PAD:
 658	if ((params) && (params->data)) {
 659	    rc5_cbc_params = (CK_RC5_CBC_PARAMS *) params->data;
 660	    return (rc5_cbc_params->ulWordsize)*2;
 661	}
 662	return 8;
 663    case CKM_DES_ECB:
 664    case CKM_DES3_ECB:
 665    case CKM_RC2_ECB:
 666    case CKM_IDEA_ECB:
 667    case CKM_CAST_ECB:
 668    case CKM_CAST3_ECB:
 669    case CKM_CAST5_ECB:
 670    case CKM_RC2_CBC:
 671    case CKM_SKIPJACK_CBC64:
 672    case CKM_SKIPJACK_ECB64:
 673    case CKM_SKIPJACK_OFB64:
 674    case CKM_SKIPJACK_CFB64:
 675    case CKM_DES_CBC:
 676    case CKM_DES3_CBC:
 677    case CKM_IDEA_CBC:
 678    case CKM_CAST_CBC:
 679    case CKM_CAST3_CBC:
 680    case CKM_CAST5_CBC:
 681    case CKM_DES_CBC_PAD:
 682    case CKM_DES3_CBC_PAD:
 683    case CKM_RC2_CBC_PAD:
 684    case CKM_IDEA_CBC_PAD:
 685    case CKM_CAST_CBC_PAD:
 686    case CKM_CAST3_CBC_PAD:
 687    case CKM_CAST5_CBC_PAD:
 688    case CKM_PBE_MD2_DES_CBC:
 689    case CKM_PBE_MD5_DES_CBC:
 690    case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
 691    case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
 692    case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
 693    case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
 694    case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
 695    case CKM_PBE_SHA1_RC2_40_CBC:
 696    case CKM_PBE_SHA1_RC2_128_CBC:
 697    case CKM_PBE_SHA1_DES3_EDE_CBC:
 698    case CKM_PBE_SHA1_DES2_EDE_CBC:
 699	return 8;
 700    case CKM_SKIPJACK_CFB32:
 701    case CKM_SKIPJACK_CFB16:
 702    case CKM_SKIPJACK_CFB8:
 703	return 4;
 704    case CKM_SEED_ECB:
 705    case CKM_SEED_CBC:
 706    case CKM_SEED_CBC_PAD:
 707    case CKM_CAMELLIA_ECB:
 708    case CKM_CAMELLIA_CBC:
 709    case CKM_CAMELLIA_CBC_PAD:
 710    case CKM_AES_ECB:
 711    case CKM_AES_CBC:
 712    case CKM_AES_CBC_PAD:
 713    case CKM_BATON_ECB128:
 714    case CKM_BATON_CBC128:
 715    case CKM_BATON_COUNTER:
 716    case CKM_BATON_SHUFFLE:
 717    case CKM_JUNIPER_ECB128:
 718    case CKM_JUNIPER_CBC128:
 719    case CKM_JUNIPER_COUNTER:
 720    case CKM_JUNIPER_SHUFFLE:
 721	return 16;
 722    case CKM_BATON_ECB96:
 723	return 12;
 724    case CKM_RC4:
 725    case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
 726    case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
 727    case CKM_PBE_SHA1_RC4_40:
 728    case CKM_PBE_SHA1_RC4_128:
 729	return 0;
 730    case CKM_RSA_PKCS:
 731    case CKM_RSA_9796:
 732    case CKM_RSA_X_509:
 733	/*actually it's the modulus length of the key!*/
 734	return -1;	/* failure */
 735    default:
 736	return pk11_lookup(type)->blockSize;
 737    }
 738}
 739
 740/*
 741 * get the iv length
 742 */
 743int
 744PK11_GetIVLength(CK_MECHANISM_TYPE type)
 745{
 746    switch (type) {
 747    case CKM_SEED_ECB:
 748    case CKM_CAMELLIA_ECB:
 749    case CKM_AES_ECB:
 750    case CKM_DES_ECB:
 751    case CKM_DES3_ECB:
 752    case CKM_RC2_ECB:
 753    case CKM_IDEA_ECB:
 754    case CKM_SKIPJACK_WRAP:
 755    case CKM_BATON_WRAP:
 756    case CKM_RC5_ECB:
 757    case CKM_CAST_ECB:
 758    case CKM_CAST3_ECB:
 759    case CKM_CAST5_ECB:
 760	return 0;
 761    case CKM_RC2_CBC:
 762    case CKM_DES_CBC:
 763    case CKM_DES3_CBC:
 764    case CKM_IDEA_CBC:
 765    case CKM_PBE_MD2_DES_CBC:
 766    case CKM_PBE_MD5_DES_CBC:
 767    case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
 768    case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
 769    case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
 770    case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
 771    case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
 772    case CKM_PBE_SHA1_RC2_40_CBC:
 773    case CKM_PBE_SHA1_RC2_128_CBC:
 774    case CKM_PBE_SHA1_DES3_EDE_CBC:
 775    case CKM_PBE_SHA1_DES2_EDE_CBC:
 776    case CKM_RC5_CBC:
 777    case CKM_CAST_CBC:
 778    case CKM_CAST3_CBC:
 779    case CKM_CAST5_CBC:
 780    case CKM_RC2_CBC_PAD:
 781    case CKM_DES_CBC_PAD:
 782    case CKM_DES3_CBC_PAD:
 783    case CKM_IDEA_CBC_PAD:
 784    case CKM_RC5_CBC_PAD:
 785    case CKM_CAST_CBC_PAD:
 786    case CKM_CAST3_CBC_PAD:
 787    case CKM_CAST5_CBC_PAD:
 788	return 8;
 789    case CKM_SEED_CBC:
 790    case CKM_SEED_CBC_PAD:
 791    case CKM_CAMELLIA_CBC:
 792    case CKM_CAMELLIA_CBC_PAD:
 793    case CKM_AES_CBC:
 794    case CKM_AES_CBC_PAD:
 795	return 16;
 796    case CKM_SKIPJACK_CBC64:
 797    case CKM_SKIPJACK_ECB64:
 798    case CKM_SKIPJACK_OFB64:
 799    case CKM_SKIPJACK_CFB64:
 800    case CKM_SKIPJACK_CFB32:
 801    case CKM_SKIPJACK_CFB16:
 802    case CKM_SKIPJACK_CFB8:
 803    case CKM_BATON_ECB128:
 804    case CKM_BATON_ECB96:
 805    case CKM_BATON_CBC128:
 806    case CKM_BATON_COUNTER:
 807    case CKM_BATON_SHUFFLE:
 808    case CKM_JUNIPER_ECB128:
 809    case CKM_JUNIPER_CBC128:
 810    case CKM_JUNIPER_COUNTER:
 811    case CKM_JUNIPER_SHUFFLE:
 812	return 24;
 813    case CKM_RC4:
 814    case CKM_RSA_PKCS:
 815    case CKM_RSA_9796:
 816    case CKM_RSA_X_509:
 817    case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
 818    case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
 819    case CKM_PBE_SHA1_RC4_40:
 820    case CKM_PBE_SHA1_RC4_128:
 821	return 0;
 822    default:
 823	return pk11_lookup(type)->iv;
 824    }
 825}
 826
 827
 828/* These next two utilities are here to help facilitate future
 829 * Dynamic Encrypt/Decrypt symetric key mechanisms, and to allow functions
 830 * like SSL and S-MIME to automatically add them.
 831 */
 832SECItem *
 833pk11_ParamFromIVWithLen(CK_MECHANISM_TYPE type, SECItem *iv, int keyLen)
 834{
 835    CK_RC2_CBC_PARAMS *rc2_params = NULL;
 836    CK_RC2_PARAMS *rc2_ecb_params = NULL;
 837    CK_RC5_PARAMS *rc5_params = NULL;
 838    CK_RC5_CBC_PARAMS *rc5_cbc_params = NULL;
 839    SECItem *param;
 840
 841    param = (SECItem *)PORT_Alloc(sizeof(SECItem));
 842    if (param == NULL) return NULL;
 843    param->data = NULL;
 844    param->len = 0;
 845    param->type = 0;
 846    switch (type) {
 847    case CKM_SEED_ECB:
 848    case CKM_CAMELLIA_ECB:
 849    case CKM_AES_ECB:
 850    case CKM_DES_ECB:
 851    case CKM_DES3_ECB:
 852    case CKM_RSA_PKCS:
 853    case CKM_RSA_X_509:
 854    case CKM_RSA_9796:
 855    case CKM_IDEA_ECB:
 856    case CKM_CDMF_ECB:
 857    case CKM_CAST_ECB:
 858    case CKM_CAST3_ECB:
 859    case CKM_CAST5_ECB:
 860    case CKM_RC4:
 861	break;
 862    case CKM_RC2_ECB:
 863	rc2_ecb_params = (CK_RC2_PARAMS *)PORT_Alloc(sizeof(CK_RC2_PARAMS));
 864	if (rc2_ecb_params == NULL) break;
 865	/*  Maybe we should pass the key size in too to get this value? */
 866	*rc2_ecb_params = keyLen ? keyLen*8 : 128;
 867	param->data = (unsigned char *) rc2_ecb_params;
 868	param->len = sizeof(CK_RC2_PARAMS);
 869	break;
 870    case CKM_RC2_CBC:
 871    case CKM_RC2_CBC_PAD:
 872	rc2_params = (CK_RC2_CBC_PARAMS *)PORT_Alloc(sizeof(CK_RC2_CBC_PARAMS));
 873	if (rc2_params == NULL) break;
 874	/* Maybe we should pass the key size in too to get this value? */
 875	rc2_params->ulEffectiveBits = keyLen ? keyLen*8 : 128;
 876	if (iv && iv->data)
 877	    PORT_Memcpy(rc2_params->iv,iv->data,sizeof(rc2_params->iv));
 878	param->data = (unsigned char *) rc2_params;
 879	param->len = sizeof(CK_RC2_CBC_PARAMS);
 880	break;
 881    case CKM_RC5_CBC:
 882    case CKM_RC5_CBC_PAD:
 883	rc5_cbc_params = (CK_RC5_CBC_PARAMS *)
 884		PORT_Alloc(sizeof(CK_RC5_CBC_PARAMS) + ((iv) ? iv->len : 0));
 885	if (rc5_cbc_params == NULL) break;
 886	if (iv && iv->data && iv->len) {
 887	    rc5_cbc_params->pIv = ((CK_BYTE_PTR) rc5_cbc_params) 
 888						+ sizeof(CK_RC5_CBC_PARAMS);
 889	    PORT_Memcpy(rc5_cbc_params->pIv,iv->data,iv->len);
 890	    rc5_cbc_params->ulIvLen = iv->len;
 891	    rc5_cbc_params->ulWordsize = iv->len/2;
 892	} else {
 893	    rc5_cbc_params->ulWordsize = 4;
 894	    rc5_cbc_params->pIv = NULL;
 895	    rc5_cbc_params->ulIvLen = 0;
 896	}
 897	rc5_cbc_params->ulRounds = 16;
 898	param->data = (unsigned char *) rc5_cbc_params;
 899	param->len = sizeof(CK_RC5_CBC_PARAMS);
 900	break;
 901    case CKM_RC5_ECB:
 902	rc5_params = (CK_RC5_PARAMS *)PORT_Alloc(sizeof(CK_RC5_PARAMS));
 903	if (rc5_params == NULL) break;
 904	if (iv && iv->data && iv->len) {
 905	    rc5_params->ulWordsize = iv->len/2;
 906	} else {
 907	    rc5_params->ulWordsize = 4;
 908	}
 909	rc5_params->ulRounds = 16;
 910	param->data = (unsigned char *) rc5_params;
 911	param->len = sizeof(CK_RC5_PARAMS);
 912	break;
 913
 914    case CKM_SEED_CBC:
 915    case CKM_CAMELLIA_CBC:
 916    case CKM_AES_CBC:
 917    case CKM_DES_CBC:
 918    case CKM_DES3_CBC:
 919    case CKM_IDEA_CBC:
 920    case CKM_CDMF_CBC:
 921    case CKM_CAST_CBC:
 922    case CKM_CAST3_CBC:
 923    case CKM_CAST5_CBC:
 924    case CKM_CAMELLIA_CBC_PAD:
 925    case CKM_AES_CBC_PAD:
 926    case CKM_DES_CBC_PAD:
 927    case CKM_DES3_CBC_PAD:
 928    case CKM_IDEA_CBC_PAD:
 929    case CKM_CDMF_CBC_PAD:
 930    case CKM_CAST_CBC_PAD:
 931    case CKM_CAST3_CBC_PAD:
 932    case CKM_CAST5_CBC_PAD:
 933    case CKM_SKIPJACK_CBC64:
 934    case CKM_SKIPJACK_ECB64:
 935    case CKM_SKIPJACK_OFB64:
 936    case CKM_SKIPJACK_CFB64:
 937    case CKM_SKIPJACK_CFB32:
 938    case CKM_SKIPJACK_CFB16:
 939    case CKM_SKIPJACK_CFB8:
 940    case CKM_BATON_ECB128:
 941    case CKM_BATON_ECB96:
 942    case CKM_BATON_CBC128:
 943    case CKM_BATON_COUNTER:
 944    case CKM_BATON_SHUFFLE:
 945    case CKM_JUNIPER_ECB128:
 946    case CKM_JUNIPER_CBC128:
 947    case CKM_JUNIPER_COUNTER:
 948    case CKM_JUNIPER_SHUFFLE:
 949	if ((iv == NULL) || (iv->data == NULL)) break;
 950	param->data = (unsigned char*)PORT_Alloc(iv->len);
 951	if (param->data != NULL) {
 952	    PORT_Memcpy(param->data,iv->data,iv->len);
 953	    param->len = iv->len;
 954	}
 955	break;
 956     /* unknown mechanism, pass IV in if it's there */
 957     default:
 958	if (pk11_lookup(type)->iv == 0) {
 959	    break;
 960	}
 961	if ((iv == NULL) || (iv->data == NULL)) {
 962	    break;
 963	}
 964	param->data = (unsigned char*)PORT_Alloc(iv->len);
 965	if (param->data != NULL) {
 966	    PORT_Memcpy(param->data,iv->data,iv->len);
 967	    param->len = iv->len;
 968	}
 969	break;
 970     }
 971     return param;
 972}
 973
 974/* These next two utilities are here to help facilitate future
 975 * Dynamic Encrypt/Decrypt symetric key mechanisms, and to allow functions
 976 * like SSL and S-MIME to automatically add them.
 977 */
 978SECItem *
 979PK11_ParamFromIV(CK_MECHANISM_TYPE type,SECItem *iv)
 980{
 981    return pk11_ParamFromIVWithLen(type, iv, 0);
 982}
 983
 984unsigned char *
 985PK11_IVFromParam(CK_MECHANISM_TYPE type,SECItem *param,int *len)
 986{
 987    CK_RC2_CBC_PARAMS *rc2_params;
 988    CK_RC5_CBC_PARAMS *rc5_cbc_params;
 989
 990    *len = 0;
 991    switch (type) {
 992    case CKM_SEED_ECB:
 993    case CKM_CAMELLIA_ECB:
 994    case CKM_AES_ECB:
 995    case CKM_DES_ECB:
 996    case CKM_DES3_ECB:
 997    case CKM_RSA_PKCS:
 998    case CKM_RSA_X_509:
 999    case CKM_RSA_9796:
1000    case CKM_IDEA_ECB:
1001    case CKM_CDMF_ECB:
1002    case CKM_CAST_ECB:
1003    case CKM_CAST3_ECB:
1004    case CKM_CAST5_ECB:
1005    case CKM_RC4:
1006	return NULL;
1007    case CKM_RC2_ECB:
1008	return NULL;
1009    case CKM_RC2_CBC:
1010    case CKM_RC2_CBC_PAD:
1011	rc2_params = (CK_RC2_CBC_PARAMS *)param->data;
1012        *len = sizeof(rc2_params->iv);
1013	return &rc2_params->iv[0];
1014    case CKM_RC5_CBC:
1015    case CKM_RC5_CBC_PAD:
1016	rc5_cbc_params = (CK_RC5_CBC_PARAMS *) param->data;
1017	*len = rc5_cbc_params->ulIvLen;
1018	return rc5_cbc_params->pIv;
1019    case CKM_SEED_CBC:
1020    case CKM_CAMELLIA_CBC:
1021    case CKM_AES_CBC:
1022    case CKM_DES_CBC:
1023    case CKM_DES3_CBC:
1024    case CKM_IDEA_CBC:
1025    case CKM_CDMF_CBC:
1026    case CKM_CAST_CBC:
1027    case CKM_CAST3_CBC:
1028    case CKM_CAST5_CBC:
1029    case CKM_CAMELLIA_CBC_PAD:
1030    case CKM_AES_CBC_PAD:
1031    case CKM_DES_CBC_PAD:
1032    case CKM_DES3_CBC_PAD:
1033    case CKM_IDEA_CBC_PAD:
1034    case CKM_CDMF_CBC_PAD:
1035    case CKM_CAST_CBC_PAD:
1036    case CKM_CAST3_CBC_PAD:
1037    case CKM_CAST5_CBC_PAD:
1038    case CKM_SKIPJACK_CBC64:
1039    case CKM_SKIPJACK_ECB64:
1040    case CKM_SKIPJACK_OFB64:
1041    case CKM_SKIPJACK_CFB64:
1042    case CKM_SKIPJACK_CFB32:
1043    case CKM_SKIPJACK_CFB16:
1044    case CKM_SKIPJACK_CFB8:
1045    case CKM_BATON_ECB128:
1046    case CKM_BATON_ECB96:
1047    case CKM_BATON_CBC128:
1048    case CKM_BATON_COUNTER:
1049    case CKM_BATON_SHUFFLE:
1050    case CKM_JUNIPER_ECB128:
1051    case CKM_JUNIPER_CBC128:
1052    case CKM_JUNIPER_COUNTER:
1053    case CKM_JUNIPER_SHUFFLE:
1054	break;
1055     /* unknown mechanism, pass IV in if it's there */
1056     default:
1057	break;
1058     }
1059     if (param->data) {
1060	*len = param->len;
1061     }
1062     return param->data;
1063}
1064
1065typedef struct sec_rc5cbcParameterStr {
1066    SECItem version;
1067    SECItem rounds;
1068    SECItem blockSizeInBits;
1069    SECItem iv;
1070} sec_rc5cbcParameter;
1071
1072static const SEC_ASN1Template sec_rc5ecb_parameter_template[] = {
1073    { SEC_ASN1_SEQUENCE,
1074          0, NULL, sizeof(sec_rc5cbcParameter) },
1075    { SEC_ASN1_INTEGER,
1076          offsetof(sec_rc5cbcParameter,version) },
1077    { SEC_ASN1_INTEGER,
1078          offsetof(sec_rc5cbcParameter,rounds) },
1079    { SEC_ASN1_INTEGER,
1080          offsetof(sec_rc5cbcParameter,blockSizeInBits) },
1081    { 0 }
1082};
1083
1084static const SEC_ASN1Template sec_rc5cbc_parameter_template[] = {
1085    { SEC_ASN1_SEQUENCE,
1086          0, NULL, sizeof(sec_rc5cbcParameter) },
1087    { SEC_ASN1_INTEGER,
1088          offsetof(sec_rc5cbcParameter,version) },
1089    { SEC_ASN1_INTEGER,
1090          offsetof(sec_rc5cbcParameter,rounds) },
1091    { SEC_ASN1_INTEGER,
1092          offsetof(sec_rc5cbcParameter,blockSizeInBits) },
1093    { SEC_ASN1_OCTET_STRING,
1094          offsetof(sec_rc5cbcParameter,iv) },
1095    { 0 }
1096};
1097
1098typedef struct sec_rc2cbcParameterStr {
1099    SECItem rc2ParameterVersion;
1100    SECItem iv;
1101} sec_rc2cbcParameter;
1102
1103static const SEC_ASN1Template sec_rc2cbc_parameter_template[] = {
1104    { SEC_ASN1_SEQUENCE,
1105          0, NULL, sizeof(sec_rc2cbcParameter) },
1106    { SEC_ASN1_INTEGER,
1107          offsetof(sec_rc2cbcParameter,rc2ParameterVersion) },
1108    { SEC_ASN1_OCTET_STRING,
1109          offsetof(sec_rc2cbcParameter,iv) },
1110    { 0 }
1111};
1112
1113static const SEC_ASN1Template sec_rc2ecb_parameter_template[] = {
1114    { SEC_ASN1_SEQUENCE,
1115          0, NULL, sizeof(sec_rc2cbcParameter) },
1116    { SEC_ASN1_INTEGER,
1117          offsetof(sec_rc2cbcParameter,rc2ParameterVersion) },
1118    { 0 }
1119};
1120
1121/* S/MIME picked id values to represent differnt keysizes */
1122/* I do have a formula, but it ain't pretty, and it only works because you
1123 * can always match three points to a parabola:) */
1124static unsigned char  rc2_map(SECItem *version)
1125{
1126    long x;
1127
1128    x = DER_GetInteger(version);
1129    
1130    switch (x) {
1131        case 58: return 128;
1132        case 120: return 64;
1133        case 160: return 40;
1134    }
1135    return 128; 
1136}
1137
1138static unsigned long  rc2_unmap(unsigned long x)
1139{
1140    switch (x) {
1141        case 128: return 58;
1142        case 64: return 120;
1143        case 40: return 160;
1144    }
1145    return 58; 
1146}
1147
1148
1149
1150/* Generate a mechaism param from a type, and iv. */
1151SECItem *
1152PK11_ParamFromAlgid(SECAlgorithmID *algid)
1153{
1154    CK_RC2_CBC_PARAMS * rc2_cbc_params = NULL;
1155    CK_RC2_PARAMS *     rc2_ecb_params = NULL;
1156    CK_RC5_CBC_PARAMS * rc5_cbc_params = NULL;
1157    CK_RC5_PARAMS *     rc5_ecb_params = NULL;
1158    PRArenaPool *       arena          = NULL;
1159    SECItem *           mech           = NULL;
1160    SECOidTag           algtag;
1161    SECStatus           rv;
1162    CK_MECHANISM_TYPE   type;
1163    /* initialize these to prevent UMRs in the ASN1 decoder. */
1164    SECItem             iv  =   {siBuffer, NULL, 0};
1165    sec_rc2cbcParameter rc2 = { {siBuffer, NULL, 0}, {siBuffer, NULL, 0} };
1166    sec_rc5cbcParameter rc5 = { {siBuffer, NULL, 0}, {siBuffer, NULL, 0},
1167                                {siBuffer, NULL, 0}, {siBuffer, NULL, 0} };
1168
1169    algtag = SECOID_GetAlgorithmTag(algid);
1170    type = PK11_AlgtagToMechanism(algtag);
1171
1172    mech = PORT_New(SECItem);
1173    if (mech == NULL) {
1174    	return NULL;
1175    }
1176    mech->type = siBuffer;
1177    mech->data = NULL;
1178    mech->len  = 0;
1179
1180    arena = PORT_NewArena(1024);
1181    if (!arena) {
1182    	goto loser;
1183    }
1184
1185    /* handle the complicated cases */
1186    switch (type) {
1187    case CKM_RC2_ECB:
1188        rv = SEC_ASN1DecodeItem(arena, &rc2 ,sec_rc2ecb_parameter_template,
1189							&(algid->parameters));
1190	if (rv != SECSuccess) { 
1191	    goto loser;
1192	}
1193	rc2_ecb_params = PORT_New(CK_RC2_PARAMS);
1194	if (rc2_ecb_params == NULL) {
1195	    goto loser;
1196	}
1197	*rc2_ecb_params = rc2_map(&rc2.rc2ParameterVersion);
1198	mech->data = (unsigned char *) rc2_ecb_params;
1199	mech->len  = sizeof *rc2_ecb_params;
1200	break;
1201    case CKM_RC2_CBC:
1202    case CKM_RC2_CBC_PAD:
1203        rv = SEC_ASN1DecodeItem(arena, &rc2 ,sec_rc2cbc_parameter_template,
1204							&(algid->parameters));
1205	if (rv != SECSuccess) { 
1206	    goto loser;
1207	}
1208	rc2_cbc_params = PORT_New(CK_RC2_CBC_PARAMS);
1209	if (rc2_cbc_params == NULL) {
1210	    goto loser;
1211	}
1212	mech->data = (unsigned char *) rc2_cbc_params;
1213	mech->len  = sizeof *rc2_cbc_params;
1214	rc2_cbc_params->ulEffectiveBits = rc2_map(&rc2.rc2ParameterVersion);
1215	if (rc2.iv.len != sizeof rc2_cbc_params->iv) {
1216	    PORT_SetError(SEC_ERROR_INPUT_LEN);
1217	    goto loser;
1218	}
1219	PORT_Memcpy(rc2_cbc_params->iv, rc2.iv.data, rc2.iv.len);
1220	break;
1221    case CKM_RC5_ECB:
1222        rv = SEC_ASN1DecodeItem(arena, &rc5 ,sec_rc5ecb_parameter_template,
1223							&(algid->parameters));
1224	if (rv != SECSuccess) { 
1225	    goto loser;
1226	}
1227	rc5_ecb_params = PORT_New(CK_RC5_PARAMS);
1228	if (rc5_ecb_params == NULL) {
1229	    goto loser;
1230	}
1231	rc5_ecb_params->ulRounds   = DER_GetInteger(&rc5.rounds);
1232	rc5_ecb_params->ulWordsize = DER_GetInteger(&rc5.blockSizeInBits)/8;
1233	mech->data = (unsigned char *) rc5_ecb_params;
1234	mech->len = sizeof *rc5_ecb_params;
1235	break;
1236    case CKM_RC5_CBC:
1237    case CKM_RC5_CBC_PAD:
1238        rv = SEC_ASN1DecodeItem(arena, &rc5 ,sec_rc5cbc_parameter_template,
1239							&(algid->parameters));
1240	if (rv != SECSuccess) { 
1241	    goto loser;
1242	}
1243	rc5_cbc_params = (CK_RC5_CBC_PARAMS *)
1244		PORT_Alloc(sizeof(CK_RC5_CBC_PARAMS) + rc5.iv.len);
1245	if (rc5_cbc_params == NULL) {
1246	    goto loser;
1247	}
1248	mech->data = (unsigned char *) rc5_cbc_params;
1249	mech->len = sizeof *rc5_cbc_params;
1250	rc5_cbc_params->ulRounds   = DER_GetInteger(&rc5.rounds);
1251	rc5_cbc_params->ulWordsize = DER_GetInteger(&rc5.blockSizeInBits)/8;
1252        rc5_cbc_params->pIv        = ((CK_BYTE_PTR)rc5_cbc_params)
1253						+ sizeof(CK_RC5_CBC_PARAMS);
1254        rc5_cbc_params->ulIvLen    = rc5.iv.len;
1255	PORT_Memcpy(rc5_cbc_params->pIv, rc5.iv.data, rc5.iv.len);
1256	break;
1257    case CKM_PBE_MD2_DES_CBC:
1258    case CKM_PBE_MD5_DES_CBC:
1259    case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
1260    case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
1261    case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
1262    case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
1263    case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
1264    case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
1265    case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
1266    case CKM_PBE_SHA1_DES2_EDE_CBC:
1267    case CKM_PBE_SHA1_DES3_EDE_CBC:
1268    case CKM_PBE_SHA1_RC2_40_CBC:
1269    case CKM_PBE_SHA1_RC2_128_CBC:
1270    case CKM_PBE_SHA1_RC4_40:
1271    case CKM_PBE_SHA1_RC4_128:
1272    case CKM_PKCS5_PBKD2:
1273	rv = pbe_PK11AlgidToParam(algid,mech);
1274	if (rv != SECSuccess) {
1275	    goto loser;
1276	}
1277	break;
1278    case CKM_RC4:
1279    case CKM_SEED_ECB:
1280    case CKM_CAMELLIA_ECB:
1281    case CKM_AES_ECB:
1282    case CKM_DES_ECB:
1283    case CKM_DES3_ECB:
1284    case CKM_IDEA_ECB:
1285    case CKM_CDMF_ECB:
1286    case CKM_CAST_ECB:
1287    case CKM_CAST3_ECB:
1288    case CKM_CAST5_ECB:
1289	break;
1290
1291    default:
1292	if (pk11_lookup(type)->iv == 0) {
1293	    break;
1294	}
1295	/* FALL THROUGH */
1296    case CKM_SEED_CBC:
1297    case CKM_CAMELLIA_CBC:
1298    case CKM_AES_CBC:
1299    case CKM_DES_CBC:
1300    case CKM_DES3_CBC:
1301    case CKM_IDEA_CBC:
1302    case CKM_CDMF_CBC:
1303    case CKM_CAST_CBC:
1304    case CKM_CAST3_CBC:
1305    case CKM_CAST5_CBC:
1306    case CKM_SEED_CBC_PAD:
1307    case CKM_CAMELLIA_CBC_PAD:
1308    case CKM_AES_CBC_PAD:
1309    case CKM_DES_CBC_PAD:
1310    case CKM_DES3_CBC_PAD:
1311    case CKM_IDEA_CBC_PAD:
1312    case CKM_CDMF_CBC_PAD:
1313    case CKM_CAST_CBC_PAD:
1314    case CKM_CAST3_CBC_PAD:
1315    case CKM_CAST5_CBC_PAD:
1316    case CKM_SKIPJACK_CBC64:
1317    case CKM_SKIPJACK_ECB64:
1318    case CKM_SKIPJACK_OFB64:
1319    case CKM_SKIPJACK_CFB64:
1320    case CKM_SKIPJACK_CFB32:
1321    case CKM_SKIPJACK_CFB16:
1322    case CKM_SKIPJACK_CFB8:
1323    case CKM_BATON_ECB128:
1324    case CKM_BATON_ECB96:
1325    case CKM_BATON_CBC128:
1326    case CKM_BATON_COUNTER:
1327    case CKM_BATON_SHUFFLE:
1328    case CKM_JUNIPER_ECB128:
1329    case CKM_JUNIPER_CBC128:
1330    case CKM_JUNIPER_COUNTER:
1331    case CKM_JUNIPER_SHUFFLE:
1332	/* simple cases are simply octet string encoded IVs */
1333	rv = SEC_ASN1DecodeItem(arena, &iv,
1334                                SEC_ASN1_GET(SEC_OctetStringTemplate),
1335                                &(algid->parameters));
1336	if (rv != SECSuccess || iv.data == NULL) {
1337	    goto loser;
1338	}
1339	/* XXX Should be some IV length sanity check here. */
1340	mech->data = (unsigned char*)PORT_Alloc(iv.len);
1341	if (mech->data == NULL) {
1342	    goto loser;
1343	}
1344	PORT_Memcpy(mech->data, iv.data, iv.len);
1345	mech->len = iv.len;
1346	break;
1347    }
1348    PORT_FreeArena(arena, PR_FALSE);
1349    return mech;
1350
1351loser:
1352    if (arena)
1353    	PORT_FreeArena(arena, PR_FALSE);
1354    SECITEM_FreeItem(mech,PR_TRUE);
1355    return NULL;
1356}
1357
1358/*
1359 * Generate an IV for the given mechanism 
1360 */
1361static SECStatus
1362pk11_GenIV(CK_MECHANISM_TYPE type, SECItem *iv) {
1363    int iv_size = PK11_GetIVLength(type);
1364    SECStatus rv;
1365
1366    iv->len = iv_size;
1367    if (iv_size == 0) { 
1368	iv->data = NULL;
1369	return SECSuccess;
1370    }
1371
1372    iv->data = (unsigned char *) PORT_Alloc(iv_size);
1373    if (iv->data == NULL) {
1374	iv->len = 0;
1375	return SECFailure;
1376    }
1377
1378    rv = PK11_GenerateRandom(iv->data,iv->len);
1379    if (rv != SECSuccess) {
1380	PORT_Free(iv->data);
1381	iv->data = NULL; iv->len = 0;
1382	return SECFailure;
1383    }
1384    return SECSuccess;
1385}
1386
1387
1388/*
1389 * create a new parameter block from the passed in MECHANISM and the
1390 * key. Use Netscape's S/MIME Rules for the New param block.
1391 */
1392SECItem *
1393pk11_GenerateNewParamWithKeyLen(CK_MECHANISM_TYPE type, int keyLen) 
1394{ 
1395    CK_RC2_CBC_PARAMS *rc2_params;
1396    CK_RC2_PARAMS *rc2_ecb_params;
1397    SECItem *mech;
1398    SECItem iv;
1399    SECStatus rv;
1400
1401
1402    mech = (SECItem *) PORT_Alloc(sizeof(SECItem));
1403    if (mech == NULL) return NULL;
1404
1405    rv = SECSuccess;
1406    mech->type = siBuffer;
1407    switch (type) {
1408    case CKM_RC4:
1409    case CKM_SEED_ECB:
1410    case CKM_CAMELLIA_ECB:
1411    case CKM_AES_ECB:
1412    case CKM_DES_ECB:
1413    case CKM_DES3_ECB:
1414    case CKM_IDEA_ECB:
1415    case CKM_CDMF_ECB:
1416    case CKM_CAST_ECB:
1417    case CKM_CAST3_ECB:
1418    case CKM_CAST5_ECB:
1419	mech->data = NULL;
1420	mech->len = 0;
1421	break;
1422    case CKM_RC2_ECB:
1423	rc2_ecb_params = (CK_RC2_PARAMS *)PORT_Alloc(sizeof(CK_RC2_PARAMS));
1424	if (rc2_ecb_params == NULL) {
1425	    rv = SECFailure;
1426	    break;
1427	}
1428	/* NOTE PK11_GetKeyLength can return -1 if the key isn't and RC2, RC5,
1429	 *   or RC4 key. Of course that wouldn't happen here doing RC2:).*/
1430	*rc2_ecb_params = keyLen ? keyLen*8 : 128;
1431	mech->data = (unsigned char *) rc2_ecb_params;
1432	mech->len = sizeof(CK_RC2_PARAMS);
1433	break;
1434    case CKM_RC2_CBC:
1435    case CKM_RC2_CBC_PAD:
1436	rv = pk11_GenIV(type,&iv);
1437	if (rv != SECSuccess) {
1438	    break;
1439	}
1440	rc2_params = (CK_RC2_CBC_PARAMS *)PORT_Alloc(sizeof(CK_RC2_CBC_PARAMS));
1441	if (rc2_params == NULL) {
1442	    PORT_Free(iv.data);
1443	    rv = SECFailure;
1444	    break;
1445	}
1446	/* NOTE PK11_GetKeyLength can return -1 if the key isn't and RC2, RC5,
1447	 *   or RC4 key. Of course that wouldn't happen here doing RC2:).*/
1448	rc2_params->ulEffectiveBits = keyLen ? keyLen*8 : 128;
1449	if (iv.data)
1450	    PORT_Memcpy(rc2_params->iv,iv.data,sizeof(rc2_params->iv));
1451	mech->data = (unsigned char *) rc2_params;
1452	mech->len = sizeof(CK_RC2_CBC_PARAMS);
1453	PORT_Free(iv.data);
1454	break;
1455    case CKM_RC5_ECB:
1456        PORT_Free(mech);
1457	return PK11_ParamFromIV(type,NULL);
1458    case CKM_RC5_CBC:
1459    case CKM_RC5_CBC_PAD:
1460	rv = pk11_GenIV(type,&iv);
1461	if (rv != SECSuccess) {
1462	    break;
1463	}
1464        PORT_Free(mech);
1465	return PK11_ParamFromIV(type,&iv);
1466    default:
1467	if (pk11_lookup(type)->iv == 0) {
1468	    mech->data = NULL;
1469	    mech->len = 0;
1470	    break;
1471	}
1472    case CKM_SEED_CBC:
1473    case CKM_CAMELLIA_CBC:
1474    case CKM_AES_CBC:
1475    case CKM_DES_CBC:
1476    case CKM_DES3_CBC:
1477    case CKM_IDEA_CBC:
1478    case CKM_CDMF_CBC:
1479    case CKM_CAST_CBC:
1480    case CKM_CAST3_CBC:
1481    case CKM_CAST5_CBC:
1482    case CKM_DES_CBC_PAD:
1483    case CKM_DES3_CBC_PAD:
1484    case CKM_IDEA_CBC_PAD:
1485    case CKM_CDMF_CBC_PAD:
1486    case CKM_CAST_CBC_PAD:
1487    case CKM_CAST3_CBC_PAD:
1488    case CKM_CAST5_CBC_PAD:
1489    case CKM_SKIPJACK_CBC64:
1490    case CKM_SKIPJACK_ECB64:
1491    case CKM_SKIPJACK_OFB64:
1492    case CKM_SKIPJACK_CFB64:
1493    case CKM_SKIPJACK_CFB32:
1494    case CKM_SKIPJACK_CFB16:
1495    case CKM_SKIPJACK_CFB8:
1496    case CKM_BATON_ECB128:
1497    case CKM_BATON_ECB96:
1498    case CKM_BATON_CBC128:
1499    case CKM_BATON_COUNTER:
1500    case CKM_BATON_SHUFFLE:
1501    case CKM_JUNIPER_ECB128:
1502    case CKM_JUNIPER_CBC128:
1503    case CKM_JUNIPER_COUNTER:
1504    case CKM_JUNIPER_SHUFFLE:
1505	rv = pk11_GenIV(type,&iv);
1506	if (rv != SECSuccess) {
1507	    break;
1508	}
1509	mech->data = (unsigned char*)PORT_Alloc(iv.len);
1510	if (mech->data == NULL) {
1511	    PORT_Free(iv.data);
1512	    rv = SECFailure;
1513	    break;
1514	}
1515	PORT_Memcpy(mech->data,iv.data,iv.len);
1516	mech->len = iv.len;
1517        PORT_Free(iv.data);
1518	break;
1519    }
1520    if (rv !=  SECSuccess) {
1521	SECITEM_FreeItem(mech,PR_TRUE);
1522	return NULL;
1523    }
1524    return mech;
1525
1526}
1527
1528SECItem *
1529PK11_GenerateNewParam(CK_MECHANISM_TYPE type, PK11SymKey *key) 
1530{ 
1531    int keyLen = key ? PK11_GetKeyLength(key) :  0;
1532
1533    return pk11_GenerateNewParamWithKeyLen(type, keyLen);
1534}
1535
1536#define RC5_V10 0x10
1537
1538/* turn a PKCS #11 parameter into a DER Encoded Algorithm ID */
1539SECStatus
1540PK11_ParamToAlgid(SECOidTag algTag, SECItem *param, 
1541				PRArenaPool *arena, SECAlgorithmID *algid) {
1542    CK_RC2_CBC_PARAMS *rc2_params;
1543    sec_rc2cbcParameter rc2;
1544    CK_RC5_CBC_PARAMS *rc5_params;
1545    sec_rc5cbcParameter rc5;
1546    CK_MECHANISM_TYPE type = PK11_AlgtagToMechanism(algTag);
1547    SECItem *newParams = NULL;
1548    SECStatus rv = SECFailure;
1549    unsigned long rc2version;
1550
1551    switch (type) {
1552    case CKM_RC4:
1553    case CKM_SEED_ECB:
1554    case CKM_CAMELLIA_ECB:
1555    case CKM_AES_ECB:
1556    case CKM_DES_ECB:
1557    case CKM_DES3_ECB:
1558    case CKM_IDEA_ECB:
1559    case CKM_CDMF_ECB:
1560    case CKM_CAST_ECB:
1561    case CKM_CAST3_ECB:
1562    case CKM_CAST5_ECB:
1563	newParams = NULL;
1564	rv = SECSuccess;
1565	break;
1566    case CKM_RC2_ECB:
1567	break;
1568    case CKM_RC2_CBC:
1569    case CKM_RC2_CBC_PAD:
1570	rc2_params = (CK_RC2_CBC_PARAMS *)param->data;
1571	rc2version = rc2_unmap(rc2_params->ulEffectiveBits);
1572	if (SEC_ASN1EncodeUnsignedInteger (NULL, &(rc2.rc2ParameterVersion),
1573					   rc2version) == NULL)
1574	    break;
1575	rc2.iv.data = rc2_params->iv;
1576	rc2.iv.len = sizeof(rc2_params->iv);
1577	newParams = SEC_ASN1EncodeItem (NULL, NULL, &rc2,
1578                                         sec_rc2cbc_parameter_template);
1579        PORT_Free(rc2.rc2ParameterVersion.data);
1580	if (newParams == NULL)
1581	    break;
1582	rv = SECSuccess;
1583	break;
1584
1585    case CKM_RC5_ECB: /* well not really... */
1586	break;
1587    case CKM_RC5_CBC:
1588    case CKM_RC5_CBC_PAD:
1589	rc5_params = (CK_RC5_CBC_PARAMS *)param->data;
1590	if (SEC_ASN1EncodeUnsignedInteger (NULL, &rc5.version, RC5_V10) == NULL)
1591	    break;
1592	if (SEC_ASN1EncodeUnsignedInteger (NULL, &rc5.blockSizeInBits, 
1593					rc5_params->ulWordsize*8) == NULL) {
1594            PORT_Free(rc5.version.data);
1595	    break;
1596	}
1597	if (SEC_ASN1EncodeUnsignedInteger (NULL, &rc5.rounds, 
1598					rc5_params->ulWordsize*8) == NULL) {
1599            PORT_Free(rc5.blockSizeInBits.data);
1600            PORT_Free(rc5.version.data);
1601	    break;
1602	}
1603	rc5.iv.data = rc5_params->pIv;
1604	rc5.iv.len = rc5_params->ulIvLen;
1605	newParams = SEC_ASN1EncodeItem (NULL, NULL, &rc5,
1606                                         sec_rc5cbc_parameter_template);
1607        PORT_Free(rc5.version.data);
1608        PORT_Free(rc5.blockSizeInBits.data);
1609        PORT_Free(rc5.rounds.data);
1610	if (newParams == NULL)
1611	    break;
1612	rv = SECSuccess;
1613	break;
1614    case CKM_PBE_MD2_DES_CBC:
1615    case CKM_PBE_MD5_DES_CBC:
1616    case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
1617    case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
1618    case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
1619    case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
1620    case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
1621    case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
1622    case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
1623    case CKM_PBE_SHA1_DES3_EDE_CBC:
1624    case CKM_PBE_SHA1_DES2_EDE_CBC:
1625    case CKM_PBE_SHA1_RC2_40_CBC:
1626    case CKM_PBE_SHA1_RC2_128_CBC:
1627    case CKM_PBE_SHA1_RC4_40:
1628    case CKM_PBE_SHA1_RC4_128:
1629	return PBE_PK11ParamToAlgid(algTag, param, arena, algid);
1630    default:
1631	if (pk11_lookup(type)->iv == 0) {
1632	    rv = SECSuccess;
1633	    newParams = NULL;
1634	    break;
1635	}
1636    case CKM_SEED_CBC:
1637    case CKM_CAMELLIA_CBC:
1638    case CKM_AES_CBC:
1639    case CKM_DES_CBC:
1640    case CKM_DES3_CBC:
1641    case CKM_IDEA_CBC:
1642    case CKM_CDMF_CBC:
1643    case CKM_CAST_CBC:
1644    case CKM_CAST3_CBC:
1645    case CKM_CAST5_CBC:
1646    case CKM_DES_CBC_PAD:
1647    case CKM_DES3_CBC_PAD:
1648    case CKM_IDEA_CBC_PAD:
1649    case CKM_CDMF_CBC_PAD:
1650    case CKM_CAST_CBC_PAD:
1651    case CKM_CAST3_CBC_PAD:
1652    case CKM_CAST5_CBC_PAD:
1653    case CKM_SKIPJACK_CBC64:
1654    case CKM_SKIPJACK_ECB64:
1655    case CKM_SKIPJACK_OFB64:
1656    case CKM_SKIPJACK_CFB64:
1657    case CKM_SKIPJACK_CFB32:
1658    case CKM_SKIPJACK_CFB16:
1659    case CKM_SKIPJACK_CFB8:
1660    case CKM_BATON_ECB128:
1661    case CKM_BATON_ECB96:
1662    case CKM_BATON_CBC128:
1663    case CKM_BATON_COUNTER:
1664    case CKM_BATON_SHUFFLE:
1665    case CKM_JUNIPER_ECB128:
1666    case CKM_JUNIPER_CBC128:
1667    case CKM_JUNIPER_COUNTER:
1668    case CKM_JUNIPER_SHUFFLE:
1669	newParams = SEC_ASN1EncodeItem(NULL,NULL,param,
1670                                       SEC_ASN1_GET(SEC_OctetStringTemplate) );
1671	if (newParams == NULL)
1672	    break;
1673	rv = SECSuccess;
1674	break;
1675    }
1676
1677    if (rv !=  SECSuccess) {
1678	if (newParams) SECITEM_FreeItem(newParams,PR_TRUE);
1679	return rv;
1680    }
1681
1682    rv = SECOID_SetAlgorithmID(arena, algid, algTag, newParams);
1683    SECITEM_FreeItem(newParams,PR_TRUE);
1684    return rv;
1685}
1686
1687/* turn an OID algorithm tag into a PKCS #11 mechanism. This allows us to
1688 * map OID's directly into the PKCS #11 mechanism we want to call. We find
1689 * this mapping in our standard OID table */
1690CK_MECHANISM_TYPE
1691PK11_AlgtagToMechanism(SECOidTag algTag) {
1692    SECOidData *oid = SECOID_FindOIDByTag(algTag);
1693
1694    if (oid) return (CK_MECHANISM_TYPE) oid->mechanism;
1695    return CKM_INVALID_MECHANISM;
1696}
1697
1698/* turn a mechanism into an oid. */
1699SECOidTag
1700PK11_MechanismToAlgtag(CK_MECHANISM_TYPE type) {
1701    SECOidData *oid = SECOID_FindOIDByMechanism((unsigned long)type);
1702
1703    if (oid) return oid->offset;
1704    return SEC_OID_UNKNOWN;
1705}
1706
1707/* Determine appropriate blocking mechanism, used when wrapping private keys
1708 * which require PKCS padding.  If the mechanism does not map to a padding
1709 * mechanism, we simply return the mechanism.
1710 */
1711CK_MECHANISM_TYPE
1712PK11_GetPadMechanism(CK_MECHANISM_TYPE type) {
1713    switch(type) {
1714	case CKM_SEED_CBC:
1715	    return CKM_SEED_CBC_PAD;
1716	case CKM_CAMELLIA_CBC:
1717	    return CKM_CAMELLIA_CBC_PAD;
1718	case CKM_AES_CBC:
1719	    return CKM_AES_CBC_PAD;
1720	case CKM_DES_CBC:
1721	    return CKM_DES_CBC_PAD;
1722	case CKM_DES3_CBC:
1723	    return CKM_DES3_CBC_PAD;
1724	case CKM_RC2_CBC:
1725	    return CKM_RC2_CBC_PAD;
1726	case CKM_CDMF_CBC:
1727	    return CKM_CDMF_CBC_PAD;
1728	case CKM_CAST_CBC:
1729	    return CKM_CAST_CBC_PAD;
1730	case CKM_CAST3_CBC:
1731	    return CKM_CAST3_CBC_PAD;
1732	case CKM_CAST5_CBC:
1733	    return CKM_CAST5_CBC_PAD;
1734	case CKM_RC5_CBC:
1735	    return CKM_RC5_CBC_PAD; 
1736	case CKM_IDEA_CBC:
1737	    return CKM_IDEA_CBC_PAD; 
1738	default:
1739	    break;
1740    }
1741
1742    return type;
1743}
1744	    
1745static PRBool
1746pk11_isAllZero(unsigned char *data,int len) {
1747    while (len--) {
1748	if (*data++) {
1749	    return PR_FALSE;
1750	}
1751    }
1752    return PR_TRUE;
1753}
1754
1755CK_RV
1756PK11_MapPBEMechanismToCryptoMechanism(CK_MECHANISM_PTR pPBEMechanism, 
1757				      CK_MECHANISM_PTR pCryptoMechanism,
1758				      SECItem *pbe_pwd, PRBool faulty3DES)
1759{
1760    int iv_len = 0;
1761    CK_PBE_PARAMS_PTR pPBEparams;
1762    CK_RC2_CBC_PARAMS_PTR rc2_params;
1763    CK_ULONG rc2_key_len;
1764
1765    if((pPBEMechanism == CK_NULL_PTR) || (pCryptoMechanism == CK_NULL_PTR)) {
1766	return CKR_HOST_MEMORY;
1767    }
1768
1769    /* pkcs5 v2 cannot be supported by this interface.
1770     * use PK11_GetPBECryptoMechanism instead.
1771     */
1772    if ((pPBEMechanism->mechanism == CKM_INVALID_MECHANISM) || 
1773	(pPBEMechanism->mechanism == CKM_PKCS5_PBKD2)) {
1774	return CKR_MECHANISM_INVALID;
1775    }
1776
1777    pPBEparams = (CK_PBE_PARAMS_PTR)pPBEMechanism->pParameter;
1778    iv_len = PK11_GetIVLength(pPBEMechanism->mechanism);
1779
1780    if (iv_len) {
1781	if (pk11_isAllZero(pPBEparams->pInitVector,iv_len)) {
1782	    SECItem param;
1783	    PK11SymKey *symKey;
1784	    PK11SlotInfo *intSlot = PK11_GetInternalSlot();
1785
1786	    if (intSlot == NULL) {
1787		return CKR_DEVICE_ERROR;
1788	    }
1789
1790	    param.data = pPBEMechanism->pParameter;
1791	    param.len = pPBEMechanism->ulParameterLen;
1792
1793	    symKey = PK11_RawPBEKeyGen(intSlot,
1794		pPBEMechanism->mechanism, &param, pbe_pwd, faulty3DES, NULL);
1795	    PK11_FreeSlot(intSlot);
1796	    if (symKey== NULL) {
1797		return CKR_DEVICE_ERROR; /* sigh */
1798	    }
1799	    PK11_FreeSymKey(symKey);
1800	}
1801    }
1802
1803    switch(pPBEMechanism->mechanism) {
1804	case CKM_PBE_MD2_DES_CBC:
1805	case CKM_PBE_MD5_DES_CBC:
1806	case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
1807	    pCryptoMechanism->mechanism = CKM_DES_CBC;
1808	    goto have_crypto_mechanism;
1809	case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
1810	case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
1811	case CKM_PBE_SHA1_DES3_EDE_CBC:
1812	case CKM_PBE_SHA1_DES2_EDE_CBC:
1813	    pCryptoMechanism->mechanism = CKM_DES3_CBC;
1814have_crypto_mechanism:
1815	    pCryptoMechanism->pParameter = PORT_Alloc(iv_len);
1816	    pCryptoMechanism->

Large files files are truncated, but you can click here to view the full file