security/nss/lib/pk11wrap/pk11mech.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial