1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/pk11wrap/pk11mech.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1886 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 +/* 1.8 + * This file maps various PKCS #11 Mechanisms to related mechanisms, key 1.9 + * types, and ASN.1 encodings. 1.10 + */ 1.11 +#include "seccomon.h" 1.12 +#include "secmod.h" 1.13 +#include "secmodi.h" 1.14 +#include "pkcs11t.h" 1.15 +#include "pk11func.h" 1.16 +#include "secitem.h" 1.17 +#include "secder.h" 1.18 +#include "secasn1.h" 1.19 +#include "secoid.h" 1.20 +#include "secerr.h" 1.21 + 1.22 +/************************************************************* 1.23 + * local static and global data 1.24 + *************************************************************/ 1.25 + 1.26 +/* 1.27 + * Tables used for Extended mechanism mapping (currently not used) 1.28 + */ 1.29 +typedef struct { 1.30 + CK_MECHANISM_TYPE keyGen; 1.31 + CK_KEY_TYPE keyType; 1.32 + CK_MECHANISM_TYPE type; 1.33 + CK_MECHANISM_TYPE padType; 1.34 + int blockSize; 1.35 + int iv; 1.36 +} pk11MechanismData; 1.37 + 1.38 +static pk11MechanismData pk11_default = 1.39 + { CKM_GENERIC_SECRET_KEY_GEN, CKK_GENERIC_SECRET, 1.40 + CKM_FAKE_RANDOM, CKM_FAKE_RANDOM, 8, 8 }; 1.41 +static pk11MechanismData *pk11_MechanismTable = NULL; 1.42 +static int pk11_MechTableSize = 0; 1.43 +static int pk11_MechEntrySize = 0; 1.44 + 1.45 +/* 1.46 + * list of mechanisms we're willing to wrap secret keys with. 1.47 + * This list is ordered by preference. 1.48 + */ 1.49 +CK_MECHANISM_TYPE wrapMechanismList[] = { 1.50 + CKM_DES3_ECB, 1.51 + CKM_CAST5_ECB, 1.52 + CKM_AES_ECB, 1.53 + CKM_CAMELLIA_ECB, 1.54 + CKM_SEED_ECB, 1.55 + CKM_CAST5_ECB, 1.56 + CKM_DES_ECB, 1.57 + CKM_KEY_WRAP_LYNKS, 1.58 + CKM_IDEA_ECB, 1.59 + CKM_CAST3_ECB, 1.60 + CKM_CAST_ECB, 1.61 + CKM_RC5_ECB, 1.62 + CKM_RC2_ECB, 1.63 + CKM_CDMF_ECB, 1.64 + CKM_SKIPJACK_WRAP, 1.65 +}; 1.66 + 1.67 +int wrapMechanismCount = sizeof(wrapMechanismList)/sizeof(wrapMechanismList[0]); 1.68 + 1.69 +/********************************************************************* 1.70 + * Mechanism Mapping functions 1.71 + *********************************************************************/ 1.72 + 1.73 +/* 1.74 + * lookup an entry in the mechanism table. If none found, return the 1.75 + * default structure. 1.76 + */ 1.77 +static pk11MechanismData * 1.78 +pk11_lookup(CK_MECHANISM_TYPE type) 1.79 +{ 1.80 + int i; 1.81 + for (i=0; i < pk11_MechEntrySize; i++) { 1.82 + if (pk11_MechanismTable[i].type == type) { 1.83 + return (&pk11_MechanismTable[i]); 1.84 + } 1.85 + } 1.86 + return &pk11_default; 1.87 +} 1.88 + 1.89 +/* 1.90 + * find the best key wrap mechanism for this slot. 1.91 + */ 1.92 +CK_MECHANISM_TYPE 1.93 +PK11_GetBestWrapMechanism(PK11SlotInfo *slot) 1.94 +{ 1.95 + int i; 1.96 + for (i=0; i < wrapMechanismCount; i++) { 1.97 + if (PK11_DoesMechanism(slot,wrapMechanismList[i])) { 1.98 + return wrapMechanismList[i]; 1.99 + } 1.100 + } 1.101 + return CKM_INVALID_MECHANISM; 1.102 +} 1.103 + 1.104 +/* 1.105 + * NOTE: This is not thread safe. Called at init time, and when loading 1.106 + * a new Entry. It is reasonably safe as long as it is not re-entered 1.107 + * (readers will always see a consistant table) 1.108 + * 1.109 + * This routine is called to add entries to the mechanism table, once there, 1.110 + * they can not be removed. 1.111 + */ 1.112 +void 1.113 +PK11_AddMechanismEntry(CK_MECHANISM_TYPE type, CK_KEY_TYPE key, 1.114 + CK_MECHANISM_TYPE keyGen, 1.115 + CK_MECHANISM_TYPE padType, 1.116 + int ivLen, int blockSize) 1.117 +{ 1.118 + int tableSize = pk11_MechTableSize; 1.119 + int size = pk11_MechEntrySize; 1.120 + int entry = size++; 1.121 + pk11MechanismData *old = pk11_MechanismTable; 1.122 + pk11MechanismData *newt = pk11_MechanismTable; 1.123 + 1.124 + 1.125 + if (size > tableSize) { 1.126 + int oldTableSize = tableSize; 1.127 + tableSize += 10; 1.128 + newt = PORT_NewArray(pk11MechanismData, tableSize); 1.129 + if (newt == NULL) return; 1.130 + 1.131 + if (old) PORT_Memcpy(newt, old, oldTableSize*sizeof(*newt)); 1.132 + } else old = NULL; 1.133 + 1.134 + newt[entry].type = type; 1.135 + newt[entry].keyType = key; 1.136 + newt[entry].keyGen = keyGen; 1.137 + newt[entry].padType = padType; 1.138 + newt[entry].iv = ivLen; 1.139 + newt[entry].blockSize = blockSize; 1.140 + 1.141 + pk11_MechanismTable = newt; 1.142 + pk11_MechTableSize = tableSize; 1.143 + pk11_MechEntrySize = size; 1.144 + if (old) PORT_Free(old); 1.145 +} 1.146 + 1.147 +/* 1.148 + * Get the mechanism needed for the given key type 1.149 + */ 1.150 +CK_MECHANISM_TYPE 1.151 +PK11_GetKeyMechanism(CK_KEY_TYPE type) 1.152 +{ 1.153 + switch (type) { 1.154 + case CKK_SEED: 1.155 + return CKM_SEED_CBC; 1.156 + case CKK_CAMELLIA: 1.157 + return CKM_CAMELLIA_CBC; 1.158 + case CKK_AES: 1.159 + return CKM_AES_CBC; 1.160 + case CKK_DES: 1.161 + return CKM_DES_CBC; 1.162 + case CKK_DES3: 1.163 + return CKM_DES3_KEY_GEN; 1.164 + case CKK_DES2: 1.165 + return CKM_DES2_KEY_GEN; 1.166 + case CKK_CDMF: 1.167 + return CKM_CDMF_CBC; 1.168 + case CKK_RC2: 1.169 + return CKM_RC2_CBC; 1.170 + case CKK_RC4: 1.171 + return CKM_RC4; 1.172 + case CKK_RC5: 1.173 + return CKM_RC5_CBC; 1.174 + case CKK_SKIPJACK: 1.175 + return CKM_SKIPJACK_CBC64; 1.176 + case CKK_BATON: 1.177 + return CKM_BATON_CBC128; 1.178 + case CKK_JUNIPER: 1.179 + return CKM_JUNIPER_CBC128; 1.180 + case CKK_IDEA: 1.181 + return CKM_IDEA_CBC; 1.182 + case CKK_CAST: 1.183 + return CKM_CAST_CBC; 1.184 + case CKK_CAST3: 1.185 + return CKM_CAST3_CBC; 1.186 + case CKK_CAST5: 1.187 + return CKM_CAST5_CBC; 1.188 + case CKK_RSA: 1.189 + return CKM_RSA_PKCS; 1.190 + case CKK_DSA: 1.191 + return CKM_DSA; 1.192 + case CKK_DH: 1.193 + return CKM_DH_PKCS_DERIVE; 1.194 + case CKK_KEA: 1.195 + return CKM_KEA_KEY_DERIVE; 1.196 + case CKK_EC: /* CKK_ECDSA is deprecated */ 1.197 + return CKM_ECDSA; 1.198 + case CKK_GENERIC_SECRET: 1.199 + default: 1.200 + return CKM_SHA_1_HMAC; 1.201 + } 1.202 +} 1.203 + 1.204 +/* 1.205 + * Get the key type needed for the given mechanism 1.206 + */ 1.207 +CK_KEY_TYPE 1.208 +PK11_GetKeyType(CK_MECHANISM_TYPE type,unsigned long len) 1.209 +{ 1.210 + switch (type) { 1.211 + case CKM_SEED_ECB: 1.212 + case CKM_SEED_CBC: 1.213 + case CKM_SEED_MAC: 1.214 + case CKM_SEED_MAC_GENERAL: 1.215 + case CKM_SEED_CBC_PAD: 1.216 + case CKM_SEED_KEY_GEN: 1.217 + return CKK_SEED; 1.218 + case CKM_CAMELLIA_ECB: 1.219 + case CKM_CAMELLIA_CBC: 1.220 + case CKM_CAMELLIA_MAC: 1.221 + case CKM_CAMELLIA_MAC_GENERAL: 1.222 + case CKM_CAMELLIA_CBC_PAD: 1.223 + case CKM_CAMELLIA_KEY_GEN: 1.224 + return CKK_CAMELLIA; 1.225 + case CKM_AES_ECB: 1.226 + case CKM_AES_CBC: 1.227 + case CKM_AES_CCM: 1.228 + case CKM_AES_CTR: 1.229 + case CKM_AES_CTS: 1.230 + case CKM_AES_GCM: 1.231 + case CKM_AES_MAC: 1.232 + case CKM_AES_MAC_GENERAL: 1.233 + case CKM_AES_CBC_PAD: 1.234 + case CKM_AES_KEY_GEN: 1.235 + case CKM_NETSCAPE_AES_KEY_WRAP: 1.236 + case CKM_NETSCAPE_AES_KEY_WRAP_PAD: 1.237 + return CKK_AES; 1.238 + case CKM_DES_ECB: 1.239 + case CKM_DES_CBC: 1.240 + case CKM_DES_MAC: 1.241 + case CKM_DES_MAC_GENERAL: 1.242 + case CKM_DES_CBC_PAD: 1.243 + case CKM_DES_KEY_GEN: 1.244 + case CKM_KEY_WRAP_LYNKS: 1.245 + case CKM_PBE_MD2_DES_CBC: 1.246 + case CKM_PBE_MD5_DES_CBC: 1.247 + return CKK_DES; 1.248 + case CKM_DES3_ECB: 1.249 + case CKM_DES3_CBC: 1.250 + case CKM_DES3_MAC: 1.251 + case CKM_DES3_MAC_GENERAL: 1.252 + case CKM_DES3_CBC_PAD: 1.253 + return (len == 16) ? CKK_DES2 : CKK_DES3; 1.254 + case CKM_DES2_KEY_GEN: 1.255 + case CKM_PBE_SHA1_DES2_EDE_CBC: 1.256 + return CKK_DES2; 1.257 + case CKM_PBE_SHA1_DES3_EDE_CBC: 1.258 + case CKM_DES3_KEY_GEN: 1.259 + return CKK_DES3; 1.260 + case CKM_CDMF_ECB: 1.261 + case CKM_CDMF_CBC: 1.262 + case CKM_CDMF_MAC: 1.263 + case CKM_CDMF_MAC_GENERAL: 1.264 + case CKM_CDMF_CBC_PAD: 1.265 + case CKM_CDMF_KEY_GEN: 1.266 + return CKK_CDMF; 1.267 + case CKM_RC2_ECB: 1.268 + case CKM_RC2_CBC: 1.269 + case CKM_RC2_MAC: 1.270 + case CKM_RC2_MAC_GENERAL: 1.271 + case CKM_RC2_CBC_PAD: 1.272 + case CKM_RC2_KEY_GEN: 1.273 + case CKM_PBE_SHA1_RC2_128_CBC: 1.274 + case CKM_PBE_SHA1_RC2_40_CBC: 1.275 + return CKK_RC2; 1.276 + case CKM_RC4: 1.277 + case CKM_RC4_KEY_GEN: 1.278 + return CKK_RC4; 1.279 + case CKM_RC5_ECB: 1.280 + case CKM_RC5_CBC: 1.281 + case CKM_RC5_MAC: 1.282 + case CKM_RC5_MAC_GENERAL: 1.283 + case CKM_RC5_CBC_PAD: 1.284 + case CKM_RC5_KEY_GEN: 1.285 + return CKK_RC5; 1.286 + case CKM_SKIPJACK_CBC64: 1.287 + case CKM_SKIPJACK_ECB64: 1.288 + case CKM_SKIPJACK_OFB64: 1.289 + case CKM_SKIPJACK_CFB64: 1.290 + case CKM_SKIPJACK_CFB32: 1.291 + case CKM_SKIPJACK_CFB16: 1.292 + case CKM_SKIPJACK_CFB8: 1.293 + case CKM_SKIPJACK_KEY_GEN: 1.294 + case CKM_SKIPJACK_WRAP: 1.295 + case CKM_SKIPJACK_PRIVATE_WRAP: 1.296 + return CKK_SKIPJACK; 1.297 + case CKM_BATON_ECB128: 1.298 + case CKM_BATON_ECB96: 1.299 + case CKM_BATON_CBC128: 1.300 + case CKM_BATON_COUNTER: 1.301 + case CKM_BATON_SHUFFLE: 1.302 + case CKM_BATON_WRAP: 1.303 + case CKM_BATON_KEY_GEN: 1.304 + return CKK_BATON; 1.305 + case CKM_JUNIPER_ECB128: 1.306 + case CKM_JUNIPER_CBC128: 1.307 + case CKM_JUNIPER_COUNTER: 1.308 + case CKM_JUNIPER_SHUFFLE: 1.309 + case CKM_JUNIPER_WRAP: 1.310 + case CKM_JUNIPER_KEY_GEN: 1.311 + return CKK_JUNIPER; 1.312 + case CKM_IDEA_CBC: 1.313 + case CKM_IDEA_ECB: 1.314 + case CKM_IDEA_MAC: 1.315 + case CKM_IDEA_MAC_GENERAL: 1.316 + case CKM_IDEA_CBC_PAD: 1.317 + case CKM_IDEA_KEY_GEN: 1.318 + return CKK_IDEA; 1.319 + case CKM_CAST_ECB: 1.320 + case CKM_CAST_CBC: 1.321 + case CKM_CAST_MAC: 1.322 + case CKM_CAST_MAC_GENERAL: 1.323 + case CKM_CAST_CBC_PAD: 1.324 + case CKM_CAST_KEY_GEN: 1.325 + case CKM_PBE_MD5_CAST_CBC: 1.326 + return CKK_CAST; 1.327 + case CKM_CAST3_ECB: 1.328 + case CKM_CAST3_CBC: 1.329 + case CKM_CAST3_MAC: 1.330 + case CKM_CAST3_MAC_GENERAL: 1.331 + case CKM_CAST3_CBC_PAD: 1.332 + case CKM_CAST3_KEY_GEN: 1.333 + case CKM_PBE_MD5_CAST3_CBC: 1.334 + return CKK_CAST3; 1.335 + case CKM_CAST5_ECB: 1.336 + case CKM_CAST5_CBC: 1.337 + case CKM_CAST5_MAC: 1.338 + case CKM_CAST5_MAC_GENERAL: 1.339 + case CKM_CAST5_CBC_PAD: 1.340 + case CKM_CAST5_KEY_GEN: 1.341 + case CKM_PBE_MD5_CAST5_CBC: 1.342 + return CKK_CAST5; 1.343 + case CKM_RSA_PKCS: 1.344 + case CKM_RSA_9796: 1.345 + case CKM_RSA_X_509: 1.346 + case CKM_MD2_RSA_PKCS: 1.347 + case CKM_MD5_RSA_PKCS: 1.348 + case CKM_SHA1_RSA_PKCS: 1.349 + case CKM_SHA224_RSA_PKCS: 1.350 + case CKM_SHA256_RSA_PKCS: 1.351 + case CKM_SHA384_RSA_PKCS: 1.352 + case CKM_SHA512_RSA_PKCS: 1.353 + case CKM_KEY_WRAP_SET_OAEP: 1.354 + case CKM_RSA_PKCS_KEY_PAIR_GEN: 1.355 + case CKM_RSA_X9_31_KEY_PAIR_GEN: 1.356 + return CKK_RSA; 1.357 + case CKM_DSA: 1.358 + case CKM_DSA_SHA1: 1.359 + case CKM_DSA_KEY_PAIR_GEN: 1.360 + return CKK_DSA; 1.361 + case CKM_DH_PKCS_DERIVE: 1.362 + case CKM_DH_PKCS_KEY_PAIR_GEN: 1.363 + return CKK_DH; 1.364 + case CKM_KEA_KEY_DERIVE: 1.365 + case CKM_KEA_KEY_PAIR_GEN: 1.366 + return CKK_KEA; 1.367 + case CKM_ECDSA: 1.368 + case CKM_ECDSA_SHA1: 1.369 + case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */ 1.370 + case CKM_ECDH1_DERIVE: 1.371 + return CKK_EC; /* CKK_ECDSA is deprecated */ 1.372 + case CKM_SSL3_PRE_MASTER_KEY_GEN: 1.373 + case CKM_GENERIC_SECRET_KEY_GEN: 1.374 + case CKM_SSL3_MASTER_KEY_DERIVE: 1.375 + case CKM_SSL3_MASTER_KEY_DERIVE_DH: 1.376 + case CKM_SSL3_KEY_AND_MAC_DERIVE: 1.377 + case CKM_SSL3_SHA1_MAC: 1.378 + case CKM_SSL3_MD5_MAC: 1.379 + case CKM_TLS_MASTER_KEY_DERIVE: 1.380 + case CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256: 1.381 + case CKM_TLS_MASTER_KEY_DERIVE_DH: 1.382 + case CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256: 1.383 + case CKM_TLS_KEY_AND_MAC_DERIVE: 1.384 + case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256: 1.385 + case CKM_SHA_1_HMAC: 1.386 + case CKM_SHA_1_HMAC_GENERAL: 1.387 + case CKM_SHA224_HMAC: 1.388 + case CKM_SHA224_HMAC_GENERAL: 1.389 + case CKM_SHA256_HMAC: 1.390 + case CKM_SHA256_HMAC_GENERAL: 1.391 + case CKM_SHA384_HMAC: 1.392 + case CKM_SHA384_HMAC_GENERAL: 1.393 + case CKM_SHA512_HMAC: 1.394 + case CKM_SHA512_HMAC_GENERAL: 1.395 + case CKM_MD2_HMAC: 1.396 + case CKM_MD2_HMAC_GENERAL: 1.397 + case CKM_MD5_HMAC: 1.398 + case CKM_MD5_HMAC_GENERAL: 1.399 + case CKM_TLS_PRF_GENERAL: 1.400 + case CKM_NSS_TLS_PRF_GENERAL_SHA256: 1.401 + return CKK_GENERIC_SECRET; 1.402 + default: 1.403 + return pk11_lookup(type)->keyType; 1.404 + } 1.405 +} 1.406 + 1.407 +/* 1.408 + * Get the Key Gen Mechanism needed for the given 1.409 + * crypto mechanism 1.410 + */ 1.411 +CK_MECHANISM_TYPE 1.412 +PK11_GetKeyGen(CK_MECHANISM_TYPE type) 1.413 +{ 1.414 + return PK11_GetKeyGenWithSize(type, 0); 1.415 +} 1.416 + 1.417 +CK_MECHANISM_TYPE 1.418 +PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size) 1.419 +{ 1.420 + switch (type) { 1.421 + case CKM_SEED_ECB: 1.422 + case CKM_SEED_CBC: 1.423 + case CKM_SEED_MAC: 1.424 + case CKM_SEED_MAC_GENERAL: 1.425 + case CKM_SEED_CBC_PAD: 1.426 + case CKM_SEED_KEY_GEN: 1.427 + return CKM_SEED_KEY_GEN; 1.428 + case CKM_CAMELLIA_ECB: 1.429 + case CKM_CAMELLIA_CBC: 1.430 + case CKM_CAMELLIA_MAC: 1.431 + case CKM_CAMELLIA_MAC_GENERAL: 1.432 + case CKM_CAMELLIA_CBC_PAD: 1.433 + case CKM_CAMELLIA_KEY_GEN: 1.434 + return CKM_CAMELLIA_KEY_GEN; 1.435 + case CKM_AES_ECB: 1.436 + case CKM_AES_CBC: 1.437 + case CKM_AES_CCM: 1.438 + case CKM_AES_CTR: 1.439 + case CKM_AES_CTS: 1.440 + case CKM_AES_GCM: 1.441 + case CKM_AES_MAC: 1.442 + case CKM_AES_MAC_GENERAL: 1.443 + case CKM_AES_CBC_PAD: 1.444 + case CKM_AES_KEY_GEN: 1.445 + return CKM_AES_KEY_GEN; 1.446 + case CKM_DES_ECB: 1.447 + case CKM_DES_CBC: 1.448 + case CKM_DES_MAC: 1.449 + case CKM_DES_MAC_GENERAL: 1.450 + case CKM_KEY_WRAP_LYNKS: 1.451 + case CKM_DES_CBC_PAD: 1.452 + case CKM_DES_KEY_GEN: 1.453 + return CKM_DES_KEY_GEN; 1.454 + case CKM_DES3_ECB: 1.455 + case CKM_DES3_CBC: 1.456 + case CKM_DES3_MAC: 1.457 + case CKM_DES3_MAC_GENERAL: 1.458 + case CKM_DES3_CBC_PAD: 1.459 + return (size == 16) ? CKM_DES2_KEY_GEN : CKM_DES3_KEY_GEN; 1.460 + case CKM_DES3_KEY_GEN: 1.461 + return CKM_DES3_KEY_GEN; 1.462 + case CKM_DES2_KEY_GEN: 1.463 + return CKM_DES2_KEY_GEN; 1.464 + case CKM_CDMF_ECB: 1.465 + case CKM_CDMF_CBC: 1.466 + case CKM_CDMF_MAC: 1.467 + case CKM_CDMF_MAC_GENERAL: 1.468 + case CKM_CDMF_CBC_PAD: 1.469 + case CKM_CDMF_KEY_GEN: 1.470 + return CKM_CDMF_KEY_GEN; 1.471 + case CKM_RC2_ECB: 1.472 + case CKM_RC2_CBC: 1.473 + case CKM_RC2_MAC: 1.474 + case CKM_RC2_MAC_GENERAL: 1.475 + case CKM_RC2_CBC_PAD: 1.476 + case CKM_RC2_KEY_GEN: 1.477 + return CKM_RC2_KEY_GEN; 1.478 + case CKM_RC4: 1.479 + case CKM_RC4_KEY_GEN: 1.480 + return CKM_RC4_KEY_GEN; 1.481 + case CKM_RC5_ECB: 1.482 + case CKM_RC5_CBC: 1.483 + case CKM_RC5_MAC: 1.484 + case CKM_RC5_MAC_GENERAL: 1.485 + case CKM_RC5_CBC_PAD: 1.486 + case CKM_RC5_KEY_GEN: 1.487 + return CKM_RC5_KEY_GEN; 1.488 + case CKM_SKIPJACK_CBC64: 1.489 + case CKM_SKIPJACK_ECB64: 1.490 + case CKM_SKIPJACK_OFB64: 1.491 + case CKM_SKIPJACK_CFB64: 1.492 + case CKM_SKIPJACK_CFB32: 1.493 + case CKM_SKIPJACK_CFB16: 1.494 + case CKM_SKIPJACK_CFB8: 1.495 + case CKM_SKIPJACK_WRAP: 1.496 + case CKM_SKIPJACK_KEY_GEN: 1.497 + return CKM_SKIPJACK_KEY_GEN; 1.498 + case CKM_BATON_ECB128: 1.499 + case CKM_BATON_ECB96: 1.500 + case CKM_BATON_CBC128: 1.501 + case CKM_BATON_COUNTER: 1.502 + case CKM_BATON_SHUFFLE: 1.503 + case CKM_BATON_WRAP: 1.504 + case CKM_BATON_KEY_GEN: 1.505 + return CKM_BATON_KEY_GEN; 1.506 + case CKM_JUNIPER_ECB128: 1.507 + case CKM_JUNIPER_CBC128: 1.508 + case CKM_JUNIPER_COUNTER: 1.509 + case CKM_JUNIPER_SHUFFLE: 1.510 + case CKM_JUNIPER_WRAP: 1.511 + case CKM_JUNIPER_KEY_GEN: 1.512 + return CKM_JUNIPER_KEY_GEN; 1.513 + case CKM_IDEA_CBC: 1.514 + case CKM_IDEA_ECB: 1.515 + case CKM_IDEA_MAC: 1.516 + case CKM_IDEA_MAC_GENERAL: 1.517 + case CKM_IDEA_CBC_PAD: 1.518 + case CKM_IDEA_KEY_GEN: 1.519 + return CKM_IDEA_KEY_GEN; 1.520 + case CKM_CAST_ECB: 1.521 + case CKM_CAST_CBC: 1.522 + case CKM_CAST_MAC: 1.523 + case CKM_CAST_MAC_GENERAL: 1.524 + case CKM_CAST_CBC_PAD: 1.525 + case CKM_CAST_KEY_GEN: 1.526 + return CKM_CAST_KEY_GEN; 1.527 + case CKM_CAST3_ECB: 1.528 + case CKM_CAST3_CBC: 1.529 + case CKM_CAST3_MAC: 1.530 + case CKM_CAST3_MAC_GENERAL: 1.531 + case CKM_CAST3_CBC_PAD: 1.532 + case CKM_CAST3_KEY_GEN: 1.533 + return CKM_CAST3_KEY_GEN; 1.534 + case CKM_CAST5_ECB: 1.535 + case CKM_CAST5_CBC: 1.536 + case CKM_CAST5_MAC: 1.537 + case CKM_CAST5_MAC_GENERAL: 1.538 + case CKM_CAST5_CBC_PAD: 1.539 + case CKM_CAST5_KEY_GEN: 1.540 + return CKM_CAST5_KEY_GEN; 1.541 + case CKM_RSA_PKCS: 1.542 + case CKM_RSA_9796: 1.543 + case CKM_RSA_X_509: 1.544 + case CKM_MD2_RSA_PKCS: 1.545 + case CKM_MD5_RSA_PKCS: 1.546 + case CKM_SHA1_RSA_PKCS: 1.547 + case CKM_SHA224_RSA_PKCS: 1.548 + case CKM_SHA256_RSA_PKCS: 1.549 + case CKM_SHA384_RSA_PKCS: 1.550 + case CKM_SHA512_RSA_PKCS: 1.551 + case CKM_KEY_WRAP_SET_OAEP: 1.552 + case CKM_RSA_PKCS_KEY_PAIR_GEN: 1.553 + return CKM_RSA_PKCS_KEY_PAIR_GEN; 1.554 + case CKM_RSA_X9_31_KEY_PAIR_GEN: 1.555 + return CKM_RSA_X9_31_KEY_PAIR_GEN; 1.556 + case CKM_DSA: 1.557 + case CKM_DSA_SHA1: 1.558 + case CKM_DSA_KEY_PAIR_GEN: 1.559 + return CKM_DSA_KEY_PAIR_GEN; 1.560 + case CKM_DH_PKCS_DERIVE: 1.561 + case CKM_DH_PKCS_KEY_PAIR_GEN: 1.562 + return CKM_DH_PKCS_KEY_PAIR_GEN; 1.563 + case CKM_KEA_KEY_DERIVE: 1.564 + case CKM_KEA_KEY_PAIR_GEN: 1.565 + return CKM_KEA_KEY_PAIR_GEN; 1.566 + case CKM_ECDSA: 1.567 + case CKM_ECDSA_SHA1: 1.568 + case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */ 1.569 + case CKM_ECDH1_DERIVE: 1.570 + return CKM_EC_KEY_PAIR_GEN; 1.571 + case CKM_SSL3_PRE_MASTER_KEY_GEN: 1.572 + case CKM_SSL3_MASTER_KEY_DERIVE: 1.573 + case CKM_SSL3_KEY_AND_MAC_DERIVE: 1.574 + case CKM_SSL3_SHA1_MAC: 1.575 + case CKM_SSL3_MD5_MAC: 1.576 + case CKM_TLS_MASTER_KEY_DERIVE: 1.577 + case CKM_TLS_KEY_AND_MAC_DERIVE: 1.578 + case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256: 1.579 + return CKM_SSL3_PRE_MASTER_KEY_GEN; 1.580 + case CKM_SHA_1_HMAC: 1.581 + case CKM_SHA_1_HMAC_GENERAL: 1.582 + case CKM_SHA224_HMAC: 1.583 + case CKM_SHA224_HMAC_GENERAL: 1.584 + case CKM_SHA256_HMAC: 1.585 + case CKM_SHA256_HMAC_GENERAL: 1.586 + case CKM_SHA384_HMAC: 1.587 + case CKM_SHA384_HMAC_GENERAL: 1.588 + case CKM_SHA512_HMAC: 1.589 + case CKM_SHA512_HMAC_GENERAL: 1.590 + case CKM_MD2_HMAC: 1.591 + case CKM_MD2_HMAC_GENERAL: 1.592 + case CKM_MD5_HMAC: 1.593 + case CKM_MD5_HMAC_GENERAL: 1.594 + case CKM_TLS_PRF_GENERAL: 1.595 + case CKM_NSS_TLS_PRF_GENERAL_SHA256: 1.596 + case CKM_GENERIC_SECRET_KEY_GEN: 1.597 + return CKM_GENERIC_SECRET_KEY_GEN; 1.598 + case CKM_PBE_MD2_DES_CBC: 1.599 + case CKM_PBE_MD5_DES_CBC: 1.600 + case CKM_PBA_SHA1_WITH_SHA1_HMAC: 1.601 + case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN: 1.602 + case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN: 1.603 + case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN: 1.604 + case CKM_NETSCAPE_PBE_SHA1_DES_CBC: 1.605 + case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC: 1.606 + case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC: 1.607 + case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4: 1.608 + case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4: 1.609 + case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC: 1.610 + case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC: 1.611 + case CKM_PBE_SHA1_RC2_40_CBC: 1.612 + case CKM_PBE_SHA1_RC2_128_CBC: 1.613 + case CKM_PBE_SHA1_RC4_40: 1.614 + case CKM_PBE_SHA1_RC4_128: 1.615 + case CKM_PBE_SHA1_DES3_EDE_CBC: 1.616 + case CKM_PBE_SHA1_DES2_EDE_CBC: 1.617 + case CKM_PKCS5_PBKD2: 1.618 + return type; 1.619 + default: 1.620 + return pk11_lookup(type)->keyGen; 1.621 + } 1.622 +} 1.623 + 1.624 +/* 1.625 + * get the mechanism block size 1.626 + */ 1.627 +int 1.628 +PK11_GetBlockSize(CK_MECHANISM_TYPE type,SECItem *params) 1.629 +{ 1.630 + CK_RC5_PARAMS *rc5_params; 1.631 + CK_RC5_CBC_PARAMS *rc5_cbc_params; 1.632 + switch (type) { 1.633 + case CKM_RC5_ECB: 1.634 + if ((params) && (params->data)) { 1.635 + rc5_params = (CK_RC5_PARAMS *) params->data; 1.636 + return (rc5_params->ulWordsize)*2; 1.637 + } 1.638 + return 8; 1.639 + case CKM_RC5_CBC: 1.640 + case CKM_RC5_CBC_PAD: 1.641 + if ((params) && (params->data)) { 1.642 + rc5_cbc_params = (CK_RC5_CBC_PARAMS *) params->data; 1.643 + return (rc5_cbc_params->ulWordsize)*2; 1.644 + } 1.645 + return 8; 1.646 + case CKM_DES_ECB: 1.647 + case CKM_DES3_ECB: 1.648 + case CKM_RC2_ECB: 1.649 + case CKM_IDEA_ECB: 1.650 + case CKM_CAST_ECB: 1.651 + case CKM_CAST3_ECB: 1.652 + case CKM_CAST5_ECB: 1.653 + case CKM_RC2_CBC: 1.654 + case CKM_SKIPJACK_CBC64: 1.655 + case CKM_SKIPJACK_ECB64: 1.656 + case CKM_SKIPJACK_OFB64: 1.657 + case CKM_SKIPJACK_CFB64: 1.658 + case CKM_DES_CBC: 1.659 + case CKM_DES3_CBC: 1.660 + case CKM_IDEA_CBC: 1.661 + case CKM_CAST_CBC: 1.662 + case CKM_CAST3_CBC: 1.663 + case CKM_CAST5_CBC: 1.664 + case CKM_DES_CBC_PAD: 1.665 + case CKM_DES3_CBC_PAD: 1.666 + case CKM_RC2_CBC_PAD: 1.667 + case CKM_IDEA_CBC_PAD: 1.668 + case CKM_CAST_CBC_PAD: 1.669 + case CKM_CAST3_CBC_PAD: 1.670 + case CKM_CAST5_CBC_PAD: 1.671 + case CKM_PBE_MD2_DES_CBC: 1.672 + case CKM_PBE_MD5_DES_CBC: 1.673 + case CKM_NETSCAPE_PBE_SHA1_DES_CBC: 1.674 + case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC: 1.675 + case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC: 1.676 + case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC: 1.677 + case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC: 1.678 + case CKM_PBE_SHA1_RC2_40_CBC: 1.679 + case CKM_PBE_SHA1_RC2_128_CBC: 1.680 + case CKM_PBE_SHA1_DES3_EDE_CBC: 1.681 + case CKM_PBE_SHA1_DES2_EDE_CBC: 1.682 + return 8; 1.683 + case CKM_SKIPJACK_CFB32: 1.684 + case CKM_SKIPJACK_CFB16: 1.685 + case CKM_SKIPJACK_CFB8: 1.686 + return 4; 1.687 + case CKM_SEED_ECB: 1.688 + case CKM_SEED_CBC: 1.689 + case CKM_SEED_CBC_PAD: 1.690 + case CKM_CAMELLIA_ECB: 1.691 + case CKM_CAMELLIA_CBC: 1.692 + case CKM_CAMELLIA_CBC_PAD: 1.693 + case CKM_AES_ECB: 1.694 + case CKM_AES_CBC: 1.695 + case CKM_AES_CBC_PAD: 1.696 + case CKM_BATON_ECB128: 1.697 + case CKM_BATON_CBC128: 1.698 + case CKM_BATON_COUNTER: 1.699 + case CKM_BATON_SHUFFLE: 1.700 + case CKM_JUNIPER_ECB128: 1.701 + case CKM_JUNIPER_CBC128: 1.702 + case CKM_JUNIPER_COUNTER: 1.703 + case CKM_JUNIPER_SHUFFLE: 1.704 + return 16; 1.705 + case CKM_BATON_ECB96: 1.706 + return 12; 1.707 + case CKM_RC4: 1.708 + case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4: 1.709 + case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4: 1.710 + case CKM_PBE_SHA1_RC4_40: 1.711 + case CKM_PBE_SHA1_RC4_128: 1.712 + return 0; 1.713 + case CKM_RSA_PKCS: 1.714 + case CKM_RSA_9796: 1.715 + case CKM_RSA_X_509: 1.716 + /*actually it's the modulus length of the key!*/ 1.717 + return -1; /* failure */ 1.718 + default: 1.719 + return pk11_lookup(type)->blockSize; 1.720 + } 1.721 +} 1.722 + 1.723 +/* 1.724 + * get the iv length 1.725 + */ 1.726 +int 1.727 +PK11_GetIVLength(CK_MECHANISM_TYPE type) 1.728 +{ 1.729 + switch (type) { 1.730 + case CKM_SEED_ECB: 1.731 + case CKM_CAMELLIA_ECB: 1.732 + case CKM_AES_ECB: 1.733 + case CKM_DES_ECB: 1.734 + case CKM_DES3_ECB: 1.735 + case CKM_RC2_ECB: 1.736 + case CKM_IDEA_ECB: 1.737 + case CKM_SKIPJACK_WRAP: 1.738 + case CKM_BATON_WRAP: 1.739 + case CKM_RC5_ECB: 1.740 + case CKM_CAST_ECB: 1.741 + case CKM_CAST3_ECB: 1.742 + case CKM_CAST5_ECB: 1.743 + return 0; 1.744 + case CKM_RC2_CBC: 1.745 + case CKM_DES_CBC: 1.746 + case CKM_DES3_CBC: 1.747 + case CKM_IDEA_CBC: 1.748 + case CKM_PBE_MD2_DES_CBC: 1.749 + case CKM_PBE_MD5_DES_CBC: 1.750 + case CKM_NETSCAPE_PBE_SHA1_DES_CBC: 1.751 + case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC: 1.752 + case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC: 1.753 + case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC: 1.754 + case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC: 1.755 + case CKM_PBE_SHA1_RC2_40_CBC: 1.756 + case CKM_PBE_SHA1_RC2_128_CBC: 1.757 + case CKM_PBE_SHA1_DES3_EDE_CBC: 1.758 + case CKM_PBE_SHA1_DES2_EDE_CBC: 1.759 + case CKM_RC5_CBC: 1.760 + case CKM_CAST_CBC: 1.761 + case CKM_CAST3_CBC: 1.762 + case CKM_CAST5_CBC: 1.763 + case CKM_RC2_CBC_PAD: 1.764 + case CKM_DES_CBC_PAD: 1.765 + case CKM_DES3_CBC_PAD: 1.766 + case CKM_IDEA_CBC_PAD: 1.767 + case CKM_RC5_CBC_PAD: 1.768 + case CKM_CAST_CBC_PAD: 1.769 + case CKM_CAST3_CBC_PAD: 1.770 + case CKM_CAST5_CBC_PAD: 1.771 + return 8; 1.772 + case CKM_SEED_CBC: 1.773 + case CKM_SEED_CBC_PAD: 1.774 + case CKM_CAMELLIA_CBC: 1.775 + case CKM_CAMELLIA_CBC_PAD: 1.776 + case CKM_AES_CBC: 1.777 + case CKM_AES_CBC_PAD: 1.778 + return 16; 1.779 + case CKM_SKIPJACK_CBC64: 1.780 + case CKM_SKIPJACK_ECB64: 1.781 + case CKM_SKIPJACK_OFB64: 1.782 + case CKM_SKIPJACK_CFB64: 1.783 + case CKM_SKIPJACK_CFB32: 1.784 + case CKM_SKIPJACK_CFB16: 1.785 + case CKM_SKIPJACK_CFB8: 1.786 + case CKM_BATON_ECB128: 1.787 + case CKM_BATON_ECB96: 1.788 + case CKM_BATON_CBC128: 1.789 + case CKM_BATON_COUNTER: 1.790 + case CKM_BATON_SHUFFLE: 1.791 + case CKM_JUNIPER_ECB128: 1.792 + case CKM_JUNIPER_CBC128: 1.793 + case CKM_JUNIPER_COUNTER: 1.794 + case CKM_JUNIPER_SHUFFLE: 1.795 + return 24; 1.796 + case CKM_RC4: 1.797 + case CKM_RSA_PKCS: 1.798 + case CKM_RSA_9796: 1.799 + case CKM_RSA_X_509: 1.800 + case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4: 1.801 + case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4: 1.802 + case CKM_PBE_SHA1_RC4_40: 1.803 + case CKM_PBE_SHA1_RC4_128: 1.804 + return 0; 1.805 + default: 1.806 + return pk11_lookup(type)->iv; 1.807 + } 1.808 +} 1.809 + 1.810 + 1.811 +/* These next two utilities are here to help facilitate future 1.812 + * Dynamic Encrypt/Decrypt symetric key mechanisms, and to allow functions 1.813 + * like SSL and S-MIME to automatically add them. 1.814 + */ 1.815 +SECItem * 1.816 +pk11_ParamFromIVWithLen(CK_MECHANISM_TYPE type, SECItem *iv, int keyLen) 1.817 +{ 1.818 + CK_RC2_CBC_PARAMS *rc2_params = NULL; 1.819 + CK_RC2_PARAMS *rc2_ecb_params = NULL; 1.820 + CK_RC5_PARAMS *rc5_params = NULL; 1.821 + CK_RC5_CBC_PARAMS *rc5_cbc_params = NULL; 1.822 + SECItem *param; 1.823 + 1.824 + param = (SECItem *)PORT_Alloc(sizeof(SECItem)); 1.825 + if (param == NULL) return NULL; 1.826 + param->data = NULL; 1.827 + param->len = 0; 1.828 + param->type = 0; 1.829 + switch (type) { 1.830 + case CKM_SEED_ECB: 1.831 + case CKM_CAMELLIA_ECB: 1.832 + case CKM_AES_ECB: 1.833 + case CKM_DES_ECB: 1.834 + case CKM_DES3_ECB: 1.835 + case CKM_RSA_PKCS: 1.836 + case CKM_RSA_X_509: 1.837 + case CKM_RSA_9796: 1.838 + case CKM_IDEA_ECB: 1.839 + case CKM_CDMF_ECB: 1.840 + case CKM_CAST_ECB: 1.841 + case CKM_CAST3_ECB: 1.842 + case CKM_CAST5_ECB: 1.843 + case CKM_RC4: 1.844 + break; 1.845 + case CKM_RC2_ECB: 1.846 + rc2_ecb_params = (CK_RC2_PARAMS *)PORT_Alloc(sizeof(CK_RC2_PARAMS)); 1.847 + if (rc2_ecb_params == NULL) break; 1.848 + /* Maybe we should pass the key size in too to get this value? */ 1.849 + *rc2_ecb_params = keyLen ? keyLen*8 : 128; 1.850 + param->data = (unsigned char *) rc2_ecb_params; 1.851 + param->len = sizeof(CK_RC2_PARAMS); 1.852 + break; 1.853 + case CKM_RC2_CBC: 1.854 + case CKM_RC2_CBC_PAD: 1.855 + rc2_params = (CK_RC2_CBC_PARAMS *)PORT_Alloc(sizeof(CK_RC2_CBC_PARAMS)); 1.856 + if (rc2_params == NULL) break; 1.857 + /* Maybe we should pass the key size in too to get this value? */ 1.858 + rc2_params->ulEffectiveBits = keyLen ? keyLen*8 : 128; 1.859 + if (iv && iv->data) 1.860 + PORT_Memcpy(rc2_params->iv,iv->data,sizeof(rc2_params->iv)); 1.861 + param->data = (unsigned char *) rc2_params; 1.862 + param->len = sizeof(CK_RC2_CBC_PARAMS); 1.863 + break; 1.864 + case CKM_RC5_CBC: 1.865 + case CKM_RC5_CBC_PAD: 1.866 + rc5_cbc_params = (CK_RC5_CBC_PARAMS *) 1.867 + PORT_Alloc(sizeof(CK_RC5_CBC_PARAMS) + ((iv) ? iv->len : 0)); 1.868 + if (rc5_cbc_params == NULL) break; 1.869 + if (iv && iv->data && iv->len) { 1.870 + rc5_cbc_params->pIv = ((CK_BYTE_PTR) rc5_cbc_params) 1.871 + + sizeof(CK_RC5_CBC_PARAMS); 1.872 + PORT_Memcpy(rc5_cbc_params->pIv,iv->data,iv->len); 1.873 + rc5_cbc_params->ulIvLen = iv->len; 1.874 + rc5_cbc_params->ulWordsize = iv->len/2; 1.875 + } else { 1.876 + rc5_cbc_params->ulWordsize = 4; 1.877 + rc5_cbc_params->pIv = NULL; 1.878 + rc5_cbc_params->ulIvLen = 0; 1.879 + } 1.880 + rc5_cbc_params->ulRounds = 16; 1.881 + param->data = (unsigned char *) rc5_cbc_params; 1.882 + param->len = sizeof(CK_RC5_CBC_PARAMS); 1.883 + break; 1.884 + case CKM_RC5_ECB: 1.885 + rc5_params = (CK_RC5_PARAMS *)PORT_Alloc(sizeof(CK_RC5_PARAMS)); 1.886 + if (rc5_params == NULL) break; 1.887 + if (iv && iv->data && iv->len) { 1.888 + rc5_params->ulWordsize = iv->len/2; 1.889 + } else { 1.890 + rc5_params->ulWordsize = 4; 1.891 + } 1.892 + rc5_params->ulRounds = 16; 1.893 + param->data = (unsigned char *) rc5_params; 1.894 + param->len = sizeof(CK_RC5_PARAMS); 1.895 + break; 1.896 + 1.897 + case CKM_SEED_CBC: 1.898 + case CKM_CAMELLIA_CBC: 1.899 + case CKM_AES_CBC: 1.900 + case CKM_DES_CBC: 1.901 + case CKM_DES3_CBC: 1.902 + case CKM_IDEA_CBC: 1.903 + case CKM_CDMF_CBC: 1.904 + case CKM_CAST_CBC: 1.905 + case CKM_CAST3_CBC: 1.906 + case CKM_CAST5_CBC: 1.907 + case CKM_CAMELLIA_CBC_PAD: 1.908 + case CKM_AES_CBC_PAD: 1.909 + case CKM_DES_CBC_PAD: 1.910 + case CKM_DES3_CBC_PAD: 1.911 + case CKM_IDEA_CBC_PAD: 1.912 + case CKM_CDMF_CBC_PAD: 1.913 + case CKM_CAST_CBC_PAD: 1.914 + case CKM_CAST3_CBC_PAD: 1.915 + case CKM_CAST5_CBC_PAD: 1.916 + case CKM_SKIPJACK_CBC64: 1.917 + case CKM_SKIPJACK_ECB64: 1.918 + case CKM_SKIPJACK_OFB64: 1.919 + case CKM_SKIPJACK_CFB64: 1.920 + case CKM_SKIPJACK_CFB32: 1.921 + case CKM_SKIPJACK_CFB16: 1.922 + case CKM_SKIPJACK_CFB8: 1.923 + case CKM_BATON_ECB128: 1.924 + case CKM_BATON_ECB96: 1.925 + case CKM_BATON_CBC128: 1.926 + case CKM_BATON_COUNTER: 1.927 + case CKM_BATON_SHUFFLE: 1.928 + case CKM_JUNIPER_ECB128: 1.929 + case CKM_JUNIPER_CBC128: 1.930 + case CKM_JUNIPER_COUNTER: 1.931 + case CKM_JUNIPER_SHUFFLE: 1.932 + if ((iv == NULL) || (iv->data == NULL)) break; 1.933 + param->data = (unsigned char*)PORT_Alloc(iv->len); 1.934 + if (param->data != NULL) { 1.935 + PORT_Memcpy(param->data,iv->data,iv->len); 1.936 + param->len = iv->len; 1.937 + } 1.938 + break; 1.939 + /* unknown mechanism, pass IV in if it's there */ 1.940 + default: 1.941 + if (pk11_lookup(type)->iv == 0) { 1.942 + break; 1.943 + } 1.944 + if ((iv == NULL) || (iv->data == NULL)) { 1.945 + break; 1.946 + } 1.947 + param->data = (unsigned char*)PORT_Alloc(iv->len); 1.948 + if (param->data != NULL) { 1.949 + PORT_Memcpy(param->data,iv->data,iv->len); 1.950 + param->len = iv->len; 1.951 + } 1.952 + break; 1.953 + } 1.954 + return param; 1.955 +} 1.956 + 1.957 +/* These next two utilities are here to help facilitate future 1.958 + * Dynamic Encrypt/Decrypt symetric key mechanisms, and to allow functions 1.959 + * like SSL and S-MIME to automatically add them. 1.960 + */ 1.961 +SECItem * 1.962 +PK11_ParamFromIV(CK_MECHANISM_TYPE type,SECItem *iv) 1.963 +{ 1.964 + return pk11_ParamFromIVWithLen(type, iv, 0); 1.965 +} 1.966 + 1.967 +unsigned char * 1.968 +PK11_IVFromParam(CK_MECHANISM_TYPE type,SECItem *param,int *len) 1.969 +{ 1.970 + CK_RC2_CBC_PARAMS *rc2_params; 1.971 + CK_RC5_CBC_PARAMS *rc5_cbc_params; 1.972 + 1.973 + *len = 0; 1.974 + switch (type) { 1.975 + case CKM_SEED_ECB: 1.976 + case CKM_CAMELLIA_ECB: 1.977 + case CKM_AES_ECB: 1.978 + case CKM_DES_ECB: 1.979 + case CKM_DES3_ECB: 1.980 + case CKM_RSA_PKCS: 1.981 + case CKM_RSA_X_509: 1.982 + case CKM_RSA_9796: 1.983 + case CKM_IDEA_ECB: 1.984 + case CKM_CDMF_ECB: 1.985 + case CKM_CAST_ECB: 1.986 + case CKM_CAST3_ECB: 1.987 + case CKM_CAST5_ECB: 1.988 + case CKM_RC4: 1.989 + return NULL; 1.990 + case CKM_RC2_ECB: 1.991 + return NULL; 1.992 + case CKM_RC2_CBC: 1.993 + case CKM_RC2_CBC_PAD: 1.994 + rc2_params = (CK_RC2_CBC_PARAMS *)param->data; 1.995 + *len = sizeof(rc2_params->iv); 1.996 + return &rc2_params->iv[0]; 1.997 + case CKM_RC5_CBC: 1.998 + case CKM_RC5_CBC_PAD: 1.999 + rc5_cbc_params = (CK_RC5_CBC_PARAMS *) param->data; 1.1000 + *len = rc5_cbc_params->ulIvLen; 1.1001 + return rc5_cbc_params->pIv; 1.1002 + case CKM_SEED_CBC: 1.1003 + case CKM_CAMELLIA_CBC: 1.1004 + case CKM_AES_CBC: 1.1005 + case CKM_DES_CBC: 1.1006 + case CKM_DES3_CBC: 1.1007 + case CKM_IDEA_CBC: 1.1008 + case CKM_CDMF_CBC: 1.1009 + case CKM_CAST_CBC: 1.1010 + case CKM_CAST3_CBC: 1.1011 + case CKM_CAST5_CBC: 1.1012 + case CKM_CAMELLIA_CBC_PAD: 1.1013 + case CKM_AES_CBC_PAD: 1.1014 + case CKM_DES_CBC_PAD: 1.1015 + case CKM_DES3_CBC_PAD: 1.1016 + case CKM_IDEA_CBC_PAD: 1.1017 + case CKM_CDMF_CBC_PAD: 1.1018 + case CKM_CAST_CBC_PAD: 1.1019 + case CKM_CAST3_CBC_PAD: 1.1020 + case CKM_CAST5_CBC_PAD: 1.1021 + case CKM_SKIPJACK_CBC64: 1.1022 + case CKM_SKIPJACK_ECB64: 1.1023 + case CKM_SKIPJACK_OFB64: 1.1024 + case CKM_SKIPJACK_CFB64: 1.1025 + case CKM_SKIPJACK_CFB32: 1.1026 + case CKM_SKIPJACK_CFB16: 1.1027 + case CKM_SKIPJACK_CFB8: 1.1028 + case CKM_BATON_ECB128: 1.1029 + case CKM_BATON_ECB96: 1.1030 + case CKM_BATON_CBC128: 1.1031 + case CKM_BATON_COUNTER: 1.1032 + case CKM_BATON_SHUFFLE: 1.1033 + case CKM_JUNIPER_ECB128: 1.1034 + case CKM_JUNIPER_CBC128: 1.1035 + case CKM_JUNIPER_COUNTER: 1.1036 + case CKM_JUNIPER_SHUFFLE: 1.1037 + break; 1.1038 + /* unknown mechanism, pass IV in if it's there */ 1.1039 + default: 1.1040 + break; 1.1041 + } 1.1042 + if (param->data) { 1.1043 + *len = param->len; 1.1044 + } 1.1045 + return param->data; 1.1046 +} 1.1047 + 1.1048 +typedef struct sec_rc5cbcParameterStr { 1.1049 + SECItem version; 1.1050 + SECItem rounds; 1.1051 + SECItem blockSizeInBits; 1.1052 + SECItem iv; 1.1053 +} sec_rc5cbcParameter; 1.1054 + 1.1055 +static const SEC_ASN1Template sec_rc5ecb_parameter_template[] = { 1.1056 + { SEC_ASN1_SEQUENCE, 1.1057 + 0, NULL, sizeof(sec_rc5cbcParameter) }, 1.1058 + { SEC_ASN1_INTEGER, 1.1059 + offsetof(sec_rc5cbcParameter,version) }, 1.1060 + { SEC_ASN1_INTEGER, 1.1061 + offsetof(sec_rc5cbcParameter,rounds) }, 1.1062 + { SEC_ASN1_INTEGER, 1.1063 + offsetof(sec_rc5cbcParameter,blockSizeInBits) }, 1.1064 + { 0 } 1.1065 +}; 1.1066 + 1.1067 +static const SEC_ASN1Template sec_rc5cbc_parameter_template[] = { 1.1068 + { SEC_ASN1_SEQUENCE, 1.1069 + 0, NULL, sizeof(sec_rc5cbcParameter) }, 1.1070 + { SEC_ASN1_INTEGER, 1.1071 + offsetof(sec_rc5cbcParameter,version) }, 1.1072 + { SEC_ASN1_INTEGER, 1.1073 + offsetof(sec_rc5cbcParameter,rounds) }, 1.1074 + { SEC_ASN1_INTEGER, 1.1075 + offsetof(sec_rc5cbcParameter,blockSizeInBits) }, 1.1076 + { SEC_ASN1_OCTET_STRING, 1.1077 + offsetof(sec_rc5cbcParameter,iv) }, 1.1078 + { 0 } 1.1079 +}; 1.1080 + 1.1081 +typedef struct sec_rc2cbcParameterStr { 1.1082 + SECItem rc2ParameterVersion; 1.1083 + SECItem iv; 1.1084 +} sec_rc2cbcParameter; 1.1085 + 1.1086 +static const SEC_ASN1Template sec_rc2cbc_parameter_template[] = { 1.1087 + { SEC_ASN1_SEQUENCE, 1.1088 + 0, NULL, sizeof(sec_rc2cbcParameter) }, 1.1089 + { SEC_ASN1_INTEGER, 1.1090 + offsetof(sec_rc2cbcParameter,rc2ParameterVersion) }, 1.1091 + { SEC_ASN1_OCTET_STRING, 1.1092 + offsetof(sec_rc2cbcParameter,iv) }, 1.1093 + { 0 } 1.1094 +}; 1.1095 + 1.1096 +static const SEC_ASN1Template sec_rc2ecb_parameter_template[] = { 1.1097 + { SEC_ASN1_SEQUENCE, 1.1098 + 0, NULL, sizeof(sec_rc2cbcParameter) }, 1.1099 + { SEC_ASN1_INTEGER, 1.1100 + offsetof(sec_rc2cbcParameter,rc2ParameterVersion) }, 1.1101 + { 0 } 1.1102 +}; 1.1103 + 1.1104 +/* S/MIME picked id values to represent differnt keysizes */ 1.1105 +/* I do have a formula, but it ain't pretty, and it only works because you 1.1106 + * can always match three points to a parabola:) */ 1.1107 +static unsigned char rc2_map(SECItem *version) 1.1108 +{ 1.1109 + long x; 1.1110 + 1.1111 + x = DER_GetInteger(version); 1.1112 + 1.1113 + switch (x) { 1.1114 + case 58: return 128; 1.1115 + case 120: return 64; 1.1116 + case 160: return 40; 1.1117 + } 1.1118 + return 128; 1.1119 +} 1.1120 + 1.1121 +static unsigned long rc2_unmap(unsigned long x) 1.1122 +{ 1.1123 + switch (x) { 1.1124 + case 128: return 58; 1.1125 + case 64: return 120; 1.1126 + case 40: return 160; 1.1127 + } 1.1128 + return 58; 1.1129 +} 1.1130 + 1.1131 + 1.1132 + 1.1133 +/* Generate a mechaism param from a type, and iv. */ 1.1134 +SECItem * 1.1135 +PK11_ParamFromAlgid(SECAlgorithmID *algid) 1.1136 +{ 1.1137 + CK_RC2_CBC_PARAMS * rc2_cbc_params = NULL; 1.1138 + CK_RC2_PARAMS * rc2_ecb_params = NULL; 1.1139 + CK_RC5_CBC_PARAMS * rc5_cbc_params = NULL; 1.1140 + CK_RC5_PARAMS * rc5_ecb_params = NULL; 1.1141 + PLArenaPool * arena = NULL; 1.1142 + SECItem * mech = NULL; 1.1143 + SECOidTag algtag; 1.1144 + SECStatus rv; 1.1145 + CK_MECHANISM_TYPE type; 1.1146 + /* initialize these to prevent UMRs in the ASN1 decoder. */ 1.1147 + SECItem iv = {siBuffer, NULL, 0}; 1.1148 + sec_rc2cbcParameter rc2 = { {siBuffer, NULL, 0}, {siBuffer, NULL, 0} }; 1.1149 + sec_rc5cbcParameter rc5 = { {siBuffer, NULL, 0}, {siBuffer, NULL, 0}, 1.1150 + {siBuffer, NULL, 0}, {siBuffer, NULL, 0} }; 1.1151 + 1.1152 + algtag = SECOID_GetAlgorithmTag(algid); 1.1153 + type = PK11_AlgtagToMechanism(algtag); 1.1154 + 1.1155 + mech = PORT_New(SECItem); 1.1156 + if (mech == NULL) { 1.1157 + return NULL; 1.1158 + } 1.1159 + mech->type = siBuffer; 1.1160 + mech->data = NULL; 1.1161 + mech->len = 0; 1.1162 + 1.1163 + arena = PORT_NewArena(1024); 1.1164 + if (!arena) { 1.1165 + goto loser; 1.1166 + } 1.1167 + 1.1168 + /* handle the complicated cases */ 1.1169 + switch (type) { 1.1170 + case CKM_RC2_ECB: 1.1171 + rv = SEC_ASN1DecodeItem(arena, &rc2 ,sec_rc2ecb_parameter_template, 1.1172 + &(algid->parameters)); 1.1173 + if (rv != SECSuccess) { 1.1174 + goto loser; 1.1175 + } 1.1176 + rc2_ecb_params = PORT_New(CK_RC2_PARAMS); 1.1177 + if (rc2_ecb_params == NULL) { 1.1178 + goto loser; 1.1179 + } 1.1180 + *rc2_ecb_params = rc2_map(&rc2.rc2ParameterVersion); 1.1181 + mech->data = (unsigned char *) rc2_ecb_params; 1.1182 + mech->len = sizeof *rc2_ecb_params; 1.1183 + break; 1.1184 + case CKM_RC2_CBC: 1.1185 + case CKM_RC2_CBC_PAD: 1.1186 + rv = SEC_ASN1DecodeItem(arena, &rc2 ,sec_rc2cbc_parameter_template, 1.1187 + &(algid->parameters)); 1.1188 + if (rv != SECSuccess) { 1.1189 + goto loser; 1.1190 + } 1.1191 + rc2_cbc_params = PORT_New(CK_RC2_CBC_PARAMS); 1.1192 + if (rc2_cbc_params == NULL) { 1.1193 + goto loser; 1.1194 + } 1.1195 + mech->data = (unsigned char *) rc2_cbc_params; 1.1196 + mech->len = sizeof *rc2_cbc_params; 1.1197 + rc2_cbc_params->ulEffectiveBits = rc2_map(&rc2.rc2ParameterVersion); 1.1198 + if (rc2.iv.len != sizeof rc2_cbc_params->iv) { 1.1199 + PORT_SetError(SEC_ERROR_INPUT_LEN); 1.1200 + goto loser; 1.1201 + } 1.1202 + PORT_Memcpy(rc2_cbc_params->iv, rc2.iv.data, rc2.iv.len); 1.1203 + break; 1.1204 + case CKM_RC5_ECB: 1.1205 + rv = SEC_ASN1DecodeItem(arena, &rc5 ,sec_rc5ecb_parameter_template, 1.1206 + &(algid->parameters)); 1.1207 + if (rv != SECSuccess) { 1.1208 + goto loser; 1.1209 + } 1.1210 + rc5_ecb_params = PORT_New(CK_RC5_PARAMS); 1.1211 + if (rc5_ecb_params == NULL) { 1.1212 + goto loser; 1.1213 + } 1.1214 + rc5_ecb_params->ulRounds = DER_GetInteger(&rc5.rounds); 1.1215 + rc5_ecb_params->ulWordsize = DER_GetInteger(&rc5.blockSizeInBits)/8; 1.1216 + mech->data = (unsigned char *) rc5_ecb_params; 1.1217 + mech->len = sizeof *rc5_ecb_params; 1.1218 + break; 1.1219 + case CKM_RC5_CBC: 1.1220 + case CKM_RC5_CBC_PAD: 1.1221 + rv = SEC_ASN1DecodeItem(arena, &rc5 ,sec_rc5cbc_parameter_template, 1.1222 + &(algid->parameters)); 1.1223 + if (rv != SECSuccess) { 1.1224 + goto loser; 1.1225 + } 1.1226 + rc5_cbc_params = (CK_RC5_CBC_PARAMS *) 1.1227 + PORT_Alloc(sizeof(CK_RC5_CBC_PARAMS) + rc5.iv.len); 1.1228 + if (rc5_cbc_params == NULL) { 1.1229 + goto loser; 1.1230 + } 1.1231 + mech->data = (unsigned char *) rc5_cbc_params; 1.1232 + mech->len = sizeof *rc5_cbc_params; 1.1233 + rc5_cbc_params->ulRounds = DER_GetInteger(&rc5.rounds); 1.1234 + rc5_cbc_params->ulWordsize = DER_GetInteger(&rc5.blockSizeInBits)/8; 1.1235 + rc5_cbc_params->pIv = ((CK_BYTE_PTR)rc5_cbc_params) 1.1236 + + sizeof(CK_RC5_CBC_PARAMS); 1.1237 + rc5_cbc_params->ulIvLen = rc5.iv.len; 1.1238 + PORT_Memcpy(rc5_cbc_params->pIv, rc5.iv.data, rc5.iv.len); 1.1239 + break; 1.1240 + case CKM_PBE_MD2_DES_CBC: 1.1241 + case CKM_PBE_MD5_DES_CBC: 1.1242 + case CKM_NETSCAPE_PBE_SHA1_DES_CBC: 1.1243 + case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC: 1.1244 + case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC: 1.1245 + case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC: 1.1246 + case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC: 1.1247 + case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4: 1.1248 + case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4: 1.1249 + case CKM_PBE_SHA1_DES2_EDE_CBC: 1.1250 + case CKM_PBE_SHA1_DES3_EDE_CBC: 1.1251 + case CKM_PBE_SHA1_RC2_40_CBC: 1.1252 + case CKM_PBE_SHA1_RC2_128_CBC: 1.1253 + case CKM_PBE_SHA1_RC4_40: 1.1254 + case CKM_PBE_SHA1_RC4_128: 1.1255 + case CKM_PKCS5_PBKD2: 1.1256 + rv = pbe_PK11AlgidToParam(algid,mech); 1.1257 + if (rv != SECSuccess) { 1.1258 + goto loser; 1.1259 + } 1.1260 + break; 1.1261 + case CKM_RC4: 1.1262 + case CKM_SEED_ECB: 1.1263 + case CKM_CAMELLIA_ECB: 1.1264 + case CKM_AES_ECB: 1.1265 + case CKM_DES_ECB: 1.1266 + case CKM_DES3_ECB: 1.1267 + case CKM_IDEA_ECB: 1.1268 + case CKM_CDMF_ECB: 1.1269 + case CKM_CAST_ECB: 1.1270 + case CKM_CAST3_ECB: 1.1271 + case CKM_CAST5_ECB: 1.1272 + break; 1.1273 + 1.1274 + default: 1.1275 + if (pk11_lookup(type)->iv == 0) { 1.1276 + break; 1.1277 + } 1.1278 + /* FALL THROUGH */ 1.1279 + case CKM_SEED_CBC: 1.1280 + case CKM_CAMELLIA_CBC: 1.1281 + case CKM_AES_CBC: 1.1282 + case CKM_DES_CBC: 1.1283 + case CKM_DES3_CBC: 1.1284 + case CKM_IDEA_CBC: 1.1285 + case CKM_CDMF_CBC: 1.1286 + case CKM_CAST_CBC: 1.1287 + case CKM_CAST3_CBC: 1.1288 + case CKM_CAST5_CBC: 1.1289 + case CKM_SEED_CBC_PAD: 1.1290 + case CKM_CAMELLIA_CBC_PAD: 1.1291 + case CKM_AES_CBC_PAD: 1.1292 + case CKM_DES_CBC_PAD: 1.1293 + case CKM_DES3_CBC_PAD: 1.1294 + case CKM_IDEA_CBC_PAD: 1.1295 + case CKM_CDMF_CBC_PAD: 1.1296 + case CKM_CAST_CBC_PAD: 1.1297 + case CKM_CAST3_CBC_PAD: 1.1298 + case CKM_CAST5_CBC_PAD: 1.1299 + case CKM_SKIPJACK_CBC64: 1.1300 + case CKM_SKIPJACK_ECB64: 1.1301 + case CKM_SKIPJACK_OFB64: 1.1302 + case CKM_SKIPJACK_CFB64: 1.1303 + case CKM_SKIPJACK_CFB32: 1.1304 + case CKM_SKIPJACK_CFB16: 1.1305 + case CKM_SKIPJACK_CFB8: 1.1306 + case CKM_BATON_ECB128: 1.1307 + case CKM_BATON_ECB96: 1.1308 + case CKM_BATON_CBC128: 1.1309 + case CKM_BATON_COUNTER: 1.1310 + case CKM_BATON_SHUFFLE: 1.1311 + case CKM_JUNIPER_ECB128: 1.1312 + case CKM_JUNIPER_CBC128: 1.1313 + case CKM_JUNIPER_COUNTER: 1.1314 + case CKM_JUNIPER_SHUFFLE: 1.1315 + /* simple cases are simply octet string encoded IVs */ 1.1316 + rv = SEC_ASN1DecodeItem(arena, &iv, 1.1317 + SEC_ASN1_GET(SEC_OctetStringTemplate), 1.1318 + &(algid->parameters)); 1.1319 + if (rv != SECSuccess || iv.data == NULL) { 1.1320 + goto loser; 1.1321 + } 1.1322 + /* XXX Should be some IV length sanity check here. */ 1.1323 + mech->data = (unsigned char*)PORT_Alloc(iv.len); 1.1324 + if (mech->data == NULL) { 1.1325 + goto loser; 1.1326 + } 1.1327 + PORT_Memcpy(mech->data, iv.data, iv.len); 1.1328 + mech->len = iv.len; 1.1329 + break; 1.1330 + } 1.1331 + PORT_FreeArena(arena, PR_FALSE); 1.1332 + return mech; 1.1333 + 1.1334 +loser: 1.1335 + if (arena) 1.1336 + PORT_FreeArena(arena, PR_FALSE); 1.1337 + SECITEM_FreeItem(mech,PR_TRUE); 1.1338 + return NULL; 1.1339 +} 1.1340 + 1.1341 +/* 1.1342 + * Generate an IV for the given mechanism 1.1343 + */ 1.1344 +static SECStatus 1.1345 +pk11_GenIV(CK_MECHANISM_TYPE type, SECItem *iv) { 1.1346 + int iv_size = PK11_GetIVLength(type); 1.1347 + SECStatus rv; 1.1348 + 1.1349 + iv->len = iv_size; 1.1350 + if (iv_size == 0) { 1.1351 + iv->data = NULL; 1.1352 + return SECSuccess; 1.1353 + } 1.1354 + 1.1355 + iv->data = (unsigned char *) PORT_Alloc(iv_size); 1.1356 + if (iv->data == NULL) { 1.1357 + iv->len = 0; 1.1358 + return SECFailure; 1.1359 + } 1.1360 + 1.1361 + rv = PK11_GenerateRandom(iv->data,iv->len); 1.1362 + if (rv != SECSuccess) { 1.1363 + PORT_Free(iv->data); 1.1364 + iv->data = NULL; iv->len = 0; 1.1365 + return SECFailure; 1.1366 + } 1.1367 + return SECSuccess; 1.1368 +} 1.1369 + 1.1370 + 1.1371 +/* 1.1372 + * create a new parameter block from the passed in MECHANISM and the 1.1373 + * key. Use Netscape's S/MIME Rules for the New param block. 1.1374 + */ 1.1375 +SECItem * 1.1376 +pk11_GenerateNewParamWithKeyLen(CK_MECHANISM_TYPE type, int keyLen) 1.1377 +{ 1.1378 + CK_RC2_CBC_PARAMS *rc2_params; 1.1379 + CK_RC2_PARAMS *rc2_ecb_params; 1.1380 + SECItem *mech; 1.1381 + SECItem iv; 1.1382 + SECStatus rv; 1.1383 + 1.1384 + 1.1385 + mech = (SECItem *) PORT_Alloc(sizeof(SECItem)); 1.1386 + if (mech == NULL) return NULL; 1.1387 + 1.1388 + rv = SECSuccess; 1.1389 + mech->type = siBuffer; 1.1390 + switch (type) { 1.1391 + case CKM_RC4: 1.1392 + case CKM_SEED_ECB: 1.1393 + case CKM_CAMELLIA_ECB: 1.1394 + case CKM_AES_ECB: 1.1395 + case CKM_DES_ECB: 1.1396 + case CKM_DES3_ECB: 1.1397 + case CKM_IDEA_ECB: 1.1398 + case CKM_CDMF_ECB: 1.1399 + case CKM_CAST_ECB: 1.1400 + case CKM_CAST3_ECB: 1.1401 + case CKM_CAST5_ECB: 1.1402 + mech->data = NULL; 1.1403 + mech->len = 0; 1.1404 + break; 1.1405 + case CKM_RC2_ECB: 1.1406 + rc2_ecb_params = (CK_RC2_PARAMS *)PORT_Alloc(sizeof(CK_RC2_PARAMS)); 1.1407 + if (rc2_ecb_params == NULL) { 1.1408 + rv = SECFailure; 1.1409 + break; 1.1410 + } 1.1411 + /* NOTE PK11_GetKeyLength can return -1 if the key isn't and RC2, RC5, 1.1412 + * or RC4 key. Of course that wouldn't happen here doing RC2:).*/ 1.1413 + *rc2_ecb_params = keyLen ? keyLen*8 : 128; 1.1414 + mech->data = (unsigned char *) rc2_ecb_params; 1.1415 + mech->len = sizeof(CK_RC2_PARAMS); 1.1416 + break; 1.1417 + case CKM_RC2_CBC: 1.1418 + case CKM_RC2_CBC_PAD: 1.1419 + rv = pk11_GenIV(type,&iv); 1.1420 + if (rv != SECSuccess) { 1.1421 + break; 1.1422 + } 1.1423 + rc2_params = (CK_RC2_CBC_PARAMS *)PORT_Alloc(sizeof(CK_RC2_CBC_PARAMS)); 1.1424 + if (rc2_params == NULL) { 1.1425 + PORT_Free(iv.data); 1.1426 + rv = SECFailure; 1.1427 + break; 1.1428 + } 1.1429 + /* NOTE PK11_GetKeyLength can return -1 if the key isn't and RC2, RC5, 1.1430 + * or RC4 key. Of course that wouldn't happen here doing RC2:).*/ 1.1431 + rc2_params->ulEffectiveBits = keyLen ? keyLen*8 : 128; 1.1432 + if (iv.data) 1.1433 + PORT_Memcpy(rc2_params->iv,iv.data,sizeof(rc2_params->iv)); 1.1434 + mech->data = (unsigned char *) rc2_params; 1.1435 + mech->len = sizeof(CK_RC2_CBC_PARAMS); 1.1436 + PORT_Free(iv.data); 1.1437 + break; 1.1438 + case CKM_RC5_ECB: 1.1439 + PORT_Free(mech); 1.1440 + return PK11_ParamFromIV(type,NULL); 1.1441 + case CKM_RC5_CBC: 1.1442 + case CKM_RC5_CBC_PAD: 1.1443 + rv = pk11_GenIV(type,&iv); 1.1444 + if (rv != SECSuccess) { 1.1445 + break; 1.1446 + } 1.1447 + PORT_Free(mech); 1.1448 + return PK11_ParamFromIV(type,&iv); 1.1449 + default: 1.1450 + if (pk11_lookup(type)->iv == 0) { 1.1451 + mech->data = NULL; 1.1452 + mech->len = 0; 1.1453 + break; 1.1454 + } 1.1455 + case CKM_SEED_CBC: 1.1456 + case CKM_CAMELLIA_CBC: 1.1457 + case CKM_AES_CBC: 1.1458 + case CKM_DES_CBC: 1.1459 + case CKM_DES3_CBC: 1.1460 + case CKM_IDEA_CBC: 1.1461 + case CKM_CDMF_CBC: 1.1462 + case CKM_CAST_CBC: 1.1463 + case CKM_CAST3_CBC: 1.1464 + case CKM_CAST5_CBC: 1.1465 + case CKM_DES_CBC_PAD: 1.1466 + case CKM_DES3_CBC_PAD: 1.1467 + case CKM_IDEA_CBC_PAD: 1.1468 + case CKM_CDMF_CBC_PAD: 1.1469 + case CKM_CAST_CBC_PAD: 1.1470 + case CKM_CAST3_CBC_PAD: 1.1471 + case CKM_CAST5_CBC_PAD: 1.1472 + case CKM_SKIPJACK_CBC64: 1.1473 + case CKM_SKIPJACK_ECB64: 1.1474 + case CKM_SKIPJACK_OFB64: 1.1475 + case CKM_SKIPJACK_CFB64: 1.1476 + case CKM_SKIPJACK_CFB32: 1.1477 + case CKM_SKIPJACK_CFB16: 1.1478 + case CKM_SKIPJACK_CFB8: 1.1479 + case CKM_BATON_ECB128: 1.1480 + case CKM_BATON_ECB96: 1.1481 + case CKM_BATON_CBC128: 1.1482 + case CKM_BATON_COUNTER: 1.1483 + case CKM_BATON_SHUFFLE: 1.1484 + case CKM_JUNIPER_ECB128: 1.1485 + case CKM_JUNIPER_CBC128: 1.1486 + case CKM_JUNIPER_COUNTER: 1.1487 + case CKM_JUNIPER_SHUFFLE: 1.1488 + rv = pk11_GenIV(type,&iv); 1.1489 + if (rv != SECSuccess) { 1.1490 + break; 1.1491 + } 1.1492 + mech->data = (unsigned char*)PORT_Alloc(iv.len); 1.1493 + if (mech->data == NULL) { 1.1494 + PORT_Free(iv.data); 1.1495 + rv = SECFailure; 1.1496 + break; 1.1497 + } 1.1498 + PORT_Memcpy(mech->data,iv.data,iv.len); 1.1499 + mech->len = iv.len; 1.1500 + PORT_Free(iv.data); 1.1501 + break; 1.1502 + } 1.1503 + if (rv != SECSuccess) { 1.1504 + SECITEM_FreeItem(mech,PR_TRUE); 1.1505 + return NULL; 1.1506 + } 1.1507 + return mech; 1.1508 + 1.1509 +} 1.1510 + 1.1511 +SECItem * 1.1512 +PK11_GenerateNewParam(CK_MECHANISM_TYPE type, PK11SymKey *key) 1.1513 +{ 1.1514 + int keyLen = key ? PK11_GetKeyLength(key) : 0; 1.1515 + 1.1516 + return pk11_GenerateNewParamWithKeyLen(type, keyLen); 1.1517 +} 1.1518 + 1.1519 +#define RC5_V10 0x10 1.1520 + 1.1521 +/* turn a PKCS #11 parameter into a DER Encoded Algorithm ID */ 1.1522 +SECStatus 1.1523 +PK11_ParamToAlgid(SECOidTag algTag, SECItem *param, 1.1524 + PLArenaPool *arena, SECAlgorithmID *algid) { 1.1525 + CK_RC2_CBC_PARAMS *rc2_params; 1.1526 + sec_rc2cbcParameter rc2; 1.1527 + CK_RC5_CBC_PARAMS *rc5_params; 1.1528 + sec_rc5cbcParameter rc5; 1.1529 + CK_MECHANISM_TYPE type = PK11_AlgtagToMechanism(algTag); 1.1530 + SECItem *newParams = NULL; 1.1531 + SECStatus rv = SECFailure; 1.1532 + unsigned long rc2version; 1.1533 + 1.1534 + switch (type) { 1.1535 + case CKM_RC4: 1.1536 + case CKM_SEED_ECB: 1.1537 + case CKM_CAMELLIA_ECB: 1.1538 + case CKM_AES_ECB: 1.1539 + case CKM_DES_ECB: 1.1540 + case CKM_DES3_ECB: 1.1541 + case CKM_IDEA_ECB: 1.1542 + case CKM_CDMF_ECB: 1.1543 + case CKM_CAST_ECB: 1.1544 + case CKM_CAST3_ECB: 1.1545 + case CKM_CAST5_ECB: 1.1546 + newParams = NULL; 1.1547 + rv = SECSuccess; 1.1548 + break; 1.1549 + case CKM_RC2_ECB: 1.1550 + break; 1.1551 + case CKM_RC2_CBC: 1.1552 + case CKM_RC2_CBC_PAD: 1.1553 + rc2_params = (CK_RC2_CBC_PARAMS *)param->data; 1.1554 + rc2version = rc2_unmap(rc2_params->ulEffectiveBits); 1.1555 + if (SEC_ASN1EncodeUnsignedInteger (NULL, &(rc2.rc2ParameterVersion), 1.1556 + rc2version) == NULL) 1.1557 + break; 1.1558 + rc2.iv.data = rc2_params->iv; 1.1559 + rc2.iv.len = sizeof(rc2_params->iv); 1.1560 + newParams = SEC_ASN1EncodeItem (NULL, NULL, &rc2, 1.1561 + sec_rc2cbc_parameter_template); 1.1562 + PORT_Free(rc2.rc2ParameterVersion.data); 1.1563 + if (newParams == NULL) 1.1564 + break; 1.1565 + rv = SECSuccess; 1.1566 + break; 1.1567 + 1.1568 + case CKM_RC5_ECB: /* well not really... */ 1.1569 + break; 1.1570 + case CKM_RC5_CBC: 1.1571 + case CKM_RC5_CBC_PAD: 1.1572 + rc5_params = (CK_RC5_CBC_PARAMS *)param->data; 1.1573 + if (SEC_ASN1EncodeUnsignedInteger (NULL, &rc5.version, RC5_V10) == NULL) 1.1574 + break; 1.1575 + if (SEC_ASN1EncodeUnsignedInteger (NULL, &rc5.blockSizeInBits, 1.1576 + rc5_params->ulWordsize*8) == NULL) { 1.1577 + PORT_Free(rc5.version.data); 1.1578 + break; 1.1579 + } 1.1580 + if (SEC_ASN1EncodeUnsignedInteger (NULL, &rc5.rounds, 1.1581 + rc5_params->ulWordsize*8) == NULL) { 1.1582 + PORT_Free(rc5.blockSizeInBits.data); 1.1583 + PORT_Free(rc5.version.data); 1.1584 + break; 1.1585 + } 1.1586 + rc5.iv.data = rc5_params->pIv; 1.1587 + rc5.iv.len = rc5_params->ulIvLen; 1.1588 + newParams = SEC_ASN1EncodeItem (NULL, NULL, &rc5, 1.1589 + sec_rc5cbc_parameter_template); 1.1590 + PORT_Free(rc5.version.data); 1.1591 + PORT_Free(rc5.blockSizeInBits.data); 1.1592 + PORT_Free(rc5.rounds.data); 1.1593 + if (newParams == NULL) 1.1594 + break; 1.1595 + rv = SECSuccess; 1.1596 + break; 1.1597 + case CKM_PBE_MD2_DES_CBC: 1.1598 + case CKM_PBE_MD5_DES_CBC: 1.1599 + case CKM_NETSCAPE_PBE_SHA1_DES_CBC: 1.1600 + case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC: 1.1601 + case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC: 1.1602 + case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC: 1.1603 + case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC: 1.1604 + case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4: 1.1605 + case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4: 1.1606 + case CKM_PBE_SHA1_DES3_EDE_CBC: 1.1607 + case CKM_PBE_SHA1_DES2_EDE_CBC: 1.1608 + case CKM_PBE_SHA1_RC2_40_CBC: 1.1609 + case CKM_PBE_SHA1_RC2_128_CBC: 1.1610 + case CKM_PBE_SHA1_RC4_40: 1.1611 + case CKM_PBE_SHA1_RC4_128: 1.1612 + return PBE_PK11ParamToAlgid(algTag, param, arena, algid); 1.1613 + default: 1.1614 + if (pk11_lookup(type)->iv == 0) { 1.1615 + rv = SECSuccess; 1.1616 + newParams = NULL; 1.1617 + break; 1.1618 + } 1.1619 + case CKM_SEED_CBC: 1.1620 + case CKM_CAMELLIA_CBC: 1.1621 + case CKM_AES_CBC: 1.1622 + case CKM_DES_CBC: 1.1623 + case CKM_DES3_CBC: 1.1624 + case CKM_IDEA_CBC: 1.1625 + case CKM_CDMF_CBC: 1.1626 + case CKM_CAST_CBC: 1.1627 + case CKM_CAST3_CBC: 1.1628 + case CKM_CAST5_CBC: 1.1629 + case CKM_DES_CBC_PAD: 1.1630 + case CKM_DES3_CBC_PAD: 1.1631 + case CKM_IDEA_CBC_PAD: 1.1632 + case CKM_CDMF_CBC_PAD: 1.1633 + case CKM_CAST_CBC_PAD: 1.1634 + case CKM_CAST3_CBC_PAD: 1.1635 + case CKM_CAST5_CBC_PAD: 1.1636 + case CKM_SKIPJACK_CBC64: 1.1637 + case CKM_SKIPJACK_ECB64: 1.1638 + case CKM_SKIPJACK_OFB64: 1.1639 + case CKM_SKIPJACK_CFB64: 1.1640 + case CKM_SKIPJACK_CFB32: 1.1641 + case CKM_SKIPJACK_CFB16: 1.1642 + case CKM_SKIPJACK_CFB8: 1.1643 + case CKM_BATON_ECB128: 1.1644 + case CKM_BATON_ECB96: 1.1645 + case CKM_BATON_CBC128: 1.1646 + case CKM_BATON_COUNTER: 1.1647 + case CKM_BATON_SHUFFLE: 1.1648 + case CKM_JUNIPER_ECB128: 1.1649 + case CKM_JUNIPER_CBC128: 1.1650 + case CKM_JUNIPER_COUNTER: 1.1651 + case CKM_JUNIPER_SHUFFLE: 1.1652 + newParams = SEC_ASN1EncodeItem(NULL,NULL,param, 1.1653 + SEC_ASN1_GET(SEC_OctetStringTemplate) ); 1.1654 + if (newParams == NULL) 1.1655 + break; 1.1656 + rv = SECSuccess; 1.1657 + break; 1.1658 + } 1.1659 + 1.1660 + if (rv != SECSuccess) { 1.1661 + if (newParams) SECITEM_FreeItem(newParams,PR_TRUE); 1.1662 + return rv; 1.1663 + } 1.1664 + 1.1665 + rv = SECOID_SetAlgorithmID(arena, algid, algTag, newParams); 1.1666 + SECITEM_FreeItem(newParams,PR_TRUE); 1.1667 + return rv; 1.1668 +} 1.1669 + 1.1670 +/* turn an OID algorithm tag into a PKCS #11 mechanism. This allows us to 1.1671 + * map OID's directly into the PKCS #11 mechanism we want to call. We find 1.1672 + * this mapping in our standard OID table */ 1.1673 +CK_MECHANISM_TYPE 1.1674 +PK11_AlgtagToMechanism(SECOidTag algTag) { 1.1675 + SECOidData *oid = SECOID_FindOIDByTag(algTag); 1.1676 + 1.1677 + if (oid) return (CK_MECHANISM_TYPE) oid->mechanism; 1.1678 + return CKM_INVALID_MECHANISM; 1.1679 +} 1.1680 + 1.1681 +/* turn a mechanism into an oid. */ 1.1682 +SECOidTag 1.1683 +PK11_MechanismToAlgtag(CK_MECHANISM_TYPE type) { 1.1684 + SECOidData *oid = SECOID_FindOIDByMechanism((unsigned long)type); 1.1685 + 1.1686 + if (oid) return oid->offset; 1.1687 + return SEC_OID_UNKNOWN; 1.1688 +} 1.1689 + 1.1690 +/* Determine appropriate blocking mechanism, used when wrapping private keys 1.1691 + * which require PKCS padding. If the mechanism does not map to a padding 1.1692 + * mechanism, we simply return the mechanism. 1.1693 + */ 1.1694 +CK_MECHANISM_TYPE 1.1695 +PK11_GetPadMechanism(CK_MECHANISM_TYPE type) { 1.1696 + switch(type) { 1.1697 + case CKM_SEED_CBC: 1.1698 + return CKM_SEED_CBC_PAD; 1.1699 + case CKM_CAMELLIA_CBC: 1.1700 + return CKM_CAMELLIA_CBC_PAD; 1.1701 + case CKM_AES_CBC: 1.1702 + return CKM_AES_CBC_PAD; 1.1703 + case CKM_DES_CBC: 1.1704 + return CKM_DES_CBC_PAD; 1.1705 + case CKM_DES3_CBC: 1.1706 + return CKM_DES3_CBC_PAD; 1.1707 + case CKM_RC2_CBC: 1.1708 + return CKM_RC2_CBC_PAD; 1.1709 + case CKM_CDMF_CBC: 1.1710 + return CKM_CDMF_CBC_PAD; 1.1711 + case CKM_CAST_CBC: 1.1712 + return CKM_CAST_CBC_PAD; 1.1713 + case CKM_CAST3_CBC: 1.1714 + return CKM_CAST3_CBC_PAD; 1.1715 + case CKM_CAST5_CBC: 1.1716 + return CKM_CAST5_CBC_PAD; 1.1717 + case CKM_RC5_CBC: 1.1718 + return CKM_RC5_CBC_PAD; 1.1719 + case CKM_IDEA_CBC: 1.1720 + return CKM_IDEA_CBC_PAD; 1.1721 + default: 1.1722 + break; 1.1723 + } 1.1724 + 1.1725 + return type; 1.1726 +} 1.1727 + 1.1728 +static PRBool 1.1729 +pk11_isAllZero(unsigned char *data,int len) { 1.1730 + while (len--) { 1.1731 + if (*data++) { 1.1732 + return PR_FALSE; 1.1733 + } 1.1734 + } 1.1735 + return PR_TRUE; 1.1736 +} 1.1737 + 1.1738 +CK_RV 1.1739 +PK11_MapPBEMechanismToCryptoMechanism(CK_MECHANISM_PTR pPBEMechanism, 1.1740 + CK_MECHANISM_PTR pCryptoMechanism, 1.1741 + SECItem *pbe_pwd, PRBool faulty3DES) 1.1742 +{ 1.1743 + int iv_len = 0; 1.1744 + CK_PBE_PARAMS_PTR pPBEparams; 1.1745 + CK_RC2_CBC_PARAMS_PTR rc2_params; 1.1746 + CK_ULONG rc2_key_len; 1.1747 + 1.1748 + if((pPBEMechanism == CK_NULL_PTR) || (pCryptoMechanism == CK_NULL_PTR)) { 1.1749 + return CKR_HOST_MEMORY; 1.1750 + } 1.1751 + 1.1752 + /* pkcs5 v2 cannot be supported by this interface. 1.1753 + * use PK11_GetPBECryptoMechanism instead. 1.1754 + */ 1.1755 + if ((pPBEMechanism->mechanism == CKM_INVALID_MECHANISM) || 1.1756 + (pPBEMechanism->mechanism == CKM_PKCS5_PBKD2)) { 1.1757 + return CKR_MECHANISM_INVALID; 1.1758 + } 1.1759 + 1.1760 + pPBEparams = (CK_PBE_PARAMS_PTR)pPBEMechanism->pParameter; 1.1761 + iv_len = PK11_GetIVLength(pPBEMechanism->mechanism); 1.1762 + 1.1763 + if (iv_len) { 1.1764 + if (pk11_isAllZero(pPBEparams->pInitVector,iv_len)) { 1.1765 + SECItem param; 1.1766 + PK11SymKey *symKey; 1.1767 + PK11SlotInfo *intSlot = PK11_GetInternalSlot(); 1.1768 + 1.1769 + if (intSlot == NULL) { 1.1770 + return CKR_DEVICE_ERROR; 1.1771 + } 1.1772 + 1.1773 + param.data = pPBEMechanism->pParameter; 1.1774 + param.len = pPBEMechanism->ulParameterLen; 1.1775 + 1.1776 + symKey = PK11_RawPBEKeyGen(intSlot, 1.1777 + pPBEMechanism->mechanism, ¶m, pbe_pwd, faulty3DES, NULL); 1.1778 + PK11_FreeSlot(intSlot); 1.1779 + if (symKey== NULL) { 1.1780 + return CKR_DEVICE_ERROR; /* sigh */ 1.1781 + } 1.1782 + PK11_FreeSymKey(symKey); 1.1783 + } 1.1784 + } 1.1785 + 1.1786 + switch(pPBEMechanism->mechanism) { 1.1787 + case CKM_PBE_MD2_DES_CBC: 1.1788 + case CKM_PBE_MD5_DES_CBC: 1.1789 + case CKM_NETSCAPE_PBE_SHA1_DES_CBC: 1.1790 + pCryptoMechanism->mechanism = CKM_DES_CBC; 1.1791 + goto have_crypto_mechanism; 1.1792 + case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC: 1.1793 + case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC: 1.1794 + case CKM_PBE_SHA1_DES3_EDE_CBC: 1.1795 + case CKM_PBE_SHA1_DES2_EDE_CBC: 1.1796 + pCryptoMechanism->mechanism = CKM_DES3_CBC; 1.1797 +have_crypto_mechanism: 1.1798 + pCryptoMechanism->pParameter = PORT_Alloc(iv_len); 1.1799 + pCryptoMechanism->ulParameterLen = (CK_ULONG)iv_len; 1.1800 + if(pCryptoMechanism->pParameter == NULL) { 1.1801 + return CKR_HOST_MEMORY; 1.1802 + } 1.1803 + PORT_Memcpy((unsigned char *)(pCryptoMechanism->pParameter), 1.1804 + (unsigned char *)(pPBEparams->pInitVector), 1.1805 + iv_len); 1.1806 + break; 1.1807 + case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4: 1.1808 + case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4: 1.1809 + case CKM_PBE_SHA1_RC4_40: 1.1810 + case CKM_PBE_SHA1_RC4_128: 1.1811 + pCryptoMechanism->mechanism = CKM_RC4; 1.1812 + pCryptoMechanism->ulParameterLen = 0; 1.1813 + pCryptoMechanism->pParameter = CK_NULL_PTR; 1.1814 + break; 1.1815 + case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC: 1.1816 + case CKM_PBE_SHA1_RC2_40_CBC: 1.1817 + rc2_key_len = 40; 1.1818 + goto have_key_len; 1.1819 + case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC: 1.1820 + rc2_key_len = 128; 1.1821 +have_key_len: 1.1822 + pCryptoMechanism->mechanism = CKM_RC2_CBC; 1.1823 + pCryptoMechanism->ulParameterLen = (CK_ULONG) 1.1824 + sizeof(CK_RC2_CBC_PARAMS); 1.1825 + pCryptoMechanism->pParameter = (CK_RC2_CBC_PARAMS_PTR) 1.1826 + PORT_ZAlloc(sizeof(CK_RC2_CBC_PARAMS)); 1.1827 + if(pCryptoMechanism->pParameter == NULL) { 1.1828 + return CKR_HOST_MEMORY; 1.1829 + } 1.1830 + rc2_params = (CK_RC2_CBC_PARAMS_PTR)pCryptoMechanism->pParameter; 1.1831 + PORT_Memcpy((unsigned char *)rc2_params->iv, 1.1832 + (unsigned char *)pPBEparams->pInitVector, 1.1833 + iv_len); 1.1834 + rc2_params->ulEffectiveBits = rc2_key_len; 1.1835 + break; 1.1836 + default: 1.1837 + return CKR_MECHANISM_INVALID; 1.1838 + } 1.1839 + 1.1840 + return CKR_OK; 1.1841 +} 1.1842 + 1.1843 +/* Make a Key type to an appropriate signing/verification mechanism */ 1.1844 +CK_MECHANISM_TYPE 1.1845 +PK11_MapSignKeyType(KeyType keyType) 1.1846 +{ 1.1847 + switch (keyType) { 1.1848 + case rsaKey: 1.1849 + return CKM_RSA_PKCS; 1.1850 + case fortezzaKey: 1.1851 + case dsaKey: 1.1852 + return CKM_DSA; 1.1853 + case ecKey: 1.1854 + return CKM_ECDSA; 1.1855 + case dhKey: 1.1856 + default: 1.1857 + break; 1.1858 + } 1.1859 + return CKM_INVALID_MECHANISM; 1.1860 +} 1.1861 + 1.1862 +CK_MECHANISM_TYPE 1.1863 +pk11_mapWrapKeyType(KeyType keyType) 1.1864 +{ 1.1865 + switch (keyType) { 1.1866 + case rsaKey: 1.1867 + return CKM_RSA_PKCS; 1.1868 + /* Add fortezza?? */ 1.1869 + default: 1.1870 + break; 1.1871 + } 1.1872 + return CKM_INVALID_MECHANISM; 1.1873 +} 1.1874 + 1.1875 +SECOidTag 1.1876 +PK11_FortezzaMapSig(SECOidTag algTag) 1.1877 +{ 1.1878 + switch (algTag) { 1.1879 + case SEC_OID_MISSI_KEA_DSS: 1.1880 + case SEC_OID_MISSI_DSS: 1.1881 + case SEC_OID_MISSI_DSS_OLD: 1.1882 + case SEC_OID_MISSI_KEA_DSS_OLD: 1.1883 + case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST: 1.1884 + return SEC_OID_ANSIX9_DSA_SIGNATURE; 1.1885 + default: 1.1886 + break; 1.1887 + } 1.1888 + return algTag; 1.1889 +}