Back to index

lightning-sunbird  0.9+nobinonly
pk11mech.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *   Dr Stephen Henson <stephen.henson@gemplus.com>
00023  *   Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 /*
00039  * This file maps various PKCS #11 Mechanisms to related mechanisms, key
00040  * types, and ASN.1 encodings.
00041  */
00042 #include "seccomon.h"
00043 #include "secmod.h"
00044 #include "secmodi.h"
00045 #include "pkcs11t.h"
00046 #include "pk11func.h"
00047 #include "secitem.h"
00048 #include "secder.h"
00049 #include "secasn1.h" 
00050 #include "secoid.h"
00051 #include "secerr.h"
00052 
00053 /*************************************************************
00054  * local static and global data
00055  *************************************************************/
00056 
00057 /*
00058  * Tables used for Extended mechanism mapping (currently not used)
00059  */
00060 typedef struct {
00061        CK_MECHANISM_TYPE keyGen;
00062        CK_KEY_TYPE keyType;
00063        CK_MECHANISM_TYPE type;
00064        int blockSize;
00065        int iv;
00066 } pk11MechanismData;
00067        
00068 static pk11MechanismData pk11_default = 
00069   { CKM_GENERIC_SECRET_KEY_GEN, CKK_GENERIC_SECRET, CKM_FAKE_RANDOM, 8, 8 };
00070 static pk11MechanismData *pk11_MechanismTable = NULL;
00071 static int pk11_MechTableSize = 0;
00072 static int pk11_MechEntrySize = 0;
00073 
00074 /*
00075  * list of mechanisms we're willing to wrap secret keys with.
00076  * This list is ordered by preference.
00077  */
00078 CK_MECHANISM_TYPE wrapMechanismList[] = {
00079     CKM_DES3_ECB,
00080     CKM_CAST5_ECB,
00081     CKM_AES_ECB,
00082     CKM_CAST5_ECB,
00083     CKM_DES_ECB,
00084     CKM_KEY_WRAP_LYNKS,
00085     CKM_IDEA_ECB,
00086     CKM_CAST3_ECB,
00087     CKM_CAST_ECB,
00088     CKM_RC5_ECB,
00089     CKM_RC2_ECB,
00090     CKM_CDMF_ECB,
00091     CKM_SKIPJACK_WRAP,
00092 };
00093 
00094 int wrapMechanismCount = sizeof(wrapMechanismList)/sizeof(wrapMechanismList[0]);
00095 
00096 /*********************************************************************
00097  *       Mechanism Mapping functions
00098  *********************************************************************/
00099 
00100 /*
00101  * lookup an entry in the mechanism table. If none found, return the
00102  * default structure.
00103  */
00104 static pk11MechanismData *
00105 pk11_lookup(CK_MECHANISM_TYPE type)
00106 {
00107     int i;
00108     for (i=0; i < pk11_MechEntrySize; i++) {
00109        if (pk11_MechanismTable[i].type == type) {
00110             return (&pk11_MechanismTable[i]);
00111        }
00112     }
00113     return &pk11_default;
00114 }
00115 
00116 /*
00117  * find the best key wrap mechanism for this slot.
00118  */
00119 CK_MECHANISM_TYPE
00120 PK11_GetBestWrapMechanism(PK11SlotInfo *slot)
00121 {
00122     int i;
00123     for (i=0; i < wrapMechanismCount; i++) {
00124        if (PK11_DoesMechanism(slot,wrapMechanismList[i])) {
00125            return wrapMechanismList[i];
00126        }
00127     }
00128     return CKM_INVALID_MECHANISM;
00129 }
00130 
00131 /*
00132  * NOTE: This is not thread safe. Called at init time, and when loading
00133  * a new Entry. It is reasonably safe as long as it is not re-entered
00134  * (readers will always see a consistant table)
00135  *
00136  * This routine is called to add entries to the mechanism table, once there,
00137  * they can not be removed.
00138  */
00139 void
00140 PK11_AddMechanismEntry(CK_MECHANISM_TYPE type, CK_KEY_TYPE key,
00141                      CK_MECHANISM_TYPE keyGen, int ivLen, int blockSize)
00142 {
00143     int tableSize = pk11_MechTableSize;
00144     int size = pk11_MechEntrySize;
00145     int entry = size++;
00146     pk11MechanismData *old = pk11_MechanismTable;
00147     pk11MechanismData *newt = pk11_MechanismTable;
00148 
00149        
00150     if (size > tableSize) {
00151        int oldTableSize = tableSize;
00152        tableSize += 10;
00153        newt = PORT_NewArray(pk11MechanismData, tableSize);
00154        if (newt == NULL) return;
00155 
00156        if (old) PORT_Memcpy(newt, old, oldTableSize*sizeof(*newt));
00157     } else old = NULL;
00158 
00159     newt[entry].type = type;
00160     newt[entry].keyType = key;
00161     newt[entry].keyGen = keyGen;
00162     newt[entry].iv = ivLen;
00163     newt[entry].blockSize = blockSize;
00164 
00165     pk11_MechanismTable = newt;
00166     pk11_MechTableSize = tableSize;
00167     pk11_MechEntrySize = size;
00168     if (old) PORT_Free(old);
00169 }
00170 
00171 /*
00172  * Get the key type needed for the given mechanism
00173  */
00174 CK_MECHANISM_TYPE
00175 PK11_GetKeyMechanism(CK_KEY_TYPE type)
00176 {
00177     switch (type) {
00178     case CKK_AES:
00179        return CKM_AES_CBC;
00180     case CKK_DES:
00181        return CKM_DES_CBC;
00182     case CKK_DES3:
00183        return CKM_DES3_KEY_GEN;
00184     case CKK_DES2:
00185        return CKM_DES2_KEY_GEN;
00186     case CKK_CDMF:
00187        return CKM_CDMF_CBC;
00188     case CKK_RC2:
00189        return CKM_RC2_CBC;
00190     case CKK_RC4:
00191        return CKM_RC4;
00192     case CKK_RC5:
00193        return CKM_RC5_CBC;
00194     case CKK_SKIPJACK:
00195        return CKM_SKIPJACK_CBC64;
00196     case CKK_BATON:
00197        return CKM_BATON_CBC128;
00198     case CKK_JUNIPER:
00199        return CKM_JUNIPER_CBC128;
00200     case CKK_IDEA:
00201        return CKM_IDEA_CBC;
00202     case CKK_CAST:
00203        return CKM_CAST_CBC;
00204     case CKK_CAST3:
00205        return CKM_CAST3_CBC;
00206     case CKK_CAST5:
00207        return CKM_CAST5_CBC;
00208     case CKK_RSA:
00209        return CKM_RSA_PKCS;
00210     case CKK_DSA:
00211        return CKM_DSA;
00212     case CKK_DH:
00213        return CKM_DH_PKCS_DERIVE;
00214     case CKK_KEA:
00215        return CKM_KEA_KEY_DERIVE;
00216     case CKK_EC:  /* CKK_ECDSA is deprecated */
00217        return CKM_ECDSA;
00218     case CKK_GENERIC_SECRET:
00219     default:
00220        return CKM_SHA_1_HMAC;
00221     }
00222 }
00223 
00224 /*
00225  * Get the key type needed for the given mechanism
00226  */
00227 CK_MECHANISM_TYPE
00228 PK11_GetKeyType(CK_MECHANISM_TYPE type,unsigned long len)
00229 {
00230     switch (type) {
00231     case CKM_AES_ECB:
00232     case CKM_AES_CBC:
00233     case CKM_AES_MAC:
00234     case CKM_AES_MAC_GENERAL:
00235     case CKM_AES_CBC_PAD:
00236     case CKM_AES_KEY_GEN:
00237     case CKM_NETSCAPE_AES_KEY_WRAP:
00238     case CKM_NETSCAPE_AES_KEY_WRAP_PAD:
00239        return CKK_AES;
00240     case CKM_DES_ECB:
00241     case CKM_DES_CBC:
00242     case CKM_DES_MAC:
00243     case CKM_DES_MAC_GENERAL:
00244     case CKM_DES_CBC_PAD:
00245     case CKM_DES_KEY_GEN:
00246     case CKM_KEY_WRAP_LYNKS:
00247     case CKM_PBE_MD2_DES_CBC:
00248     case CKM_PBE_MD5_DES_CBC:
00249        return CKK_DES;
00250     case CKM_DES3_ECB:
00251     case CKM_DES3_CBC:
00252     case CKM_DES3_MAC:
00253     case CKM_DES3_MAC_GENERAL:
00254     case CKM_DES3_CBC_PAD:
00255        return (len == 16) ? CKK_DES2 : CKK_DES3;
00256     case CKM_DES2_KEY_GEN:
00257     case CKM_PBE_SHA1_DES2_EDE_CBC:
00258        return CKK_DES2;
00259     case CKM_PBE_SHA1_DES3_EDE_CBC:
00260     case CKM_DES3_KEY_GEN:
00261        return CKK_DES3;
00262     case CKM_CDMF_ECB:
00263     case CKM_CDMF_CBC:
00264     case CKM_CDMF_MAC:
00265     case CKM_CDMF_MAC_GENERAL:
00266     case CKM_CDMF_CBC_PAD:
00267     case CKM_CDMF_KEY_GEN:
00268        return CKK_CDMF;
00269     case CKM_RC2_ECB:
00270     case CKM_RC2_CBC:
00271     case CKM_RC2_MAC:
00272     case CKM_RC2_MAC_GENERAL:
00273     case CKM_RC2_CBC_PAD:
00274     case CKM_RC2_KEY_GEN:
00275     case CKM_PBE_SHA1_RC2_128_CBC:
00276     case CKM_PBE_SHA1_RC2_40_CBC:
00277        return CKK_RC2;
00278     case CKM_RC4:
00279     case CKM_RC4_KEY_GEN:
00280        return CKK_RC4;
00281     case CKM_RC5_ECB:
00282     case CKM_RC5_CBC:
00283     case CKM_RC5_MAC:
00284     case CKM_RC5_MAC_GENERAL:
00285     case CKM_RC5_CBC_PAD:
00286     case CKM_RC5_KEY_GEN:
00287        return CKK_RC5;
00288     case CKM_SKIPJACK_CBC64:
00289     case CKM_SKIPJACK_ECB64:
00290     case CKM_SKIPJACK_OFB64:
00291     case CKM_SKIPJACK_CFB64:
00292     case CKM_SKIPJACK_CFB32:
00293     case CKM_SKIPJACK_CFB16:
00294     case CKM_SKIPJACK_CFB8:
00295     case CKM_SKIPJACK_KEY_GEN:
00296     case CKM_SKIPJACK_WRAP:
00297     case CKM_SKIPJACK_PRIVATE_WRAP:
00298        return CKK_SKIPJACK;
00299     case CKM_BATON_ECB128:
00300     case CKM_BATON_ECB96:
00301     case CKM_BATON_CBC128:
00302     case CKM_BATON_COUNTER:
00303     case CKM_BATON_SHUFFLE:
00304     case CKM_BATON_WRAP:
00305     case CKM_BATON_KEY_GEN:
00306        return CKK_BATON;
00307     case CKM_JUNIPER_ECB128:
00308     case CKM_JUNIPER_CBC128:
00309     case CKM_JUNIPER_COUNTER:
00310     case CKM_JUNIPER_SHUFFLE:
00311     case CKM_JUNIPER_WRAP:
00312     case CKM_JUNIPER_KEY_GEN:
00313        return CKK_JUNIPER;
00314     case CKM_IDEA_CBC:
00315     case CKM_IDEA_ECB:
00316     case CKM_IDEA_MAC:
00317     case CKM_IDEA_MAC_GENERAL:
00318     case CKM_IDEA_CBC_PAD:
00319     case CKM_IDEA_KEY_GEN:
00320        return CKK_IDEA;
00321     case CKM_CAST_ECB:
00322     case CKM_CAST_CBC:
00323     case CKM_CAST_MAC:
00324     case CKM_CAST_MAC_GENERAL:
00325     case CKM_CAST_CBC_PAD:
00326     case CKM_CAST_KEY_GEN:
00327     case CKM_PBE_MD5_CAST_CBC:
00328        return CKK_CAST;
00329     case CKM_CAST3_ECB:
00330     case CKM_CAST3_CBC:
00331     case CKM_CAST3_MAC:
00332     case CKM_CAST3_MAC_GENERAL:
00333     case CKM_CAST3_CBC_PAD:
00334     case CKM_CAST3_KEY_GEN:
00335     case CKM_PBE_MD5_CAST3_CBC:
00336        return CKK_CAST3;
00337     case CKM_CAST5_ECB:
00338     case CKM_CAST5_CBC:
00339     case CKM_CAST5_MAC:
00340     case CKM_CAST5_MAC_GENERAL:
00341     case CKM_CAST5_CBC_PAD:
00342     case CKM_CAST5_KEY_GEN:
00343     case CKM_PBE_MD5_CAST5_CBC:
00344        return CKK_CAST5;
00345     case CKM_RSA_PKCS:
00346     case CKM_RSA_9796:
00347     case CKM_RSA_X_509:
00348     case CKM_MD2_RSA_PKCS:
00349     case CKM_MD5_RSA_PKCS:
00350     case CKM_SHA1_RSA_PKCS:
00351     case CKM_SHA256_RSA_PKCS:
00352     case CKM_SHA384_RSA_PKCS:
00353     case CKM_SHA512_RSA_PKCS:
00354     case CKM_KEY_WRAP_SET_OAEP:
00355     case CKM_RSA_PKCS_KEY_PAIR_GEN:
00356     case CKM_RSA_X9_31_KEY_PAIR_GEN:
00357        return CKK_RSA;
00358     case CKM_DSA:
00359     case CKM_DSA_SHA1:
00360     case CKM_DSA_KEY_PAIR_GEN:
00361        return CKK_DSA;
00362     case CKM_DH_PKCS_DERIVE:
00363     case CKM_DH_PKCS_KEY_PAIR_GEN:
00364        return CKK_DH;
00365     case CKM_KEA_KEY_DERIVE:
00366     case CKM_KEA_KEY_PAIR_GEN:
00367        return CKK_KEA;
00368     case CKM_ECDSA:
00369     case CKM_ECDSA_SHA1:
00370     case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */
00371     case CKM_ECDH1_DERIVE:
00372        return CKK_EC;  /* CKK_ECDSA is deprecated */
00373     case CKM_SSL3_PRE_MASTER_KEY_GEN:
00374     case CKM_GENERIC_SECRET_KEY_GEN:
00375     case CKM_SSL3_MASTER_KEY_DERIVE:
00376     case CKM_SSL3_MASTER_KEY_DERIVE_DH:
00377     case CKM_SSL3_KEY_AND_MAC_DERIVE:
00378     case CKM_SSL3_SHA1_MAC:
00379     case CKM_SSL3_MD5_MAC:
00380     case CKM_TLS_MASTER_KEY_DERIVE:
00381     case CKM_TLS_MASTER_KEY_DERIVE_DH:
00382     case CKM_TLS_KEY_AND_MAC_DERIVE:
00383     case CKM_SHA_1_HMAC:
00384     case CKM_SHA_1_HMAC_GENERAL:
00385     case CKM_SHA256_HMAC:
00386     case CKM_SHA256_HMAC_GENERAL:
00387     case CKM_SHA384_HMAC:
00388     case CKM_SHA384_HMAC_GENERAL:
00389     case CKM_SHA512_HMAC:
00390     case CKM_SHA512_HMAC_GENERAL:
00391     case CKM_MD2_HMAC:
00392     case CKM_MD2_HMAC_GENERAL:
00393     case CKM_MD5_HMAC:
00394     case CKM_MD5_HMAC_GENERAL:
00395     case CKM_TLS_PRF_GENERAL:
00396        return CKK_GENERIC_SECRET;
00397     default:
00398        return pk11_lookup(type)->keyType;
00399     }
00400 }
00401 
00402 /*
00403  * Get the Key Gen Mechanism needed for the given 
00404  * crypto mechanism
00405  */
00406 CK_MECHANISM_TYPE
00407 PK11_GetKeyGen(CK_MECHANISM_TYPE type)
00408 {
00409     return PK11_GetKeyGenWithSize(type, 0);
00410 }
00411 
00412 CK_MECHANISM_TYPE
00413 PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size)
00414 {
00415     switch (type) {
00416     case CKM_AES_ECB:
00417     case CKM_AES_CBC:
00418     case CKM_AES_MAC:
00419     case CKM_AES_MAC_GENERAL:
00420     case CKM_AES_CBC_PAD:
00421     case CKM_AES_KEY_GEN:
00422        return CKM_AES_KEY_GEN;
00423     case CKM_DES_ECB:
00424     case CKM_DES_CBC:
00425     case CKM_DES_MAC:
00426     case CKM_DES_MAC_GENERAL:
00427     case CKM_KEY_WRAP_LYNKS:
00428     case CKM_DES_CBC_PAD:
00429     case CKM_DES_KEY_GEN:
00430        return CKM_DES_KEY_GEN;
00431     case CKM_DES3_ECB:
00432     case CKM_DES3_CBC:
00433     case CKM_DES3_MAC:
00434     case CKM_DES3_MAC_GENERAL:
00435     case CKM_DES3_CBC_PAD:
00436        return (size == 16) ? CKM_DES2_KEY_GEN : CKM_DES3_KEY_GEN;
00437     case CKM_DES3_KEY_GEN:
00438        return CKM_DES3_KEY_GEN;
00439     case CKM_DES2_KEY_GEN:
00440        return CKM_DES2_KEY_GEN;
00441     case CKM_CDMF_ECB:
00442     case CKM_CDMF_CBC:
00443     case CKM_CDMF_MAC:
00444     case CKM_CDMF_MAC_GENERAL:
00445     case CKM_CDMF_CBC_PAD:
00446     case CKM_CDMF_KEY_GEN:
00447        return CKM_CDMF_KEY_GEN;
00448     case CKM_RC2_ECB:
00449     case CKM_RC2_CBC:
00450     case CKM_RC2_MAC:
00451     case CKM_RC2_MAC_GENERAL:
00452     case CKM_RC2_CBC_PAD:
00453     case CKM_RC2_KEY_GEN:
00454        return CKM_RC2_KEY_GEN;
00455     case CKM_RC4:
00456     case CKM_RC4_KEY_GEN:
00457        return CKM_RC4_KEY_GEN;
00458     case CKM_RC5_ECB:
00459     case CKM_RC5_CBC:
00460     case CKM_RC5_MAC:
00461     case CKM_RC5_MAC_GENERAL:
00462     case CKM_RC5_CBC_PAD:
00463     case CKM_RC5_KEY_GEN:
00464        return CKM_RC5_KEY_GEN;
00465     case CKM_SKIPJACK_CBC64:
00466     case CKM_SKIPJACK_ECB64:
00467     case CKM_SKIPJACK_OFB64:
00468     case CKM_SKIPJACK_CFB64:
00469     case CKM_SKIPJACK_CFB32:
00470     case CKM_SKIPJACK_CFB16:
00471     case CKM_SKIPJACK_CFB8:
00472     case CKM_SKIPJACK_WRAP:
00473     case CKM_SKIPJACK_KEY_GEN:
00474        return CKM_SKIPJACK_KEY_GEN;
00475     case CKM_BATON_ECB128:
00476     case CKM_BATON_ECB96:
00477     case CKM_BATON_CBC128:
00478     case CKM_BATON_COUNTER:
00479     case CKM_BATON_SHUFFLE:
00480     case CKM_BATON_WRAP:
00481     case CKM_BATON_KEY_GEN:
00482        return CKM_BATON_KEY_GEN;
00483     case CKM_JUNIPER_ECB128:
00484     case CKM_JUNIPER_CBC128:
00485     case CKM_JUNIPER_COUNTER:
00486     case CKM_JUNIPER_SHUFFLE:
00487     case CKM_JUNIPER_WRAP:
00488     case CKM_JUNIPER_KEY_GEN:
00489        return CKM_JUNIPER_KEY_GEN;
00490     case CKM_IDEA_CBC:
00491     case CKM_IDEA_ECB:
00492     case CKM_IDEA_MAC:
00493     case CKM_IDEA_MAC_GENERAL:
00494     case CKM_IDEA_CBC_PAD:
00495     case CKM_IDEA_KEY_GEN:
00496        return CKM_IDEA_KEY_GEN;
00497     case CKM_CAST_ECB:
00498     case CKM_CAST_CBC:
00499     case CKM_CAST_MAC:
00500     case CKM_CAST_MAC_GENERAL:
00501     case CKM_CAST_CBC_PAD:
00502     case CKM_CAST_KEY_GEN:
00503        return CKM_CAST_KEY_GEN;
00504     case CKM_CAST3_ECB:
00505     case CKM_CAST3_CBC:
00506     case CKM_CAST3_MAC:
00507     case CKM_CAST3_MAC_GENERAL:
00508     case CKM_CAST3_CBC_PAD:
00509     case CKM_CAST3_KEY_GEN:
00510        return CKM_CAST3_KEY_GEN;
00511     case CKM_CAST5_ECB:
00512     case CKM_CAST5_CBC:
00513     case CKM_CAST5_MAC:
00514     case CKM_CAST5_MAC_GENERAL:
00515     case CKM_CAST5_CBC_PAD:
00516     case CKM_CAST5_KEY_GEN:
00517        return CKM_CAST5_KEY_GEN;
00518     case CKM_RSA_PKCS:
00519     case CKM_RSA_9796:
00520     case CKM_RSA_X_509:
00521     case CKM_MD2_RSA_PKCS:
00522     case CKM_MD5_RSA_PKCS:
00523     case CKM_SHA1_RSA_PKCS:
00524     case CKM_SHA256_RSA_PKCS:
00525     case CKM_SHA384_RSA_PKCS:
00526     case CKM_SHA512_RSA_PKCS:
00527     case CKM_KEY_WRAP_SET_OAEP:
00528     case CKM_RSA_PKCS_KEY_PAIR_GEN:
00529        return CKM_RSA_PKCS_KEY_PAIR_GEN;
00530     case CKM_RSA_X9_31_KEY_PAIR_GEN:
00531        return CKM_RSA_X9_31_KEY_PAIR_GEN;
00532     case CKM_DSA:
00533     case CKM_DSA_SHA1:
00534     case CKM_DSA_KEY_PAIR_GEN:
00535        return CKM_DSA_KEY_PAIR_GEN;
00536     case CKM_DH_PKCS_DERIVE:
00537     case CKM_DH_PKCS_KEY_PAIR_GEN:
00538        return CKM_DH_PKCS_KEY_PAIR_GEN;
00539     case CKM_KEA_KEY_DERIVE:
00540     case CKM_KEA_KEY_PAIR_GEN:
00541        return CKM_KEA_KEY_PAIR_GEN;
00542     case CKM_ECDSA:
00543     case CKM_ECDSA_SHA1:
00544     case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */
00545     case CKM_ECDH1_DERIVE:
00546         return CKM_EC_KEY_PAIR_GEN; 
00547     case CKM_SSL3_PRE_MASTER_KEY_GEN:
00548     case CKM_SSL3_MASTER_KEY_DERIVE:
00549     case CKM_SSL3_KEY_AND_MAC_DERIVE:
00550     case CKM_SSL3_SHA1_MAC:
00551     case CKM_SSL3_MD5_MAC:
00552     case CKM_TLS_MASTER_KEY_DERIVE:
00553     case CKM_TLS_KEY_AND_MAC_DERIVE:
00554        return CKM_SSL3_PRE_MASTER_KEY_GEN;
00555     case CKM_SHA_1_HMAC:
00556     case CKM_SHA_1_HMAC_GENERAL:
00557     case CKM_SHA256_HMAC:
00558     case CKM_SHA256_HMAC_GENERAL:
00559     case CKM_SHA384_HMAC:
00560     case CKM_SHA384_HMAC_GENERAL:
00561     case CKM_SHA512_HMAC:
00562     case CKM_SHA512_HMAC_GENERAL:
00563     case CKM_MD2_HMAC:
00564     case CKM_MD2_HMAC_GENERAL:
00565     case CKM_MD5_HMAC:
00566     case CKM_MD5_HMAC_GENERAL:
00567     case CKM_TLS_PRF_GENERAL:
00568     case CKM_GENERIC_SECRET_KEY_GEN:
00569        return CKM_GENERIC_SECRET_KEY_GEN;
00570     case CKM_PBE_MD2_DES_CBC:
00571     case CKM_PBE_MD5_DES_CBC:
00572     case CKM_PBA_SHA1_WITH_SHA1_HMAC:
00573     case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
00574     case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
00575     case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
00576     case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
00577     case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
00578     case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
00579     case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
00580     case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
00581     case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
00582     case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
00583     case CKM_PBE_SHA1_RC2_40_CBC:
00584     case CKM_PBE_SHA1_RC2_128_CBC:
00585     case CKM_PBE_SHA1_RC4_40:
00586     case CKM_PBE_SHA1_RC4_128:
00587     case CKM_PBE_SHA1_DES3_EDE_CBC:
00588     case CKM_PBE_SHA1_DES2_EDE_CBC:
00589        return type;
00590     default:
00591        return pk11_lookup(type)->keyGen;
00592     }
00593 }
00594 
00595 /*
00596  * get the mechanism block size
00597  */
00598 int
00599 PK11_GetBlockSize(CK_MECHANISM_TYPE type,SECItem *params)
00600 {
00601     CK_RC5_PARAMS *rc5_params;
00602     CK_RC5_CBC_PARAMS *rc5_cbc_params;
00603     switch (type) {
00604     case CKM_RC5_ECB:
00605        if ((params) && (params->data)) {
00606            rc5_params = (CK_RC5_PARAMS *) params->data;
00607            return (rc5_params->ulWordsize)*2;
00608        }
00609        return 8;
00610     case CKM_RC5_CBC:
00611     case CKM_RC5_CBC_PAD:
00612        if ((params) && (params->data)) {
00613            rc5_cbc_params = (CK_RC5_CBC_PARAMS *) params->data;
00614            return (rc5_cbc_params->ulWordsize)*2;
00615        }
00616        return 8;
00617     case CKM_DES_ECB:
00618     case CKM_DES3_ECB:
00619     case CKM_RC2_ECB:
00620     case CKM_IDEA_ECB:
00621     case CKM_CAST_ECB:
00622     case CKM_CAST3_ECB:
00623     case CKM_CAST5_ECB:
00624     case CKM_RC2_CBC:
00625     case CKM_SKIPJACK_CBC64:
00626     case CKM_SKIPJACK_ECB64:
00627     case CKM_SKIPJACK_OFB64:
00628     case CKM_SKIPJACK_CFB64:
00629     case CKM_DES_CBC:
00630     case CKM_DES3_CBC:
00631     case CKM_IDEA_CBC:
00632     case CKM_CAST_CBC:
00633     case CKM_CAST3_CBC:
00634     case CKM_CAST5_CBC:
00635     case CKM_DES_CBC_PAD:
00636     case CKM_DES3_CBC_PAD:
00637     case CKM_RC2_CBC_PAD:
00638     case CKM_IDEA_CBC_PAD:
00639     case CKM_CAST_CBC_PAD:
00640     case CKM_CAST3_CBC_PAD:
00641     case CKM_CAST5_CBC_PAD:
00642     case CKM_PBE_MD2_DES_CBC:
00643     case CKM_PBE_MD5_DES_CBC:
00644     case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
00645     case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
00646     case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
00647     case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
00648     case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
00649     case CKM_PBE_SHA1_RC2_40_CBC:
00650     case CKM_PBE_SHA1_RC2_128_CBC:
00651     case CKM_PBE_SHA1_DES3_EDE_CBC:
00652     case CKM_PBE_SHA1_DES2_EDE_CBC:
00653        return 8;
00654     case CKM_SKIPJACK_CFB32:
00655     case CKM_SKIPJACK_CFB16:
00656     case CKM_SKIPJACK_CFB8:
00657        return 4;
00658     case CKM_AES_ECB:
00659     case CKM_AES_CBC:
00660     case CKM_AES_CBC_PAD:
00661     case CKM_BATON_ECB128:
00662     case CKM_BATON_CBC128:
00663     case CKM_BATON_COUNTER:
00664     case CKM_BATON_SHUFFLE:
00665     case CKM_JUNIPER_ECB128:
00666     case CKM_JUNIPER_CBC128:
00667     case CKM_JUNIPER_COUNTER:
00668     case CKM_JUNIPER_SHUFFLE:
00669        return 16;
00670     case CKM_BATON_ECB96:
00671        return 12;
00672     case CKM_RC4:
00673     case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
00674     case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
00675     case CKM_PBE_SHA1_RC4_40:
00676     case CKM_PBE_SHA1_RC4_128:
00677        return 0;
00678     case CKM_RSA_PKCS:
00679     case CKM_RSA_9796:
00680     case CKM_RSA_X_509:
00681        /*actually it's the modulus length of the key!*/
00682        return -1;    /* failure */
00683     default:
00684        return pk11_lookup(type)->blockSize;
00685     }
00686 }
00687 
00688 /*
00689  * get the iv length
00690  */
00691 int
00692 PK11_GetIVLength(CK_MECHANISM_TYPE type)
00693 {
00694     switch (type) {
00695     case CKM_AES_ECB:
00696     case CKM_DES_ECB:
00697     case CKM_DES3_ECB:
00698     case CKM_RC2_ECB:
00699     case CKM_IDEA_ECB:
00700     case CKM_SKIPJACK_WRAP:
00701     case CKM_BATON_WRAP:
00702     case CKM_RC5_ECB:
00703     case CKM_CAST_ECB:
00704     case CKM_CAST3_ECB:
00705     case CKM_CAST5_ECB:
00706        return 0;
00707     case CKM_RC2_CBC:
00708     case CKM_DES_CBC:
00709     case CKM_DES3_CBC:
00710     case CKM_IDEA_CBC:
00711     case CKM_PBE_MD2_DES_CBC:
00712     case CKM_PBE_MD5_DES_CBC:
00713     case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
00714     case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
00715     case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
00716     case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
00717     case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
00718     case CKM_PBE_SHA1_RC2_40_CBC:
00719     case CKM_PBE_SHA1_RC2_128_CBC:
00720     case CKM_PBE_SHA1_DES3_EDE_CBC:
00721     case CKM_PBE_SHA1_DES2_EDE_CBC:
00722     case CKM_RC5_CBC:
00723     case CKM_CAST_CBC:
00724     case CKM_CAST3_CBC:
00725     case CKM_CAST5_CBC:
00726     case CKM_RC2_CBC_PAD:
00727     case CKM_DES_CBC_PAD:
00728     case CKM_DES3_CBC_PAD:
00729     case CKM_IDEA_CBC_PAD:
00730     case CKM_RC5_CBC_PAD:
00731     case CKM_CAST_CBC_PAD:
00732     case CKM_CAST3_CBC_PAD:
00733     case CKM_CAST5_CBC_PAD:
00734        return 8;
00735     case CKM_AES_CBC:
00736     case CKM_AES_CBC_PAD:
00737        return 16;
00738     case CKM_SKIPJACK_CBC64:
00739     case CKM_SKIPJACK_ECB64:
00740     case CKM_SKIPJACK_OFB64:
00741     case CKM_SKIPJACK_CFB64:
00742     case CKM_SKIPJACK_CFB32:
00743     case CKM_SKIPJACK_CFB16:
00744     case CKM_SKIPJACK_CFB8:
00745     case CKM_BATON_ECB128:
00746     case CKM_BATON_ECB96:
00747     case CKM_BATON_CBC128:
00748     case CKM_BATON_COUNTER:
00749     case CKM_BATON_SHUFFLE:
00750     case CKM_JUNIPER_ECB128:
00751     case CKM_JUNIPER_CBC128:
00752     case CKM_JUNIPER_COUNTER:
00753     case CKM_JUNIPER_SHUFFLE:
00754        return 24;
00755     case CKM_RC4:
00756     case CKM_RSA_PKCS:
00757     case CKM_RSA_9796:
00758     case CKM_RSA_X_509:
00759     case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
00760     case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
00761     case CKM_PBE_SHA1_RC4_40:
00762     case CKM_PBE_SHA1_RC4_128:
00763        return 0;
00764     default:
00765        return pk11_lookup(type)->iv;
00766     }
00767 }
00768 
00769 
00770 /* These next two utilities are here to help facilitate future
00771  * Dynamic Encrypt/Decrypt symetric key mechanisms, and to allow functions
00772  * like SSL and S-MIME to automatically add them.
00773  */
00774 SECItem *
00775 PK11_ParamFromIV(CK_MECHANISM_TYPE type,SECItem *iv)
00776 {
00777     CK_RC2_CBC_PARAMS *rc2_params = NULL;
00778     CK_RC2_PARAMS *rc2_ecb_params = NULL;
00779     CK_RC5_PARAMS *rc5_params = NULL;
00780     CK_RC5_CBC_PARAMS *rc5_cbc_params = NULL;
00781     SECItem *param;
00782 
00783     param = (SECItem *)PORT_Alloc(sizeof(SECItem));
00784     if (param == NULL) return NULL;
00785     param->data = NULL;
00786     param->len = 0;
00787     param->type = 0;
00788     switch (type) {
00789     case CKM_AES_ECB:
00790     case CKM_DES_ECB:
00791     case CKM_DES3_ECB:
00792     case CKM_RSA_PKCS:
00793     case CKM_RSA_X_509:
00794     case CKM_RSA_9796:
00795     case CKM_IDEA_ECB:
00796     case CKM_CDMF_ECB:
00797     case CKM_CAST_ECB:
00798     case CKM_CAST3_ECB:
00799     case CKM_CAST5_ECB:
00800     case CKM_RC4:
00801        break;
00802     case CKM_RC2_ECB:
00803        rc2_ecb_params = (CK_RC2_PARAMS *)PORT_Alloc(sizeof(CK_RC2_PARAMS));
00804        if (rc2_ecb_params == NULL) break;
00805        /*  Maybe we should pass the key size in too to get this value? */
00806        *rc2_ecb_params = 128;
00807        param->data = (unsigned char *) rc2_ecb_params;
00808        param->len = sizeof(CK_RC2_PARAMS);
00809        break;
00810     case CKM_RC2_CBC:
00811     case CKM_RC2_CBC_PAD:
00812        rc2_params = (CK_RC2_CBC_PARAMS *)PORT_Alloc(sizeof(CK_RC2_CBC_PARAMS));
00813        if (rc2_params == NULL) break;
00814        /* Maybe we should pass the key size in too to get this value? */
00815        rc2_params->ulEffectiveBits = 128;
00816        if (iv && iv->data)
00817            PORT_Memcpy(rc2_params->iv,iv->data,sizeof(rc2_params->iv));
00818        param->data = (unsigned char *) rc2_params;
00819        param->len = sizeof(CK_RC2_CBC_PARAMS);
00820        break;
00821     case CKM_RC5_CBC:
00822     case CKM_RC5_CBC_PAD:
00823        rc5_cbc_params = (CK_RC5_CBC_PARAMS *)
00824               PORT_Alloc(sizeof(CK_RC5_CBC_PARAMS) + ((iv) ? iv->len : 0));
00825        if (rc5_cbc_params == NULL) break;
00826        if (iv && iv->data && iv->len) {
00827            rc5_cbc_params->pIv = ((CK_BYTE_PTR) rc5_cbc_params) 
00828                                           + sizeof(CK_RC5_CBC_PARAMS);
00829            PORT_Memcpy(rc5_cbc_params->pIv,iv->data,iv->len);
00830            rc5_cbc_params->ulIvLen = iv->len;
00831            rc5_cbc_params->ulWordsize = iv->len/2;
00832        } else {
00833            rc5_cbc_params->ulWordsize = 4;
00834            rc5_cbc_params->pIv = NULL;
00835            rc5_cbc_params->ulIvLen = 0;
00836        }
00837        rc5_cbc_params->ulRounds = 16;
00838        param->data = (unsigned char *) rc5_cbc_params;
00839        param->len = sizeof(CK_RC5_CBC_PARAMS);
00840        break;
00841     case CKM_RC5_ECB:
00842        rc5_params = (CK_RC5_PARAMS *)PORT_Alloc(sizeof(CK_RC5_PARAMS));
00843        if (rc5_params == NULL) break;
00844        if (iv && iv->data && iv->len) {
00845            rc5_params->ulWordsize = iv->len/2;
00846        } else {
00847            rc5_params->ulWordsize = 4;
00848        }
00849        rc5_params->ulRounds = 16;
00850        param->data = (unsigned char *) rc5_params;
00851        param->len = sizeof(CK_RC5_PARAMS);
00852        break;
00853     case CKM_AES_CBC:
00854     case CKM_DES_CBC:
00855     case CKM_DES3_CBC:
00856     case CKM_IDEA_CBC:
00857     case CKM_CDMF_CBC:
00858     case CKM_CAST_CBC:
00859     case CKM_CAST3_CBC:
00860     case CKM_CAST5_CBC:
00861     case CKM_AES_CBC_PAD:
00862     case CKM_DES_CBC_PAD:
00863     case CKM_DES3_CBC_PAD:
00864     case CKM_IDEA_CBC_PAD:
00865     case CKM_CDMF_CBC_PAD:
00866     case CKM_CAST_CBC_PAD:
00867     case CKM_CAST3_CBC_PAD:
00868     case CKM_CAST5_CBC_PAD:
00869     case CKM_SKIPJACK_CBC64:
00870     case CKM_SKIPJACK_ECB64:
00871     case CKM_SKIPJACK_OFB64:
00872     case CKM_SKIPJACK_CFB64:
00873     case CKM_SKIPJACK_CFB32:
00874     case CKM_SKIPJACK_CFB16:
00875     case CKM_SKIPJACK_CFB8:
00876     case CKM_BATON_ECB128:
00877     case CKM_BATON_ECB96:
00878     case CKM_BATON_CBC128:
00879     case CKM_BATON_COUNTER:
00880     case CKM_BATON_SHUFFLE:
00881     case CKM_JUNIPER_ECB128:
00882     case CKM_JUNIPER_CBC128:
00883     case CKM_JUNIPER_COUNTER:
00884     case CKM_JUNIPER_SHUFFLE:
00885        if ((iv == NULL) || (iv->data == NULL)) break;
00886        param->data = (unsigned char*)PORT_Alloc(iv->len);
00887        if (param->data != NULL) {
00888            PORT_Memcpy(param->data,iv->data,iv->len);
00889            param->len = iv->len;
00890        }
00891        break;
00892      /* unknown mechanism, pass IV in if it's there */
00893      default:
00894        if (pk11_lookup(type)->iv == 0) {
00895            break;
00896        }
00897        if ((iv == NULL) || (iv->data == NULL)) {
00898            break;
00899        }
00900        param->data = (unsigned char*)PORT_Alloc(iv->len);
00901        if (param->data != NULL) {
00902            PORT_Memcpy(param->data,iv->data,iv->len);
00903            param->len = iv->len;
00904        }
00905        break;
00906      }
00907      return param;
00908 }
00909 
00910 unsigned char *
00911 PK11_IVFromParam(CK_MECHANISM_TYPE type,SECItem *param,int *len)
00912 {
00913     CK_RC2_CBC_PARAMS *rc2_params;
00914     CK_RC5_CBC_PARAMS *rc5_cbc_params;
00915 
00916     *len = 0;
00917     switch (type) {
00918     case CKM_AES_ECB:
00919     case CKM_DES_ECB:
00920     case CKM_DES3_ECB:
00921     case CKM_RSA_PKCS:
00922     case CKM_RSA_X_509:
00923     case CKM_RSA_9796:
00924     case CKM_IDEA_ECB:
00925     case CKM_CDMF_ECB:
00926     case CKM_CAST_ECB:
00927     case CKM_CAST3_ECB:
00928     case CKM_CAST5_ECB:
00929     case CKM_RC4:
00930        return NULL;
00931     case CKM_RC2_ECB:
00932        return NULL;
00933     case CKM_RC2_CBC:
00934     case CKM_RC2_CBC_PAD:
00935        rc2_params = (CK_RC2_CBC_PARAMS *)param->data;
00936         *len = sizeof(rc2_params->iv);
00937        return &rc2_params->iv[0];
00938     case CKM_RC5_CBC:
00939     case CKM_RC5_CBC_PAD:
00940        rc5_cbc_params = (CK_RC5_CBC_PARAMS *) param->data;
00941        *len = rc5_cbc_params->ulIvLen;
00942        return rc5_cbc_params->pIv;
00943     case CKM_AES_CBC:
00944     case CKM_DES_CBC:
00945     case CKM_DES3_CBC:
00946     case CKM_IDEA_CBC:
00947     case CKM_CDMF_CBC:
00948     case CKM_CAST_CBC:
00949     case CKM_CAST3_CBC:
00950     case CKM_CAST5_CBC:
00951     case CKM_DES_CBC_PAD:
00952     case CKM_DES3_CBC_PAD:
00953     case CKM_IDEA_CBC_PAD:
00954     case CKM_CDMF_CBC_PAD:
00955     case CKM_CAST_CBC_PAD:
00956     case CKM_CAST3_CBC_PAD:
00957     case CKM_CAST5_CBC_PAD:
00958     case CKM_SKIPJACK_CBC64:
00959     case CKM_SKIPJACK_ECB64:
00960     case CKM_SKIPJACK_OFB64:
00961     case CKM_SKIPJACK_CFB64:
00962     case CKM_SKIPJACK_CFB32:
00963     case CKM_SKIPJACK_CFB16:
00964     case CKM_SKIPJACK_CFB8:
00965     case CKM_BATON_ECB128:
00966     case CKM_BATON_ECB96:
00967     case CKM_BATON_CBC128:
00968     case CKM_BATON_COUNTER:
00969     case CKM_BATON_SHUFFLE:
00970     case CKM_JUNIPER_ECB128:
00971     case CKM_JUNIPER_CBC128:
00972     case CKM_JUNIPER_COUNTER:
00973     case CKM_JUNIPER_SHUFFLE:
00974        break;
00975      /* unknown mechanism, pass IV in if it's there */
00976      default:
00977        break;
00978      }
00979      if (param->data) {
00980        *len = param->len;
00981      }
00982      return param->data;
00983 }
00984 
00985 typedef struct sec_rc5cbcParameterStr {
00986     SECItem version;
00987     SECItem rounds;
00988     SECItem blockSizeInBits;
00989     SECItem iv;
00990 } sec_rc5cbcParameter;
00991 
00992 static const SEC_ASN1Template sec_rc5ecb_parameter_template[] = {
00993     { SEC_ASN1_SEQUENCE,
00994           0, NULL, sizeof(sec_rc5cbcParameter) },
00995     { SEC_ASN1_INTEGER,
00996           offsetof(sec_rc5cbcParameter,version) },
00997     { SEC_ASN1_INTEGER,
00998           offsetof(sec_rc5cbcParameter,rounds) },
00999     { SEC_ASN1_INTEGER,
01000           offsetof(sec_rc5cbcParameter,blockSizeInBits) },
01001     { 0 }
01002 };
01003 
01004 static const SEC_ASN1Template sec_rc5cbc_parameter_template[] = {
01005     { SEC_ASN1_SEQUENCE,
01006           0, NULL, sizeof(sec_rc5cbcParameter) },
01007     { SEC_ASN1_INTEGER,
01008           offsetof(sec_rc5cbcParameter,version) },
01009     { SEC_ASN1_INTEGER,
01010           offsetof(sec_rc5cbcParameter,rounds) },
01011     { SEC_ASN1_INTEGER,
01012           offsetof(sec_rc5cbcParameter,blockSizeInBits) },
01013     { SEC_ASN1_OCTET_STRING,
01014           offsetof(sec_rc5cbcParameter,iv) },
01015     { 0 }
01016 };
01017 
01018 typedef struct sec_rc2cbcParameterStr {
01019     SECItem rc2ParameterVersion;
01020     SECItem iv;
01021 } sec_rc2cbcParameter;
01022 
01023 static const SEC_ASN1Template sec_rc2cbc_parameter_template[] = {
01024     { SEC_ASN1_SEQUENCE,
01025           0, NULL, sizeof(sec_rc2cbcParameter) },
01026     { SEC_ASN1_INTEGER,
01027           offsetof(sec_rc2cbcParameter,rc2ParameterVersion) },
01028     { SEC_ASN1_OCTET_STRING,
01029           offsetof(sec_rc2cbcParameter,iv) },
01030     { 0 }
01031 };
01032 
01033 static const SEC_ASN1Template sec_rc2ecb_parameter_template[] = {
01034     { SEC_ASN1_SEQUENCE,
01035           0, NULL, sizeof(sec_rc2cbcParameter) },
01036     { SEC_ASN1_INTEGER,
01037           offsetof(sec_rc2cbcParameter,rc2ParameterVersion) },
01038     { 0 }
01039 };
01040 
01041 /* S/MIME picked id values to represent differnt keysizes */
01042 /* I do have a formula, but it ain't pretty, and it only works because you
01043  * can always match three points to a parabola:) */
01044 static unsigned char  rc2_map(SECItem *version)
01045 {
01046     long x;
01047 
01048     x = DER_GetInteger(version);
01049     
01050     switch (x) {
01051         case 58: return 128;
01052         case 120: return 64;
01053         case 160: return 40;
01054     }
01055     return 128; 
01056 }
01057 
01058 static unsigned long  rc2_unmap(unsigned long x)
01059 {
01060     switch (x) {
01061         case 128: return 58;
01062         case 64: return 120;
01063         case 40: return 160;
01064     }
01065     return 58; 
01066 }
01067 
01068 
01069 
01070 /* Generate a mechaism param from a type, and iv. */
01071 SECItem *
01072 PK11_ParamFromAlgid(SECAlgorithmID *algid)
01073 {
01074     CK_RC2_CBC_PARAMS * rc2_cbc_params = NULL;
01075     CK_RC2_PARAMS *     rc2_ecb_params = NULL;
01076     CK_RC5_CBC_PARAMS * rc5_cbc_params = NULL;
01077     CK_RC5_PARAMS *     rc5_ecb_params = NULL;
01078     PRArenaPool *       arena          = NULL;
01079     SECItem *           mech           = NULL;
01080     SECOidTag           algtag;
01081     SECStatus           rv;
01082     CK_MECHANISM_TYPE   type;
01083     /* initialize these to prevent UMRs in the ASN1 decoder. */
01084     SECItem             iv  =   {siBuffer, NULL, 0};
01085     sec_rc2cbcParameter rc2 = { {siBuffer, NULL, 0}, {siBuffer, NULL, 0} };
01086     sec_rc5cbcParameter rc5 = { {siBuffer, NULL, 0}, {siBuffer, NULL, 0},
01087                                 {siBuffer, NULL, 0}, {siBuffer, NULL, 0} };
01088 
01089     algtag = SECOID_GetAlgorithmTag(algid);
01090     type = PK11_AlgtagToMechanism(algtag);
01091 
01092     mech = PORT_New(SECItem);
01093     if (mech == NULL) {
01094        return NULL;
01095     }
01096     mech->type = siBuffer;
01097     mech->data = NULL;
01098     mech->len  = 0;
01099 
01100     arena = PORT_NewArena(1024);
01101     if (!arena) {
01102        goto loser;
01103     }
01104 
01105     /* handle the complicated cases */
01106     switch (type) {
01107     case CKM_RC2_ECB:
01108         rv = SEC_ASN1DecodeItem(arena, &rc2 ,sec_rc2ecb_parameter_template,
01109                                                  &(algid->parameters));
01110        if (rv != SECSuccess) { 
01111            goto loser;
01112        }
01113        rc2_ecb_params = PORT_New(CK_RC2_PARAMS);
01114        if (rc2_ecb_params == NULL) {
01115            goto loser;
01116        }
01117        *rc2_ecb_params = rc2_map(&rc2.rc2ParameterVersion);
01118        mech->data = (unsigned char *) rc2_ecb_params;
01119        mech->len  = sizeof *rc2_ecb_params;
01120        break;
01121     case CKM_RC2_CBC:
01122     case CKM_RC2_CBC_PAD:
01123         rv = SEC_ASN1DecodeItem(arena, &rc2 ,sec_rc2cbc_parameter_template,
01124                                                  &(algid->parameters));
01125        if (rv != SECSuccess) { 
01126            goto loser;
01127        }
01128        rc2_cbc_params = PORT_New(CK_RC2_CBC_PARAMS);
01129        if (rc2_cbc_params == NULL) {
01130            goto loser;
01131        }
01132        mech->data = (unsigned char *) rc2_cbc_params;
01133        mech->len  = sizeof *rc2_cbc_params;
01134        rc2_cbc_params->ulEffectiveBits = rc2_map(&rc2.rc2ParameterVersion);
01135        if (rc2.iv.len != sizeof rc2_cbc_params->iv) {
01136            PORT_SetError(SEC_ERROR_INPUT_LEN);
01137            goto loser;
01138        }
01139        PORT_Memcpy(rc2_cbc_params->iv, rc2.iv.data, rc2.iv.len);
01140        break;
01141     case CKM_RC5_ECB:
01142         rv = SEC_ASN1DecodeItem(arena, &rc5 ,sec_rc5ecb_parameter_template,
01143                                                  &(algid->parameters));
01144        if (rv != SECSuccess) { 
01145            goto loser;
01146        }
01147        rc5_ecb_params = PORT_New(CK_RC5_PARAMS);
01148        if (rc5_ecb_params == NULL) {
01149            goto loser;
01150        }
01151        rc5_ecb_params->ulRounds   = DER_GetInteger(&rc5.rounds);
01152        rc5_ecb_params->ulWordsize = DER_GetInteger(&rc5.blockSizeInBits)/8;
01153        mech->data = (unsigned char *) rc5_ecb_params;
01154        mech->len = sizeof *rc5_ecb_params;
01155        break;
01156     case CKM_RC5_CBC:
01157     case CKM_RC5_CBC_PAD:
01158         rv = SEC_ASN1DecodeItem(arena, &rc5 ,sec_rc5cbc_parameter_template,
01159                                                  &(algid->parameters));
01160        if (rv != SECSuccess) { 
01161            goto loser;
01162        }
01163        rc5_cbc_params = (CK_RC5_CBC_PARAMS *)
01164               PORT_Alloc(sizeof(CK_RC5_CBC_PARAMS) + rc5.iv.len);
01165        if (rc5_cbc_params == NULL) {
01166            goto loser;
01167        }
01168        mech->data = (unsigned char *) rc5_cbc_params;
01169        mech->len = sizeof *rc5_cbc_params;
01170        rc5_cbc_params->ulRounds   = DER_GetInteger(&rc5.rounds);
01171        rc5_cbc_params->ulWordsize = DER_GetInteger(&rc5.blockSizeInBits)/8;
01172         rc5_cbc_params->pIv        = ((CK_BYTE_PTR)rc5_cbc_params)
01173                                           + sizeof(CK_RC5_CBC_PARAMS);
01174         rc5_cbc_params->ulIvLen    = rc5.iv.len;
01175        PORT_Memcpy(rc5_cbc_params->pIv, rc5.iv.data, rc5.iv.len);
01176        break;
01177     case CKM_PBE_MD2_DES_CBC:
01178     case CKM_PBE_MD5_DES_CBC:
01179     case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
01180     case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
01181     case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
01182     case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
01183     case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
01184     case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
01185     case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
01186     case CKM_PBE_SHA1_DES2_EDE_CBC:
01187     case CKM_PBE_SHA1_DES3_EDE_CBC:
01188     case CKM_PBE_SHA1_RC2_40_CBC:
01189     case CKM_PBE_SHA1_RC2_128_CBC:
01190     case CKM_PBE_SHA1_RC4_40:
01191     case CKM_PBE_SHA1_RC4_128:
01192        rv = pbe_PK11AlgidToParam(algid,mech);
01193        if (rv != SECSuccess) {
01194            goto loser;
01195        }
01196        break;
01197     case CKM_RC4:
01198     case CKM_AES_ECB:
01199     case CKM_DES_ECB:
01200     case CKM_DES3_ECB:
01201     case CKM_IDEA_ECB:
01202     case CKM_CDMF_ECB:
01203     case CKM_CAST_ECB:
01204     case CKM_CAST3_ECB:
01205     case CKM_CAST5_ECB:
01206        break;
01207 
01208     default:
01209        if (pk11_lookup(type)->iv == 0) {
01210            break;
01211        }
01212        /* FALL THROUGH */
01213     case CKM_AES_CBC:
01214     case CKM_DES_CBC:
01215     case CKM_DES3_CBC:
01216     case CKM_IDEA_CBC:
01217     case CKM_CDMF_CBC:
01218     case CKM_CAST_CBC:
01219     case CKM_CAST3_CBC:
01220     case CKM_CAST5_CBC:
01221     case CKM_AES_CBC_PAD:
01222     case CKM_DES_CBC_PAD:
01223     case CKM_DES3_CBC_PAD:
01224     case CKM_IDEA_CBC_PAD:
01225     case CKM_CDMF_CBC_PAD:
01226     case CKM_CAST_CBC_PAD:
01227     case CKM_CAST3_CBC_PAD:
01228     case CKM_CAST5_CBC_PAD:
01229     case CKM_SKIPJACK_CBC64:
01230     case CKM_SKIPJACK_ECB64:
01231     case CKM_SKIPJACK_OFB64:
01232     case CKM_SKIPJACK_CFB64:
01233     case CKM_SKIPJACK_CFB32:
01234     case CKM_SKIPJACK_CFB16:
01235     case CKM_SKIPJACK_CFB8:
01236     case CKM_BATON_ECB128:
01237     case CKM_BATON_ECB96:
01238     case CKM_BATON_CBC128:
01239     case CKM_BATON_COUNTER:
01240     case CKM_BATON_SHUFFLE:
01241     case CKM_JUNIPER_ECB128:
01242     case CKM_JUNIPER_CBC128:
01243     case CKM_JUNIPER_COUNTER:
01244     case CKM_JUNIPER_SHUFFLE:
01245        /* simple cases are simply octet string encoded IVs */
01246        rv = SEC_ASN1DecodeItem(arena, &iv, SEC_OctetStringTemplate, 
01247                                        &(algid->parameters));
01248        if (rv != SECSuccess || iv.data == NULL) {
01249            goto loser;
01250        }
01251        /* XXX Should be some IV length sanity check here. */
01252        mech->data = (unsigned char*)PORT_Alloc(iv.len);
01253        if (mech->data == NULL) {
01254            goto loser;
01255        }
01256        PORT_Memcpy(mech->data, iv.data, iv.len);
01257        mech->len = iv.len;
01258        break;
01259     }
01260     PORT_FreeArena(arena, PR_FALSE);
01261     return mech;
01262 
01263 loser:
01264     if (arena)
01265        PORT_FreeArena(arena, PR_FALSE);
01266     SECITEM_FreeItem(mech,PR_TRUE);
01267     return NULL;
01268 }
01269 
01270 /*
01271  * Generate an IV for the given mechanism 
01272  */
01273 static SECStatus
01274 pk11_GenIV(CK_MECHANISM_TYPE type, SECItem *iv) {
01275     int iv_size = PK11_GetIVLength(type);
01276     SECStatus rv;
01277 
01278     iv->len = iv_size;
01279     if (iv_size == 0) { 
01280        iv->data = NULL;
01281        return SECSuccess;
01282     }
01283 
01284     iv->data = (unsigned char *) PORT_Alloc(iv_size);
01285     if (iv->data == NULL) {
01286        iv->len = 0;
01287        return SECFailure;
01288     }
01289 
01290     rv = PK11_GenerateRandom(iv->data,iv->len);
01291     if (rv != SECSuccess) {
01292        PORT_Free(iv->data);
01293        iv->data = NULL; iv->len = 0;
01294        return SECFailure;
01295     }
01296     return SECSuccess;
01297 }
01298 
01299 
01300 /*
01301  * create a new paramter block from the passed in MECHANISM and the
01302  * key. Use Netscape's S/MIME Rules for the New param block.
01303  */
01304 SECItem *
01305 PK11_GenerateNewParam(CK_MECHANISM_TYPE type, PK11SymKey *key) { 
01306     CK_RC2_CBC_PARAMS *rc2_params;
01307     CK_RC2_PARAMS *rc2_ecb_params;
01308     SECItem *mech;
01309     SECItem iv;
01310     SECStatus rv;
01311 
01312 
01313     mech = (SECItem *) PORT_Alloc(sizeof(SECItem));
01314     if (mech == NULL) return NULL;
01315 
01316     rv = SECSuccess;
01317     mech->type = siBuffer;
01318     switch (type) {
01319     case CKM_RC4:
01320     case CKM_AES_ECB:
01321     case CKM_DES_ECB:
01322     case CKM_DES3_ECB:
01323     case CKM_IDEA_ECB:
01324     case CKM_CDMF_ECB:
01325     case CKM_CAST_ECB:
01326     case CKM_CAST3_ECB:
01327     case CKM_CAST5_ECB:
01328        mech->data = NULL;
01329        mech->len = 0;
01330        break;
01331     case CKM_RC2_ECB:
01332        rc2_ecb_params = (CK_RC2_PARAMS *)PORT_Alloc(sizeof(CK_RC2_PARAMS));
01333        if (rc2_ecb_params == NULL) {
01334            rv = SECFailure;
01335            break;
01336        }
01337        /* NOTE PK11_GetKeyLength can return -1 if the key isn't and RC2, RC5,
01338         *   or RC4 key. Of course that wouldn't happen here doing RC2:).*/
01339        *rc2_ecb_params = PK11_GetKeyLength(key)*8;
01340        mech->data = (unsigned char *) rc2_ecb_params;
01341        mech->len = sizeof(CK_RC2_PARAMS);
01342        break;
01343     case CKM_RC2_CBC:
01344     case CKM_RC2_CBC_PAD:
01345        rv = pk11_GenIV(type,&iv);
01346        if (rv != SECSuccess) {
01347            break;
01348        }
01349        rc2_params = (CK_RC2_CBC_PARAMS *)PORT_Alloc(sizeof(CK_RC2_CBC_PARAMS));
01350        if (rc2_params == NULL) {
01351            PORT_Free(iv.data);
01352            rv = SECFailure;
01353            break;
01354        }
01355        /* NOTE PK11_GetKeyLength can return -1 if the key isn't and RC2, RC5,
01356         *   or RC4 key. Of course that wouldn't happen here doing RC2:).*/
01357        rc2_params->ulEffectiveBits = PK11_GetKeyLength(key)*8;
01358        if (iv.data)
01359            PORT_Memcpy(rc2_params->iv,iv.data,sizeof(rc2_params->iv));
01360        mech->data = (unsigned char *) rc2_params;
01361        mech->len = sizeof(CK_RC2_CBC_PARAMS);
01362        PORT_Free(iv.data);
01363        break;
01364     case CKM_RC5_ECB:
01365         PORT_Free(mech);
01366        return PK11_ParamFromIV(type,NULL);
01367     case CKM_RC5_CBC:
01368     case CKM_RC5_CBC_PAD:
01369        rv = pk11_GenIV(type,&iv);
01370        if (rv != SECSuccess) {
01371            break;
01372        }
01373         PORT_Free(mech);
01374        return PK11_ParamFromIV(type,&iv);
01375     default:
01376        if (pk11_lookup(type)->iv == 0) {
01377            mech->data = NULL;
01378            mech->len = 0;
01379            break;
01380        }
01381     case CKM_AES_CBC:
01382     case CKM_DES_CBC:
01383     case CKM_DES3_CBC:
01384     case CKM_IDEA_CBC:
01385     case CKM_CDMF_CBC:
01386     case CKM_CAST_CBC:
01387     case CKM_CAST3_CBC:
01388     case CKM_CAST5_CBC:
01389     case CKM_DES_CBC_PAD:
01390     case CKM_DES3_CBC_PAD:
01391     case CKM_IDEA_CBC_PAD:
01392     case CKM_CDMF_CBC_PAD:
01393     case CKM_CAST_CBC_PAD:
01394     case CKM_CAST3_CBC_PAD:
01395     case CKM_CAST5_CBC_PAD:
01396     case CKM_SKIPJACK_CBC64:
01397     case CKM_SKIPJACK_ECB64:
01398     case CKM_SKIPJACK_OFB64:
01399     case CKM_SKIPJACK_CFB64:
01400     case CKM_SKIPJACK_CFB32:
01401     case CKM_SKIPJACK_CFB16:
01402     case CKM_SKIPJACK_CFB8:
01403     case CKM_BATON_ECB128:
01404     case CKM_BATON_ECB96:
01405     case CKM_BATON_CBC128:
01406     case CKM_BATON_COUNTER:
01407     case CKM_BATON_SHUFFLE:
01408     case CKM_JUNIPER_ECB128:
01409     case CKM_JUNIPER_CBC128:
01410     case CKM_JUNIPER_COUNTER:
01411     case CKM_JUNIPER_SHUFFLE:
01412        rv = pk11_GenIV(type,&iv);
01413        if (rv != SECSuccess) {
01414            break;
01415        }
01416        mech->data = (unsigned char*)PORT_Alloc(iv.len);
01417        if (mech->data == NULL) {
01418            PORT_Free(iv.data);
01419            rv = SECFailure;
01420            break;
01421        }
01422        PORT_Memcpy(mech->data,iv.data,iv.len);
01423        mech->len = iv.len;
01424         PORT_Free(iv.data);
01425        break;
01426     }
01427     if (rv !=  SECSuccess) {
01428        SECITEM_FreeItem(mech,PR_TRUE);
01429        return NULL;
01430     }
01431     return mech;
01432 
01433 }
01434 
01435 #define RC5_V10 0x10
01436 
01437 /* turn a PKCS #11 parameter into a DER Encoded Algorithm ID */
01438 SECStatus
01439 PK11_ParamToAlgid(SECOidTag algTag, SECItem *param, 
01440                             PRArenaPool *arena, SECAlgorithmID *algid) {
01441     CK_RC2_CBC_PARAMS *rc2_params;
01442     sec_rc2cbcParameter rc2;
01443     CK_RC5_CBC_PARAMS *rc5_params;
01444     sec_rc5cbcParameter rc5;
01445     CK_MECHANISM_TYPE type = PK11_AlgtagToMechanism(algTag);
01446     SECItem *newParams = NULL;
01447     SECStatus rv = SECFailure;
01448     unsigned long rc2version;
01449 
01450     rv = SECSuccess;
01451     switch (type) {
01452     case CKM_RC4:
01453     case CKM_AES_ECB:
01454     case CKM_DES_ECB:
01455     case CKM_DES3_ECB:
01456     case CKM_IDEA_ECB:
01457     case CKM_CDMF_ECB:
01458     case CKM_CAST_ECB:
01459     case CKM_CAST3_ECB:
01460     case CKM_CAST5_ECB:
01461        newParams = NULL;
01462        rv = SECSuccess;
01463        break;
01464     case CKM_RC2_ECB:
01465        break;
01466     case CKM_RC2_CBC:
01467     case CKM_RC2_CBC_PAD:
01468        rc2_params = (CK_RC2_CBC_PARAMS *)param->data;
01469        rc2version = rc2_unmap(rc2_params->ulEffectiveBits);
01470        if (SEC_ASN1EncodeUnsignedInteger (NULL, &(rc2.rc2ParameterVersion),
01471                                       rc2version) == NULL)
01472            break;
01473        rc2.iv.data = rc2_params->iv;
01474        rc2.iv.len = sizeof(rc2_params->iv);
01475        newParams = SEC_ASN1EncodeItem (NULL, NULL, &rc2,
01476                                          sec_rc2cbc_parameter_template);
01477         PORT_Free(rc2.rc2ParameterVersion.data);
01478        if (newParams == NULL)
01479            break;
01480        rv = SECSuccess;
01481        break;
01482 
01483     case CKM_RC5_ECB: /* well not really... */
01484        break;
01485     case CKM_RC5_CBC:
01486     case CKM_RC5_CBC_PAD:
01487        rc5_params = (CK_RC5_CBC_PARAMS *)param->data;
01488        if (SEC_ASN1EncodeUnsignedInteger (NULL, &rc5.version, RC5_V10) == NULL)
01489            break;
01490        if (SEC_ASN1EncodeUnsignedInteger (NULL, &rc5.blockSizeInBits, 
01491                                    rc5_params->ulWordsize*8) == NULL) {
01492             PORT_Free(rc5.version.data);
01493            break;
01494        }
01495        if (SEC_ASN1EncodeUnsignedInteger (NULL, &rc5.rounds, 
01496                                    rc5_params->ulWordsize*8) == NULL) {
01497             PORT_Free(rc5.blockSizeInBits.data);
01498             PORT_Free(rc5.version.data);
01499            break;
01500        }
01501        rc5.iv.data = rc5_params->pIv;
01502        rc5.iv.len = rc5_params->ulIvLen;
01503        newParams = SEC_ASN1EncodeItem (NULL, NULL, &rc5,
01504                                          sec_rc5cbc_parameter_template);
01505         PORT_Free(rc5.version.data);
01506         PORT_Free(rc5.blockSizeInBits.data);
01507         PORT_Free(rc5.rounds.data);
01508        if (newParams == NULL)
01509            break;
01510        rv = SECSuccess;
01511        break;
01512     case CKM_PBE_MD2_DES_CBC:
01513     case CKM_PBE_MD5_DES_CBC:
01514     case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
01515     case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
01516     case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
01517     case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
01518     case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
01519     case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
01520     case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
01521     case CKM_PBE_SHA1_DES3_EDE_CBC:
01522     case CKM_PBE_SHA1_DES2_EDE_CBC:
01523     case CKM_PBE_SHA1_RC2_40_CBC:
01524     case CKM_PBE_SHA1_RC2_128_CBC:
01525     case CKM_PBE_SHA1_RC4_40:
01526     case CKM_PBE_SHA1_RC4_128:
01527        return PBE_PK11ParamToAlgid(algTag, param, arena, algid);
01528     default:
01529        if (pk11_lookup(type)->iv == 0) {
01530            rv = SECSuccess;
01531            newParams = NULL;
01532            break;
01533        }
01534     case CKM_AES_CBC:
01535     case CKM_DES_CBC:
01536     case CKM_DES3_CBC:
01537     case CKM_IDEA_CBC:
01538     case CKM_CDMF_CBC:
01539     case CKM_CAST_CBC:
01540     case CKM_CAST3_CBC:
01541     case CKM_CAST5_CBC:
01542     case CKM_DES_CBC_PAD:
01543     case CKM_DES3_CBC_PAD:
01544     case CKM_IDEA_CBC_PAD:
01545     case CKM_CDMF_CBC_PAD:
01546     case CKM_CAST_CBC_PAD:
01547     case CKM_CAST3_CBC_PAD:
01548     case CKM_CAST5_CBC_PAD:
01549     case CKM_SKIPJACK_CBC64:
01550     case CKM_SKIPJACK_ECB64:
01551     case CKM_SKIPJACK_OFB64:
01552     case CKM_SKIPJACK_CFB64:
01553     case CKM_SKIPJACK_CFB32:
01554     case CKM_SKIPJACK_CFB16:
01555     case CKM_SKIPJACK_CFB8:
01556     case CKM_BATON_ECB128:
01557     case CKM_BATON_ECB96:
01558     case CKM_BATON_CBC128:
01559     case CKM_BATON_COUNTER:
01560     case CKM_BATON_SHUFFLE:
01561     case CKM_JUNIPER_ECB128:
01562     case CKM_JUNIPER_CBC128:
01563     case CKM_JUNIPER_COUNTER:
01564     case CKM_JUNIPER_SHUFFLE:
01565        newParams = SEC_ASN1EncodeItem(NULL,NULL,param,
01566                                           SEC_OctetStringTemplate);
01567        rv = SECSuccess;
01568        break;
01569     }
01570 
01571     if (rv !=  SECSuccess) {
01572        if (newParams) SECITEM_FreeItem(newParams,PR_TRUE);
01573        return rv;
01574     }
01575 
01576     rv = SECOID_SetAlgorithmID(arena, algid, algTag, newParams);
01577     SECITEM_FreeItem(newParams,PR_TRUE);
01578     return rv;
01579 }
01580 
01581 /* turn an OID algorithm tag into a PKCS #11 mechanism. This allows us to
01582  * map OID's directly into the PKCS #11 mechanism we want to call. We find
01583  * this mapping in our standard OID table */
01584 CK_MECHANISM_TYPE
01585 PK11_AlgtagToMechanism(SECOidTag algTag) {
01586     SECOidData *oid = SECOID_FindOIDByTag(algTag);
01587 
01588     if (oid) return (CK_MECHANISM_TYPE) oid->mechanism;
01589     return CKM_INVALID_MECHANISM;
01590 }
01591 
01592 /* turn a mechanism into an oid. */
01593 SECOidTag
01594 PK11_MechanismToAlgtag(CK_MECHANISM_TYPE type) {
01595     SECOidData *oid = SECOID_FindOIDByMechanism((unsigned long)type);
01596 
01597     if (oid) return oid->offset;
01598     return SEC_OID_UNKNOWN;
01599 }
01600 
01601 /* Determine appropriate blocking mechanism, used when wrapping private keys
01602  * which require PKCS padding.  If the mechanism does not map to a padding
01603  * mechanism, we simply return the mechanism.
01604  */
01605 CK_MECHANISM_TYPE
01606 PK11_GetPadMechanism(CK_MECHANISM_TYPE type) {
01607     switch(type) {
01608        case CKM_AES_CBC:
01609            return CKM_AES_CBC_PAD;
01610        case CKM_DES_CBC:
01611            return CKM_DES_CBC_PAD;
01612        case CKM_DES3_CBC:
01613            return CKM_DES3_CBC_PAD;
01614        case CKM_RC2_CBC:
01615            return CKM_RC2_CBC_PAD;
01616        case CKM_CDMF_CBC:
01617            return CKM_CDMF_CBC_PAD;
01618        case CKM_CAST_CBC:
01619            return CKM_CAST_CBC_PAD;
01620        case CKM_CAST3_CBC:
01621            return CKM_CAST3_CBC_PAD;
01622        case CKM_CAST5_CBC:
01623            return CKM_CAST5_CBC_PAD;
01624        case CKM_RC5_CBC:
01625            return CKM_RC5_CBC_PAD; 
01626        case CKM_IDEA_CBC:
01627            return CKM_IDEA_CBC_PAD; 
01628        default:
01629            break;
01630     }
01631 
01632     return type;
01633 }
01634            
01635 static PRBool
01636 pk11_isAllZero(unsigned char *data,int len) {
01637     while (len--) {
01638        if (*data++) {
01639            return PR_FALSE;
01640        }
01641     }
01642     return PR_TRUE;
01643 }
01644 
01645 CK_RV
01646 PK11_MapPBEMechanismToCryptoMechanism(CK_MECHANISM_PTR pPBEMechanism, 
01647                                   CK_MECHANISM_PTR pCryptoMechanism,
01648                                   SECItem *pbe_pwd, PRBool faulty3DES)
01649 {
01650     int iv_len = 0;
01651     CK_PBE_PARAMS_PTR pPBEparams;
01652     CK_RC2_CBC_PARAMS_PTR rc2_params;
01653     CK_ULONG rc2_key_len;
01654 
01655     if((pPBEMechanism == CK_NULL_PTR) || (pCryptoMechanism == CK_NULL_PTR)) {
01656        return CKR_HOST_MEMORY;
01657     }
01658 
01659     pPBEparams = (CK_PBE_PARAMS_PTR)pPBEMechanism->pParameter;
01660     iv_len = PK11_GetIVLength(pPBEMechanism->mechanism);
01661 
01662     if (iv_len) {
01663        if (pk11_isAllZero(pPBEparams->pInitVector,iv_len)) {
01664            SECItem param;
01665            PK11SymKey *symKey;
01666            PK11SlotInfo *intSlot = PK11_GetInternalSlot();
01667 
01668            if (intSlot == NULL) {
01669               return CKR_DEVICE_ERROR;
01670            }
01671 
01672            param.data = pPBEMechanism->pParameter;
01673            param.len = pPBEMechanism->ulParameterLen;
01674 
01675            symKey = PK11_RawPBEKeyGen(intSlot,
01676               pPBEMechanism->mechanism, &param, pbe_pwd, faulty3DES, NULL);
01677            PK11_FreeSlot(intSlot);
01678            if (symKey== NULL) {
01679               return CKR_DEVICE_ERROR; /* sigh */
01680            }
01681            PK11_FreeSymKey(symKey);
01682        }
01683     }
01684 
01685     switch(pPBEMechanism->mechanism) {
01686        case CKM_PBE_MD2_DES_CBC:
01687        case CKM_PBE_MD5_DES_CBC:
01688        case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
01689            pCryptoMechanism->mechanism = CKM_DES_CBC;
01690            goto have_crypto_mechanism;
01691        case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
01692        case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
01693        case CKM_PBE_SHA1_DES3_EDE_CBC:
01694        case CKM_PBE_SHA1_DES2_EDE_CBC:
01695            pCryptoMechanism->mechanism = CKM_DES3_CBC;
01696 have_crypto_mechanism:
01697            pCryptoMechanism->pParameter = PORT_Alloc(iv_len);
01698            pCryptoMechanism->ulParameterLen = (CK_ULONG)iv_len;
01699            if(pCryptoMechanism->pParameter == NULL) {
01700               return CKR_HOST_MEMORY;
01701            }
01702            PORT_Memcpy((unsigned char *)(pCryptoMechanism->pParameter),
01703                      (unsigned char *)(pPBEparams->pInitVector),
01704                      iv_len);
01705            break;
01706        case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
01707        case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
01708        case CKM_PBE_SHA1_RC4_40:
01709        case CKM_PBE_SHA1_RC4_128:
01710            pCryptoMechanism->mechanism = CKM_RC4;
01711            pCryptoMechanism->ulParameterLen = 0;
01712            pCryptoMechanism->pParameter = CK_NULL_PTR;
01713            break;
01714        case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
01715        case CKM_PBE_SHA1_RC2_40_CBC:
01716            rc2_key_len = 40;
01717            goto have_key_len;
01718        case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
01719            rc2_key_len = 128;
01720 have_key_len:
01721            pCryptoMechanism->mechanism = CKM_RC2_CBC;
01722            pCryptoMechanism->ulParameterLen = (CK_ULONG)
01723                                           sizeof(CK_RC2_CBC_PARAMS);
01724            pCryptoMechanism->pParameter = (CK_RC2_CBC_PARAMS_PTR)
01725                             PORT_ZAlloc(sizeof(CK_RC2_CBC_PARAMS));
01726            if(pCryptoMechanism->pParameter == NULL) {
01727               return CKR_HOST_MEMORY;
01728            }
01729            rc2_params = (CK_RC2_CBC_PARAMS_PTR)pCryptoMechanism->pParameter;
01730            PORT_Memcpy((unsigned char *)rc2_params->iv,
01731                      (unsigned char *)pPBEparams->pInitVector,
01732                      iv_len);
01733            rc2_params->ulEffectiveBits = rc2_key_len;
01734            break;
01735        default:
01736            return CKR_MECHANISM_INVALID;
01737     }
01738 
01739     return CKR_OK;
01740 }
01741 
01742 /* Make a Key type to an appropriate signing/verification mechanism */
01743 CK_MECHANISM_TYPE
01744 PK11_MapSignKeyType(KeyType keyType)
01745 {
01746     switch (keyType) {
01747     case rsaKey:
01748        return CKM_RSA_PKCS;
01749     case fortezzaKey:
01750     case dsaKey:
01751        return CKM_DSA;
01752     case ecKey:
01753        return CKM_ECDSA;
01754     case dhKey:
01755     default:
01756        break;
01757     }
01758     return CKM_INVALID_MECHANISM;
01759 }
01760 
01761 CK_MECHANISM_TYPE
01762 pk11_mapWrapKeyType(KeyType keyType)
01763 {
01764     switch (keyType) {
01765     case rsaKey:
01766        return CKM_RSA_PKCS;
01767     /* Add fortezza?? */
01768     default:
01769        break;
01770     }
01771     return CKM_INVALID_MECHANISM;
01772 }
01773 
01774 SECOidTag 
01775 PK11_FortezzaMapSig(SECOidTag algTag)
01776 {
01777     switch (algTag) {
01778     case SEC_OID_MISSI_KEA_DSS:
01779     case SEC_OID_MISSI_DSS:
01780     case SEC_OID_MISSI_DSS_OLD:
01781     case SEC_OID_MISSI_KEA_DSS_OLD:
01782     case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST:
01783        return SEC_OID_ANSIX9_DSA_SIGNATURE;
01784     default:
01785        break;
01786     }
01787     return algTag;
01788 }