/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * This file maps various PKCS #11 Mechanisms to related mechanisms, key * types, and ASN.1 encodings.
*/ #include"seccomon.h" #include"secmod.h" #include"secmodi.h" #include"pkcs11t.h" #include"pk11func.h" #include"secitem.h" #include"secder.h" #include"secasn1.h" #include"secoid.h" #include"secerr.h"
/************************************************************* * local static and global data
*************************************************************/
/* * Tables used for Extended mechanism mapping (currently not used)
*/ typedefstruct {
CK_MECHANISM_TYPE keyGen;
CK_KEY_TYPE keyType;
CK_MECHANISM_TYPE type;
CK_MECHANISM_TYPE padType; int blockSize; int iv;
} pk11MechanismData;
/* * lookup an entry in the mechanism table. If none found, return the * default structure.
*/ static pk11MechanismData *
pk11_lookup(CK_MECHANISM_TYPE type)
{ int i; for (i = 0; i < pk11_MechEntrySize; i++) { if (pk11_MechanismTable[i].type == type) { return (&pk11_MechanismTable[i]);
}
} return &pk11_default;
}
/* * find the best key wrap mechanism for this slot.
*/
CK_MECHANISM_TYPE
PK11_GetBestWrapMechanism(PK11SlotInfo *slot)
{ int i; for (i = 0; i < wrapMechanismCount; i++) { if (PK11_DoesMechanism(slot, wrapMechanismList[i])) { return wrapMechanismList[i];
}
} return CKM_INVALID_MECHANISM;
}
/* * NOTE: This is not thread safe. Called at init time, and when loading * a new Entry. It is reasonably safe as long as it is not re-entered * (readers will always see a consistant table) * * This routine is called to add entries to the mechanism table, once there, * they can not be removed.
*/ void
PK11_AddMechanismEntry(CK_MECHANISM_TYPE type, CK_KEY_TYPE key,
CK_MECHANISM_TYPE keyGen,
CK_MECHANISM_TYPE padType, int ivLen, int blockSize)
{ int tableSize = pk11_MechTableSize; int size = pk11_MechEntrySize; int entry = size++;
pk11MechanismData *old = pk11_MechanismTable;
pk11MechanismData *newt = pk11_MechanismTable;
if (size > tableSize) { int oldTableSize = tableSize;
tableSize += 10;
newt = PORT_NewArray(pk11MechanismData, tableSize); if (newt == NULL) return;
if (old)
PORT_Memcpy(newt, old, oldTableSize * sizeof(*newt));
} else
old = NULL;
/* * Get the mechanism needed for the given key type
*/
CK_MECHANISM_TYPE
PK11_GetKeyMechanism(CK_KEY_TYPE type)
{ switch (type) { case CKK_SEED: return CKM_SEED_CBC; case CKK_CAMELLIA: return CKM_CAMELLIA_CBC; case CKK_NSS_CHACHA20: return CKM_NSS_CHACHA20_POLY1305; case CKK_CHACHA20: return CKM_CHACHA20_POLY1305; case CKK_AES: return CKM_AES_CBC; case CKK_DES: return CKM_DES_CBC; case CKK_DES3: return CKM_DES3_KEY_GEN; case CKK_DES2: return CKM_DES2_KEY_GEN; case CKK_CDMF: return CKM_CDMF_CBC; case CKK_RC2: return CKM_RC2_CBC; case CKK_RC4: return CKM_RC4; case CKK_RC5: return CKM_RC5_CBC; case CKK_SKIPJACK: return CKM_SKIPJACK_CBC64; case CKK_BATON: return CKM_BATON_CBC128; case CKK_JUNIPER: return CKM_JUNIPER_CBC128; case CKK_IDEA: return CKM_IDEA_CBC; case CKK_CAST: return CKM_CAST_CBC; case CKK_CAST3: return CKM_CAST3_CBC; case CKK_CAST5: return CKM_CAST5_CBC; case CKK_RSA: return CKM_RSA_PKCS; case CKK_DSA: return CKM_DSA; case CKK_DH: return CKM_DH_PKCS_DERIVE; case CKK_KEA: return CKM_KEA_KEY_DERIVE; case CKK_EC: /* CKK_ECDSA is deprecated */ return CKM_ECDSA; case CKK_EC_EDWARDS: return CKM_EDDSA; case CKK_HKDF: return CKM_HKDF_DERIVE; case CKK_GENERIC_SECRET: default: return CKM_SHA_1_HMAC;
}
}
/* * Get the key type needed for the given mechanism
*/
CK_KEY_TYPE
PK11_GetKeyType(CK_MECHANISM_TYPE type, unsignedlong len)
{ switch (type) { case CKM_SEED_ECB: case CKM_SEED_CBC: case CKM_SEED_MAC: case CKM_SEED_MAC_GENERAL: case CKM_SEED_CBC_PAD: case CKM_SEED_KEY_GEN: return CKK_SEED; case CKM_CAMELLIA_ECB: case CKM_CAMELLIA_CBC: case CKM_CAMELLIA_MAC: case CKM_CAMELLIA_MAC_GENERAL: case CKM_CAMELLIA_CBC_PAD: case CKM_CAMELLIA_KEY_GEN: return CKK_CAMELLIA; case CKM_NSS_CHACHA20_POLY1305: case CKM_NSS_CHACHA20_KEY_GEN: case CKM_NSS_CHACHA20_CTR: return CKK_NSS_CHACHA20; case CKM_CHACHA20_POLY1305: case CKM_CHACHA20_KEY_GEN: case CKM_CHACHA20: return CKK_CHACHA20; case CKM_AES_ECB: case CKM_AES_CBC: case CKM_AES_CCM: case CKM_AES_CTR: case CKM_AES_CTS: case CKM_AES_GCM: case CKM_AES_MAC: case CKM_AES_MAC_GENERAL: case CKM_AES_CMAC: case CKM_AES_CMAC_GENERAL: case CKM_AES_CBC_PAD: case CKM_AES_KEY_GEN: case CKM_NSS_AES_KEY_WRAP: case CKM_NSS_AES_KEY_WRAP_PAD: case CKM_AES_KEY_WRAP: case CKM_AES_KEY_WRAP_KWP: case CKM_AES_XCBC_MAC: case CKM_AES_XCBC_MAC_96: return CKK_AES; case CKM_DES_ECB: case CKM_DES_CBC: case CKM_DES_MAC: case CKM_DES_MAC_GENERAL: case CKM_DES_CBC_PAD: case CKM_DES_KEY_GEN: case CKM_KEY_WRAP_LYNKS: case CKM_PBE_MD2_DES_CBC: case CKM_PBE_MD5_DES_CBC: return CKK_DES; case CKM_DES3_ECB: case CKM_DES3_CBC: case CKM_DES3_MAC: case CKM_DES3_MAC_GENERAL: case CKM_DES3_CBC_PAD: return (len == 16) ? CKK_DES2 : CKK_DES3; case CKM_DES2_KEY_GEN: case CKM_PBE_SHA1_DES2_EDE_CBC: return CKK_DES2; case CKM_PBE_SHA1_DES3_EDE_CBC: case CKM_DES3_KEY_GEN: return CKK_DES3; case CKM_CDMF_ECB: case CKM_CDMF_CBC: case CKM_CDMF_MAC: case CKM_CDMF_MAC_GENERAL: case CKM_CDMF_CBC_PAD: case CKM_CDMF_KEY_GEN: return CKK_CDMF; case CKM_RC2_ECB: case CKM_RC2_CBC: case CKM_RC2_MAC: case CKM_RC2_MAC_GENERAL: case CKM_RC2_CBC_PAD: case CKM_RC2_KEY_GEN: case CKM_PBE_SHA1_RC2_128_CBC: case CKM_PBE_SHA1_RC2_40_CBC: return CKK_RC2; case CKM_RC4: case CKM_RC4_KEY_GEN: return CKK_RC4; case CKM_RC5_ECB: case CKM_RC5_CBC: case CKM_RC5_MAC: case CKM_RC5_MAC_GENERAL: case CKM_RC5_CBC_PAD: case CKM_RC5_KEY_GEN: return CKK_RC5; case CKM_SKIPJACK_CBC64: case CKM_SKIPJACK_ECB64: case CKM_SKIPJACK_OFB64: case CKM_SKIPJACK_CFB64: case CKM_SKIPJACK_CFB32: case CKM_SKIPJACK_CFB16: case CKM_SKIPJACK_CFB8: case CKM_SKIPJACK_KEY_GEN: case CKM_SKIPJACK_WRAP: case CKM_SKIPJACK_PRIVATE_WRAP: return CKK_SKIPJACK; case CKM_BATON_ECB128: case CKM_BATON_ECB96: case CKM_BATON_CBC128: case CKM_BATON_COUNTER: case CKM_BATON_SHUFFLE: case CKM_BATON_WRAP: case CKM_BATON_KEY_GEN: return CKK_BATON; case CKM_JUNIPER_ECB128: case CKM_JUNIPER_CBC128: case CKM_JUNIPER_COUNTER: case CKM_JUNIPER_SHUFFLE: case CKM_JUNIPER_WRAP: case CKM_JUNIPER_KEY_GEN: return CKK_JUNIPER; case CKM_IDEA_CBC: case CKM_IDEA_ECB: case CKM_IDEA_MAC: case CKM_IDEA_MAC_GENERAL: case CKM_IDEA_CBC_PAD: case CKM_IDEA_KEY_GEN: return CKK_IDEA; case CKM_CAST_ECB: case CKM_CAST_CBC: case CKM_CAST_MAC: case CKM_CAST_MAC_GENERAL: case CKM_CAST_CBC_PAD: case CKM_CAST_KEY_GEN: case CKM_PBE_MD5_CAST_CBC: return CKK_CAST; case CKM_CAST3_ECB: case CKM_CAST3_CBC: case CKM_CAST3_MAC: case CKM_CAST3_MAC_GENERAL: case CKM_CAST3_CBC_PAD: case CKM_CAST3_KEY_GEN: case CKM_PBE_MD5_CAST3_CBC: return CKK_CAST3; case CKM_CAST5_ECB: case CKM_CAST5_CBC: case CKM_CAST5_MAC: case CKM_CAST5_MAC_GENERAL: case CKM_CAST5_CBC_PAD: case CKM_CAST5_KEY_GEN: case CKM_PBE_MD5_CAST5_CBC: return CKK_CAST5; case CKM_RSA_PKCS: case CKM_RSA_9796: case CKM_RSA_X_509: case CKM_MD2_RSA_PKCS: case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: case CKM_SHA224_RSA_PKCS: case CKM_SHA256_RSA_PKCS: case CKM_SHA384_RSA_PKCS: case CKM_SHA512_RSA_PKCS: case CKM_KEY_WRAP_SET_OAEP: case CKM_RSA_PKCS_KEY_PAIR_GEN: case CKM_RSA_X9_31_KEY_PAIR_GEN: return CKK_RSA; case CKM_DSA: case CKM_DSA_SHA1: case CKM_DSA_KEY_PAIR_GEN: return CKK_DSA; case CKM_DH_PKCS_DERIVE: case CKM_DH_PKCS_KEY_PAIR_GEN: return CKK_DH; case CKM_KEA_KEY_DERIVE: case CKM_KEA_KEY_PAIR_GEN: return CKK_KEA; case CKM_ECDSA: case CKM_ECDSA_SHA1: case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */ case CKM_ECDH1_DERIVE: return CKK_EC; /* CKK_ECDSA is deprecated */ case CKM_EC_EDWARDS_KEY_PAIR_GEN: case CKM_EDDSA: return CKK_EC_EDWARDS; case CKM_HKDF_KEY_GEN: case CKM_HKDF_DERIVE: case CKM_HKDF_DATA: return CKK_HKDF; case CKM_SSL3_PRE_MASTER_KEY_GEN: case CKM_GENERIC_SECRET_KEY_GEN: case CKM_SSL3_MASTER_KEY_DERIVE: case CKM_SSL3_MASTER_KEY_DERIVE_DH: case CKM_SSL3_KEY_AND_MAC_DERIVE: case CKM_SSL3_SHA1_MAC: case CKM_SSL3_MD5_MAC: case CKM_TLS_MASTER_KEY_DERIVE: case CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256: case CKM_TLS_MASTER_KEY_DERIVE_DH: case CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256: case CKM_TLS_KEY_AND_MAC_DERIVE: case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256: case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE: case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH: case CKM_SHA_1_HMAC: case CKM_SHA_1_HMAC_GENERAL: case CKM_SHA224_HMAC: case CKM_SHA224_HMAC_GENERAL: case CKM_SHA256_HMAC: case CKM_SHA256_HMAC_GENERAL: case CKM_SHA384_HMAC: case CKM_SHA384_HMAC_GENERAL: case CKM_SHA512_HMAC: case CKM_SHA512_HMAC_GENERAL: case CKM_MD2_HMAC: case CKM_MD2_HMAC_GENERAL: case CKM_MD5_HMAC: case CKM_MD5_HMAC_GENERAL: case CKM_TLS_PRF_GENERAL: case CKM_NSS_TLS_PRF_GENERAL_SHA256: return CKK_GENERIC_SECRET; case CKM_NSS_KYBER_KEY_PAIR_GEN: return CKK_NSS_KYBER; case CKM_NSS_ML_KEM_KEY_PAIR_GEN: return CKK_NSS_ML_KEM; default: return pk11_lookup(type)->keyType;
}
}
/* * Get the Key Gen Mechanism needed for the given * crypto mechanism
*/
CK_MECHANISM_TYPE
PK11_GetKeyGen(CK_MECHANISM_TYPE type)
{ return PK11_GetKeyGenWithSize(type, 0);
}
CK_MECHANISM_TYPE
PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size)
{ switch (type) { case CKM_SEED_ECB: case CKM_SEED_CBC: case CKM_SEED_MAC: case CKM_SEED_MAC_GENERAL: case CKM_SEED_CBC_PAD: case CKM_SEED_KEY_GEN: return CKM_SEED_KEY_GEN; case CKM_CAMELLIA_ECB: case CKM_CAMELLIA_CBC: case CKM_CAMELLIA_MAC: case CKM_CAMELLIA_MAC_GENERAL: case CKM_CAMELLIA_CBC_PAD: case CKM_CAMELLIA_KEY_GEN: return CKM_CAMELLIA_KEY_GEN; case CKM_NSS_CHACHA20_POLY1305: case CKM_NSS_CHACHA20_CTR: return CKM_NSS_CHACHA20_KEY_GEN; case CKM_CHACHA20_POLY1305: case CKM_CHACHA20: return CKM_CHACHA20_KEY_GEN; case CKM_AES_ECB: case CKM_AES_CBC: case CKM_AES_CCM: case CKM_AES_CTR: case CKM_AES_CTS: case CKM_AES_GCM: case CKM_AES_MAC: case CKM_AES_MAC_GENERAL: case CKM_AES_CMAC: case CKM_AES_CMAC_GENERAL: case CKM_AES_CBC_PAD: case CKM_AES_KEY_GEN: return CKM_AES_KEY_GEN; case CKM_DES_ECB: case CKM_DES_CBC: case CKM_DES_MAC: case CKM_DES_MAC_GENERAL: case CKM_KEY_WRAP_LYNKS: case CKM_DES_CBC_PAD: case CKM_DES_KEY_GEN: return CKM_DES_KEY_GEN; case CKM_DES3_ECB: case CKM_DES3_CBC: case CKM_DES3_MAC: case CKM_DES3_MAC_GENERAL: case CKM_DES3_CBC_PAD: return (size == 16) ? CKM_DES2_KEY_GEN : CKM_DES3_KEY_GEN; case CKM_DES3_KEY_GEN: return CKM_DES3_KEY_GEN; case CKM_DES2_KEY_GEN: return CKM_DES2_KEY_GEN; case CKM_CDMF_ECB: case CKM_CDMF_CBC: case CKM_CDMF_MAC: case CKM_CDMF_MAC_GENERAL: case CKM_CDMF_CBC_PAD: case CKM_CDMF_KEY_GEN: return CKM_CDMF_KEY_GEN; case CKM_RC2_ECB: case CKM_RC2_CBC: case CKM_RC2_MAC: case CKM_RC2_MAC_GENERAL: case CKM_RC2_CBC_PAD: case CKM_RC2_KEY_GEN: return CKM_RC2_KEY_GEN; case CKM_RC4: case CKM_RC4_KEY_GEN: return CKM_RC4_KEY_GEN; case CKM_RC5_ECB: case CKM_RC5_CBC: case CKM_RC5_MAC: case CKM_RC5_MAC_GENERAL: case CKM_RC5_CBC_PAD: case CKM_RC5_KEY_GEN: return CKM_RC5_KEY_GEN; case CKM_SKIPJACK_CBC64: case CKM_SKIPJACK_ECB64: case CKM_SKIPJACK_OFB64: case CKM_SKIPJACK_CFB64: case CKM_SKIPJACK_CFB32: case CKM_SKIPJACK_CFB16: case CKM_SKIPJACK_CFB8: case CKM_SKIPJACK_WRAP: case CKM_SKIPJACK_KEY_GEN: return CKM_SKIPJACK_KEY_GEN; case CKM_BATON_ECB128: case CKM_BATON_ECB96: case CKM_BATON_CBC128: case CKM_BATON_COUNTER: case CKM_BATON_SHUFFLE: case CKM_BATON_WRAP: case CKM_BATON_KEY_GEN: return CKM_BATON_KEY_GEN; case CKM_JUNIPER_ECB128: case CKM_JUNIPER_CBC128: case CKM_JUNIPER_COUNTER: case CKM_JUNIPER_SHUFFLE: case CKM_JUNIPER_WRAP: case CKM_JUNIPER_KEY_GEN: return CKM_JUNIPER_KEY_GEN; case CKM_IDEA_CBC: case CKM_IDEA_ECB: case CKM_IDEA_MAC: case CKM_IDEA_MAC_GENERAL: case CKM_IDEA_CBC_PAD: case CKM_IDEA_KEY_GEN: return CKM_IDEA_KEY_GEN; case CKM_CAST_ECB: case CKM_CAST_CBC: case CKM_CAST_MAC: case CKM_CAST_MAC_GENERAL: case CKM_CAST_CBC_PAD: case CKM_CAST_KEY_GEN: return CKM_CAST_KEY_GEN; case CKM_CAST3_ECB: case CKM_CAST3_CBC: case CKM_CAST3_MAC: case CKM_CAST3_MAC_GENERAL: case CKM_CAST3_CBC_PAD: case CKM_CAST3_KEY_GEN: return CKM_CAST3_KEY_GEN; case CKM_CAST5_ECB: case CKM_CAST5_CBC: case CKM_CAST5_MAC: case CKM_CAST5_MAC_GENERAL: case CKM_CAST5_CBC_PAD: case CKM_CAST5_KEY_GEN: return CKM_CAST5_KEY_GEN; case CKM_RSA_PKCS: case CKM_RSA_9796: case CKM_RSA_X_509: case CKM_MD2_RSA_PKCS: case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: case CKM_SHA224_RSA_PKCS: case CKM_SHA256_RSA_PKCS: case CKM_SHA384_RSA_PKCS: case CKM_SHA512_RSA_PKCS: case CKM_KEY_WRAP_SET_OAEP: case CKM_RSA_PKCS_KEY_PAIR_GEN: return CKM_RSA_PKCS_KEY_PAIR_GEN; case CKM_RSA_X9_31_KEY_PAIR_GEN: return CKM_RSA_X9_31_KEY_PAIR_GEN; case CKM_DSA: case CKM_DSA_SHA1: case CKM_DSA_KEY_PAIR_GEN: return CKM_DSA_KEY_PAIR_GEN; case CKM_DH_PKCS_DERIVE: case CKM_DH_PKCS_KEY_PAIR_GEN: return CKM_DH_PKCS_KEY_PAIR_GEN; case CKM_KEA_KEY_DERIVE: case CKM_KEA_KEY_PAIR_GEN: return CKM_KEA_KEY_PAIR_GEN; case CKM_ECDSA: case CKM_ECDSA_SHA1: case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */ case CKM_ECDH1_DERIVE: return CKM_EC_KEY_PAIR_GEN; case CKM_EDDSA: return CKM_EC_EDWARDS_KEY_PAIR_GEN; case CKM_SSL3_PRE_MASTER_KEY_GEN: case CKM_SSL3_MASTER_KEY_DERIVE: case CKM_SSL3_KEY_AND_MAC_DERIVE: case CKM_SSL3_SHA1_MAC: case CKM_SSL3_MD5_MAC: case CKM_TLS_MASTER_KEY_DERIVE: case CKM_TLS_KEY_AND_MAC_DERIVE: case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256: case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE: case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH: return CKM_SSL3_PRE_MASTER_KEY_GEN; case CKM_SHA_1_HMAC: case CKM_SHA_1_HMAC_GENERAL: case CKM_SHA224_HMAC: case CKM_SHA224_HMAC_GENERAL: case CKM_SHA256_HMAC: case CKM_SHA256_HMAC_GENERAL: case CKM_SHA384_HMAC: case CKM_SHA384_HMAC_GENERAL: case CKM_SHA512_HMAC: case CKM_SHA512_HMAC_GENERAL: case CKM_MD2_HMAC: case CKM_MD2_HMAC_GENERAL: case CKM_MD5_HMAC: case CKM_MD5_HMAC_GENERAL: case CKM_TLS_PRF_GENERAL: case CKM_NSS_TLS_PRF_GENERAL_SHA256: case CKM_GENERIC_SECRET_KEY_GEN: return CKM_GENERIC_SECRET_KEY_GEN; case CKM_PBE_MD2_DES_CBC: case CKM_PBE_MD5_DES_CBC: case CKM_PBA_SHA1_WITH_SHA1_HMAC: case CKM_NSS_PBE_SHA1_HMAC_KEY_GEN: case CKM_NSS_PBE_MD5_HMAC_KEY_GEN: case CKM_NSS_PBE_MD2_HMAC_KEY_GEN: case CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN: case CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN: case CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN: case CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN: case CKM_NSS_PBE_SHA1_DES_CBC: case CKM_NSS_PBE_SHA1_40_BIT_RC2_CBC: case CKM_NSS_PBE_SHA1_128_BIT_RC2_CBC: case CKM_NSS_PBE_SHA1_40_BIT_RC4: case CKM_NSS_PBE_SHA1_128_BIT_RC4: case CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC: case CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC: case CKM_PBE_SHA1_RC2_40_CBC: case CKM_PBE_SHA1_RC2_128_CBC: case CKM_PBE_SHA1_RC4_40: case CKM_PBE_SHA1_RC4_128: case CKM_PBE_SHA1_DES3_EDE_CBC: case CKM_PBE_SHA1_DES2_EDE_CBC: case CKM_PKCS5_PBKD2: return type; default: return pk11_lookup(type)->keyGen;
}
}
/* * get the mechanism block size
*/ int
PK11_GetBlockSize(CK_MECHANISM_TYPE type, SECItem *params)
{
CK_RC5_PARAMS *rc5_params;
CK_RC5_CBC_PARAMS *rc5_cbc_params; switch (type) { case CKM_RC5_ECB: if ((params) && (params->data)) {
rc5_params = (CK_RC5_PARAMS *)params->data; return (rc5_params->ulWordsize) * 2;
} return 8; case CKM_RC5_CBC: case CKM_RC5_CBC_PAD: if ((params) && (params->data)) {
rc5_cbc_params = (CK_RC5_CBC_PARAMS *)params->data; return (rc5_cbc_params->ulWordsize) * 2;
} return 8; case CKM_DES_ECB: case CKM_DES3_ECB: case CKM_RC2_ECB: case CKM_IDEA_ECB: case CKM_CAST_ECB: case CKM_CAST3_ECB: case CKM_CAST5_ECB: case CKM_RC2_CBC: case CKM_SKIPJACK_CBC64: case CKM_SKIPJACK_ECB64: case CKM_SKIPJACK_OFB64: case CKM_SKIPJACK_CFB64: case CKM_DES_CBC: case CKM_DES3_CBC: case CKM_IDEA_CBC: case CKM_CAST_CBC: case CKM_CAST3_CBC: case CKM_CAST5_CBC: case CKM_DES_CBC_PAD: case CKM_DES3_CBC_PAD: case CKM_RC2_CBC_PAD: case CKM_IDEA_CBC_PAD: case CKM_CAST_CBC_PAD: case CKM_CAST3_CBC_PAD: case CKM_CAST5_CBC_PAD: case CKM_PBE_MD2_DES_CBC: case CKM_PBE_MD5_DES_CBC: case CKM_NSS_PBE_SHA1_DES_CBC: case CKM_NSS_PBE_SHA1_40_BIT_RC2_CBC: case CKM_NSS_PBE_SHA1_128_BIT_RC2_CBC: case CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC: case CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC: case CKM_PBE_SHA1_RC2_40_CBC: case CKM_PBE_SHA1_RC2_128_CBC: case CKM_PBE_SHA1_DES3_EDE_CBC: case CKM_PBE_SHA1_DES2_EDE_CBC: return 8; case CKM_SKIPJACK_CFB32: case CKM_SKIPJACK_CFB16: case CKM_SKIPJACK_CFB8: return 4; case CKM_SEED_ECB: case CKM_SEED_CBC: case CKM_SEED_CBC_PAD: case CKM_CAMELLIA_ECB: case CKM_CAMELLIA_CBC: case CKM_CAMELLIA_CBC_PAD: case CKM_AES_ECB: case CKM_AES_CBC: case CKM_AES_CBC_PAD: case CKM_BATON_ECB128: case CKM_BATON_CBC128: case CKM_BATON_COUNTER: case CKM_BATON_SHUFFLE: case CKM_JUNIPER_ECB128: case CKM_JUNIPER_CBC128: case CKM_JUNIPER_COUNTER: case CKM_JUNIPER_SHUFFLE: return 16; case CKM_BATON_ECB96: return 12; case CKM_RC4: case CKM_NSS_PBE_SHA1_40_BIT_RC4: case CKM_NSS_PBE_SHA1_128_BIT_RC4: case CKM_PBE_SHA1_RC4_40: case CKM_PBE_SHA1_RC4_128: return 0; case CKM_RSA_PKCS: case CKM_RSA_9796: case CKM_RSA_X_509: /*actually it's the modulus length of the key!*/ return -1; /* failure */ case CKM_NSS_CHACHA20_POLY1305: case CKM_NSS_CHACHA20_CTR: case CKM_CHACHA20_POLY1305: case CKM_CHACHA20: return 64; default: return pk11_lookup(type)->blockSize;
}
}
/* * get the iv length
*/ int
PK11_GetIVLength(CK_MECHANISM_TYPE type)
{ switch (type) { case CKM_SEED_ECB: case CKM_CAMELLIA_ECB: case CKM_AES_ECB: case CKM_DES_ECB: case CKM_DES3_ECB: case CKM_RC2_ECB: case CKM_IDEA_ECB: case CKM_SKIPJACK_WRAP: case CKM_BATON_WRAP: case CKM_RC5_ECB: case CKM_CAST_ECB: case CKM_CAST3_ECB: case CKM_CAST5_ECB: return 0; case CKM_RC2_CBC: case CKM_DES_CBC: case CKM_DES3_CBC: case CKM_IDEA_CBC: case CKM_PBE_MD2_DES_CBC: case CKM_PBE_MD5_DES_CBC: case CKM_NSS_PBE_SHA1_DES_CBC: case CKM_NSS_PBE_SHA1_40_BIT_RC2_CBC: case CKM_NSS_PBE_SHA1_128_BIT_RC2_CBC: case CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC: case CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC: case CKM_PBE_SHA1_RC2_40_CBC: case CKM_PBE_SHA1_RC2_128_CBC: case CKM_PBE_SHA1_DES3_EDE_CBC: case CKM_PBE_SHA1_DES2_EDE_CBC: case CKM_RC5_CBC: case CKM_CAST_CBC: case CKM_CAST3_CBC: case CKM_CAST5_CBC: case CKM_RC2_CBC_PAD: case CKM_DES_CBC_PAD: case CKM_DES3_CBC_PAD: case CKM_IDEA_CBC_PAD: case CKM_RC5_CBC_PAD: case CKM_CAST_CBC_PAD: case CKM_CAST3_CBC_PAD: case CKM_CAST5_CBC_PAD: return 8; case CKM_AES_GCM: case CKM_NSS_CHACHA20_POLY1305: case CKM_CHACHA20_POLY1305: return 12; case CKM_SEED_CBC: case CKM_SEED_CBC_PAD: case CKM_CAMELLIA_CBC: case CKM_CAMELLIA_CBC_PAD: case CKM_AES_CBC: case CKM_AES_CBC_PAD: case CKM_NSS_CHACHA20_CTR: case CKM_CHACHA20: return 16; case CKM_SKIPJACK_CBC64: case CKM_SKIPJACK_ECB64: case CKM_SKIPJACK_OFB64: case CKM_SKIPJACK_CFB64: case CKM_SKIPJACK_CFB32: case CKM_SKIPJACK_CFB16: case CKM_SKIPJACK_CFB8: case CKM_BATON_ECB128: case CKM_BATON_ECB96: case CKM_BATON_CBC128: case CKM_BATON_COUNTER: case CKM_BATON_SHUFFLE: case CKM_JUNIPER_ECB128: case CKM_JUNIPER_CBC128: case CKM_JUNIPER_COUNTER: case CKM_JUNIPER_SHUFFLE: return 24; case CKM_RC4: case CKM_RSA_PKCS: case CKM_RSA_9796: case CKM_RSA_X_509: case CKM_NSS_PBE_SHA1_40_BIT_RC4: case CKM_NSS_PBE_SHA1_128_BIT_RC4: case CKM_PBE_SHA1_RC4_40: case CKM_PBE_SHA1_RC4_128: return 0; default: return pk11_lookup(type)->iv;
}
}
/* These next two utilities are here to help facilitate future * Dynamic Encrypt/Decrypt symetric key mechanisms, and to allow functions * like SSL and S-MIME to automatically add them.
*/
SECItem *
pk11_ParamFromIVWithLen(CK_MECHANISM_TYPE type, SECItem *iv, int keyLen)
{
CK_RC2_CBC_PARAMS *rc2_params = NULL;
CK_RC2_PARAMS *rc2_ecb_params = NULL;
CK_RC5_PARAMS *rc5_params = NULL;
CK_RC5_CBC_PARAMS *rc5_cbc_params = NULL;
SECItem *param;
param = (SECItem *)PORT_Alloc(sizeof(SECItem)); if (param == NULL) return NULL;
param->data = NULL;
param->len = 0;
param->type = 0; switch (type) { case CKM_SEED_ECB: case CKM_CAMELLIA_ECB: case CKM_AES_ECB: case CKM_DES_ECB: case CKM_DES3_ECB: case CKM_RSA_PKCS: case CKM_RSA_X_509: case CKM_RSA_9796: case CKM_IDEA_ECB: case CKM_CDMF_ECB: case CKM_CAST_ECB: case CKM_CAST3_ECB: case CKM_CAST5_ECB: case CKM_RC4: break; case CKM_RC2_ECB:
rc2_ecb_params = (CK_RC2_PARAMS *)PORT_Alloc(sizeof(CK_RC2_PARAMS)); if (rc2_ecb_params == NULL) break; /* Maybe we should pass the key size in too to get this value? */
*rc2_ecb_params = keyLen ? keyLen * 8 : 128;
param->data = (unsignedchar *)rc2_ecb_params;
param->len = sizeof(CK_RC2_PARAMS); break; case CKM_RC2_CBC: case CKM_RC2_CBC_PAD:
rc2_params = (CK_RC2_CBC_PARAMS *)PORT_Alloc(sizeof(CK_RC2_CBC_PARAMS)); if (rc2_params == NULL) break; /* Maybe we should pass the key size in too to get this value? */
rc2_params->ulEffectiveBits = keyLen ? keyLen * 8 : 128; if (iv && iv->data)
PORT_Memcpy(rc2_params->iv, iv->data, sizeof(rc2_params->iv));
param->data = (unsignedchar *)rc2_params;
param->len = sizeof(CK_RC2_CBC_PARAMS); break; case CKM_RC5_CBC: case CKM_RC5_CBC_PAD:
rc5_cbc_params = (CK_RC5_CBC_PARAMS *)
PORT_Alloc(sizeof(CK_RC5_CBC_PARAMS) + ((iv) ? iv->len : 0)); if (rc5_cbc_params == NULL) break; if (iv && iv->data && iv->len) {
rc5_cbc_params->pIv = ((CK_BYTE_PTR)rc5_cbc_params) + sizeof(CK_RC5_CBC_PARAMS);
PORT_Memcpy(rc5_cbc_params->pIv, iv->data, iv->len);
rc5_cbc_params->ulIvLen = iv->len;
rc5_cbc_params->ulWordsize = iv->len / 2;
} else {
rc5_cbc_params->ulWordsize = 4;
rc5_cbc_params->pIv = NULL;
rc5_cbc_params->ulIvLen = 0;
}
rc5_cbc_params->ulRounds = 16;
param->data = (unsignedchar *)rc5_cbc_params;
param->len = sizeof(CK_RC5_CBC_PARAMS); break; case CKM_RC5_ECB:
rc5_params = (CK_RC5_PARAMS *)PORT_Alloc(sizeof(CK_RC5_PARAMS)); if (rc5_params == NULL) break; if (iv && iv->data && iv->len) {
rc5_params->ulWordsize = iv->len / 2;
} else {
rc5_params->ulWordsize = 4;
}
rc5_params->ulRounds = 16;
param->data = (unsignedchar *)rc5_params;
param->len = sizeof(CK_RC5_PARAMS); break;
case CKM_SEED_CBC: case CKM_CAMELLIA_CBC: case CKM_AES_CBC: case CKM_DES_CBC: case CKM_DES3_CBC: case CKM_IDEA_CBC: case CKM_CDMF_CBC: case CKM_CAST_CBC: case CKM_CAST3_CBC: case CKM_CAST5_CBC: case CKM_CAMELLIA_CBC_PAD: case CKM_AES_CBC_PAD: case CKM_DES_CBC_PAD: case CKM_DES3_CBC_PAD: case CKM_IDEA_CBC_PAD: case CKM_CDMF_CBC_PAD: case CKM_CAST_CBC_PAD: case CKM_CAST3_CBC_PAD: case CKM_CAST5_CBC_PAD: case CKM_SKIPJACK_CBC64: case CKM_SKIPJACK_ECB64: case CKM_SKIPJACK_OFB64: case CKM_SKIPJACK_CFB64: case CKM_SKIPJACK_CFB32: case CKM_SKIPJACK_CFB16: case CKM_SKIPJACK_CFB8: case CKM_BATON_ECB128: case CKM_BATON_ECB96: case CKM_BATON_CBC128: case CKM_BATON_COUNTER: case CKM_BATON_SHUFFLE: case CKM_JUNIPER_ECB128: case CKM_JUNIPER_CBC128: case CKM_JUNIPER_COUNTER: case CKM_JUNIPER_SHUFFLE: if ((iv == NULL) || (iv->data == NULL)) break;
param->data = (unsignedchar *)PORT_Alloc(iv->len); if (param->data != NULL) {
PORT_Memcpy(param->data, iv->data, iv->len);
param->len = iv->len;
} break; /* unknown mechanism, pass IV in if it's there */ default: if (pk11_lookup(type)->iv == 0) { break;
} if ((iv == NULL) || (iv->data == NULL)) { break;
}
param->data = (unsignedchar *)PORT_Alloc(iv->len); if (param->data != NULL) {
PORT_Memcpy(param->data, iv->data, iv->len);
param->len = iv->len;
} break;
} return param;
}
/* These next two utilities are here to help facilitate future * Dynamic Encrypt/Decrypt symetric key mechanisms, and to allow functions * like SSL and S-MIME to automatically add them.
*/
SECItem *
PK11_ParamFromIV(CK_MECHANISM_TYPE type, SECItem *iv)
{ return pk11_ParamFromIVWithLen(type, iv, 0);
}
*len = 0; switch (type) { case CKM_SEED_ECB: case CKM_CAMELLIA_ECB: case CKM_AES_ECB: case CKM_DES_ECB: case CKM_DES3_ECB: case CKM_RSA_PKCS: case CKM_RSA_X_509: case CKM_RSA_9796: case CKM_IDEA_ECB: case CKM_CDMF_ECB: case CKM_CAST_ECB: case CKM_CAST3_ECB: case CKM_CAST5_ECB: case CKM_RC4: return NULL; case CKM_RC2_ECB: return NULL; case CKM_RC2_CBC: case CKM_RC2_CBC_PAD:
rc2_params = (CK_RC2_CBC_PARAMS *)param->data;
*len = sizeof(rc2_params->iv); return &rc2_params->iv[0]; case CKM_RC5_CBC: case CKM_RC5_CBC_PAD:
rc5_cbc_params = (CK_RC5_CBC_PARAMS *)param->data;
*len = rc5_cbc_params->ulIvLen; return rc5_cbc_params->pIv; case CKM_SEED_CBC: case CKM_CAMELLIA_CBC: case CKM_AES_CBC: case CKM_DES_CBC: case CKM_DES3_CBC: case CKM_IDEA_CBC: case CKM_CDMF_CBC: case CKM_CAST_CBC: case CKM_CAST3_CBC: case CKM_CAST5_CBC: case CKM_CAMELLIA_CBC_PAD: case CKM_AES_CBC_PAD: case CKM_DES_CBC_PAD: case CKM_DES3_CBC_PAD: case CKM_IDEA_CBC_PAD: case CKM_CDMF_CBC_PAD: case CKM_CAST_CBC_PAD: case CKM_CAST3_CBC_PAD: case CKM_CAST5_CBC_PAD: case CKM_SKIPJACK_CBC64: case CKM_SKIPJACK_ECB64: case CKM_SKIPJACK_OFB64: case CKM_SKIPJACK_CFB64: case CKM_SKIPJACK_CFB32: case CKM_SKIPJACK_CFB16: case CKM_SKIPJACK_CFB8: case CKM_BATON_ECB128: case CKM_BATON_ECB96: case CKM_BATON_CBC128: case CKM_BATON_COUNTER: case CKM_BATON_SHUFFLE: case CKM_JUNIPER_ECB128: case CKM_JUNIPER_CBC128: case CKM_JUNIPER_COUNTER: case CKM_JUNIPER_SHUFFLE: break; /* unknown mechanism, pass IV in if it's there */ default: break;
} if (param->data) {
*len = param->len;
} return param->data;
}
/* S/MIME picked id values to represent differnt keysizes */ /* I do have a formula, but it ain't pretty, and it only works because you
* can always match three points to a parabola:) */ staticunsignedchar
rc2_map(SECItem *version)
{ long x;
x = DER_GetInteger(version);
switch (x) { case 58: return 128; case 120: return 64; case 160: return 40;
} return 128;
}
staticunsignedlong
rc2_unmap(unsignedlong x)
{ switch (x) { case 128: return 58; case 64: return 120; case 40: return 160;
} return 58;
}
arena = PORT_NewArena(1024); if (!arena) { goto loser;
}
/* handle the complicated cases */ switch (type) { case CKM_RC2_ECB:
rv = SEC_ASN1DecodeItem(arena, &rc2, sec_rc2ecb_parameter_template,
&(algid->parameters)); if (rv != SECSuccess) { goto loser;
}
rc2_ecb_params = PORT_New(CK_RC2_PARAMS); if (rc2_ecb_params == NULL) { goto loser;
}
*rc2_ecb_params = rc2_map(&rc2.rc2ParameterVersion);
mech->data = (unsignedchar *)rc2_ecb_params;
mech->len = sizeof *rc2_ecb_params; break; case CKM_RC2_CBC: case CKM_RC2_CBC_PAD:
rv = SEC_ASN1DecodeItem(arena, &rc2, sec_rc2cbc_parameter_template,
&(algid->parameters)); if (rv != SECSuccess) { goto loser;
}
rc2_cbc_params = PORT_New(CK_RC2_CBC_PARAMS); if (rc2_cbc_params == NULL) { goto loser;
}
mech->data = (unsignedchar *)rc2_cbc_params;
mech->len = sizeof *rc2_cbc_params;
rc2_cbc_params->ulEffectiveBits = rc2_map(&rc2.rc2ParameterVersion); if (rc2.iv.len != sizeof rc2_cbc_params->iv) {
PORT_SetError(SEC_ERROR_INPUT_LEN); goto loser;
}
PORT_Memcpy(rc2_cbc_params->iv, rc2.iv.data, rc2.iv.len); break; case CKM_RC5_ECB:
rv = SEC_ASN1DecodeItem(arena, &rc5, sec_rc5ecb_parameter_template,
&(algid->parameters)); if (rv != SECSuccess) { goto loser;
}
rc5_ecb_params = PORT_New(CK_RC5_PARAMS); if (rc5_ecb_params == NULL) { goto loser;
}
rc5_ecb_params->ulRounds = DER_GetInteger(&rc5.rounds);
rc5_ecb_params->ulWordsize = DER_GetInteger(&rc5.blockSizeInBits) / 8;
mech->data = (unsignedchar *)rc5_ecb_params;
mech->len = sizeof *rc5_ecb_params; break; case CKM_RC5_CBC: case CKM_RC5_CBC_PAD:
rv = SEC_ASN1DecodeItem(arena, &rc5, sec_rc5cbc_parameter_template,
&(algid->parameters)); if (rv != SECSuccess) { goto loser;
}
rc5_cbc_params = (CK_RC5_CBC_PARAMS *)
PORT_Alloc(sizeof(CK_RC5_CBC_PARAMS) + rc5.iv.len); if (rc5_cbc_params == NULL) { goto loser;
}
mech->data = (unsignedchar *)rc5_cbc_params;
mech->len = sizeof *rc5_cbc_params;
rc5_cbc_params->ulRounds = DER_GetInteger(&rc5.rounds);
rc5_cbc_params->ulWordsize = DER_GetInteger(&rc5.blockSizeInBits) / 8;
rc5_cbc_params->pIv = ((CK_BYTE_PTR)rc5_cbc_params) + sizeof(CK_RC5_CBC_PARAMS);
rc5_cbc_params->ulIvLen = rc5.iv.len;
PORT_Memcpy(rc5_cbc_params->pIv, rc5.iv.data, rc5.iv.len); break; case CKM_PBE_MD2_DES_CBC: case CKM_PBE_MD5_DES_CBC: case CKM_NSS_PBE_SHA1_DES_CBC: case CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC: case CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC: case CKM_NSS_PBE_SHA1_40_BIT_RC2_CBC: case CKM_NSS_PBE_SHA1_128_BIT_RC2_CBC: case CKM_NSS_PBE_SHA1_40_BIT_RC4: case CKM_NSS_PBE_SHA1_128_BIT_RC4: case CKM_PBE_SHA1_DES2_EDE_CBC: case CKM_PBE_SHA1_DES3_EDE_CBC: case CKM_PBE_SHA1_RC2_40_CBC: case CKM_PBE_SHA1_RC2_128_CBC: case CKM_PBE_SHA1_RC4_40: case CKM_PBE_SHA1_RC4_128: case CKM_PKCS5_PBKD2:
rv = pbe_PK11AlgidToParam(algid, mech); if (rv != SECSuccess) { goto loser;
} break; case CKM_RC4: case CKM_SEED_ECB: case CKM_CAMELLIA_ECB: case CKM_AES_ECB: case CKM_DES_ECB: case CKM_DES3_ECB: case CKM_IDEA_ECB: case CKM_CDMF_ECB: case CKM_CAST_ECB: case CKM_CAST3_ECB: case CKM_CAST5_ECB: break;
default: if (pk11_lookup(type)->iv == 0) { break;
} /* FALL THROUGH */ case CKM_SEED_CBC: case CKM_CAMELLIA_CBC: case CKM_AES_CBC: case CKM_DES_CBC: case CKM_DES3_CBC: case CKM_IDEA_CBC: case CKM_CDMF_CBC: case CKM_CAST_CBC: case CKM_CAST3_CBC: case CKM_CAST5_CBC: case CKM_SEED_CBC_PAD: case CKM_CAMELLIA_CBC_PAD: case CKM_AES_CBC_PAD: case CKM_DES_CBC_PAD: case CKM_DES3_CBC_PAD: case CKM_IDEA_CBC_PAD: case CKM_CDMF_CBC_PAD: case CKM_CAST_CBC_PAD: case CKM_CAST3_CBC_PAD: case CKM_CAST5_CBC_PAD: case CKM_SKIPJACK_CBC64: case CKM_SKIPJACK_ECB64: case CKM_SKIPJACK_OFB64: case CKM_SKIPJACK_CFB64: case CKM_SKIPJACK_CFB32: case CKM_SKIPJACK_CFB16: case CKM_SKIPJACK_CFB8: case CKM_BATON_ECB128: case CKM_BATON_ECB96: case CKM_BATON_CBC128: case CKM_BATON_COUNTER: case CKM_BATON_SHUFFLE: case CKM_JUNIPER_ECB128: case CKM_JUNIPER_CBC128: case CKM_JUNIPER_COUNTER: case CKM_JUNIPER_SHUFFLE: /* simple cases are simply octet string encoded IVs */
rv = SEC_ASN1DecodeItem(arena, &iv,
SEC_ASN1_GET(SEC_OctetStringTemplate),
&(algid->parameters)); if (rv != SECSuccess || iv.data == NULL) { goto loser;
} /* XXX Should be some IV length sanity check here. */
mech->data = (unsignedchar *)PORT_Alloc(iv.len); if (mech->data == NULL) { goto loser;
}
PORT_Memcpy(mech->data, iv.data, iv.len);
mech->len = iv.len; break;
}
PORT_FreeArena(arena, PR_FALSE); return mech;
loser: if (arena)
PORT_FreeArena(arena, PR_FALSE);
SECITEM_FreeItem(mech, PR_TRUE); return NULL;
}
/* * Generate an IV for the given mechanism
*/ static SECStatus
pk11_GenIV(CK_MECHANISM_TYPE type, SECItem *iv)
{ int iv_size = PK11_GetIVLength(type);
SECStatus rv;
/* * create a new parameter block from the passed in MECHANISM and the * key. Use Netscape's S/MIME Rules for the New param block.
*/
SECItem *
pk11_GenerateNewParamWithKeyLen(CK_MECHANISM_TYPE type, int keyLen)
{
CK_RC2_CBC_PARAMS *rc2_params;
CK_RC2_PARAMS *rc2_ecb_params;
SECItem *mech;
SECItem iv;
SECStatus rv;
mech = (SECItem *)PORT_Alloc(sizeof(SECItem)); if (mech == NULL) return NULL;
rv = SECSuccess;
mech->type = siBuffer;
mech->data = NULL;
mech->len = 0; switch (type) { case CKM_RC4: case CKM_SEED_ECB: case CKM_CAMELLIA_ECB: case CKM_AES_ECB: case CKM_DES_ECB: case CKM_DES3_ECB: case CKM_IDEA_ECB: case CKM_CDMF_ECB: case CKM_CAST_ECB: case CKM_CAST3_ECB: case CKM_CAST5_ECB: break; case CKM_RC2_ECB:
rc2_ecb_params = (CK_RC2_PARAMS *)PORT_Alloc(sizeof(CK_RC2_PARAMS)); if (rc2_ecb_params == NULL) {
rv = SECFailure; break;
} /* NOTE PK11_GetKeyLength can return -1 if the key isn't and RC2, RC5,
* or RC4 key. Of course that wouldn't happen here doing RC2:).*/
*rc2_ecb_params = keyLen ? keyLen * 8 : 128;
mech->data = (unsignedchar *)rc2_ecb_params;
mech->len = sizeof(CK_RC2_PARAMS); break; case CKM_RC2_CBC: case CKM_RC2_CBC_PAD:
rv = pk11_GenIV(type, &iv); if (rv != SECSuccess) { break;
}
rc2_params = (CK_RC2_CBC_PARAMS *)PORT_Alloc(sizeof(CK_RC2_CBC_PARAMS)); if (rc2_params == NULL) {
PORT_Free(iv.data);
rv = SECFailure; break;
} /* NOTE PK11_GetKeyLength can return -1 if the key isn't and RC2, RC5,
* or RC4 key. Of course that wouldn't happen here doing RC2:).*/
rc2_params->ulEffectiveBits = keyLen ? keyLen * 8 : 128; if (iv.data)
PORT_Memcpy(rc2_params->iv, iv.data, sizeof(rc2_params->iv));
mech->data = (unsignedchar *)rc2_params;
mech->len = sizeof(CK_RC2_CBC_PARAMS);
PORT_Free(iv.data); break; case CKM_RC5_ECB:
PORT_Free(mech); return PK11_ParamFromIV(type, NULL); case CKM_RC5_CBC: case CKM_RC5_CBC_PAD:
rv = pk11_GenIV(type, &iv); if (rv != SECSuccess) { break;
}
PORT_Free(mech); return PK11_ParamFromIV(type, &iv); default: if (pk11_lookup(type)->iv == 0) { break;
} case CKM_SEED_CBC: case CKM_CAMELLIA_CBC: case CKM_AES_CBC: case CKM_DES_CBC: case CKM_DES3_CBC: case CKM_IDEA_CBC: case CKM_CDMF_CBC: case CKM_CAST_CBC: case CKM_CAST3_CBC: case CKM_CAST5_CBC: case CKM_DES_CBC_PAD: case CKM_DES3_CBC_PAD: case CKM_IDEA_CBC_PAD: case CKM_CDMF_CBC_PAD: case CKM_CAST_CBC_PAD: case CKM_CAST3_CBC_PAD: case CKM_CAST5_CBC_PAD: case CKM_SKIPJACK_CBC64: case CKM_SKIPJACK_ECB64: case CKM_SKIPJACK_OFB64: case CKM_SKIPJACK_CFB64: case CKM_SKIPJACK_CFB32: case CKM_SKIPJACK_CFB16: case CKM_SKIPJACK_CFB8: case CKM_BATON_ECB128: case CKM_BATON_ECB96: case CKM_BATON_CBC128: case CKM_BATON_COUNTER: case CKM_BATON_SHUFFLE: case CKM_JUNIPER_ECB128: case CKM_JUNIPER_CBC128: case CKM_JUNIPER_COUNTER: case CKM_JUNIPER_SHUFFLE:
rv = pk11_GenIV(type, &iv); if (rv != SECSuccess) { break;
}
mech->data = (unsignedchar *)PORT_Alloc(iv.len); if (mech->data == NULL) {
PORT_Free(iv.data);
rv = SECFailure; break;
} if (iv.len) {
PORT_Memcpy(mech->data, iv.data, iv.len);
}
mech->len = iv.len;
PORT_Free(iv.data); break;
} if (rv != SECSuccess) {
SECITEM_FreeItem(mech, PR_TRUE); return NULL;
} return mech;
}
/* turn a PKCS #11 parameter into a DER Encoded Algorithm ID */
SECStatus
PK11_ParamToAlgid(SECOidTag algTag, SECItem *param,
PLArenaPool *arena, SECAlgorithmID *algid)
{
CK_RC2_CBC_PARAMS *rc2_params;
sec_rc2cbcParameter rc2;
CK_RC5_CBC_PARAMS *rc5_params;
sec_rc5cbcParameter rc5;
CK_MECHANISM_TYPE type = PK11_AlgtagToMechanism(algTag);
SECItem *newParams = NULL;
SECStatus rv = SECFailure; unsignedlong rc2version;
switch (type) { case CKM_RC4: case CKM_SEED_ECB: case CKM_CAMELLIA_ECB: case CKM_AES_ECB: case CKM_DES_ECB: case CKM_DES3_ECB: case CKM_IDEA_ECB: case CKM_CDMF_ECB: case CKM_CAST_ECB: case CKM_CAST3_ECB: case CKM_CAST5_ECB:
newParams = NULL;
rv = SECSuccess; break; case CKM_RC2_ECB: break; case CKM_RC2_CBC: case CKM_RC2_CBC_PAD:
rc2_params = (CK_RC2_CBC_PARAMS *)param->data;
rc2version = rc2_unmap(rc2_params->ulEffectiveBits); if (SEC_ASN1EncodeUnsignedInteger(NULL, &(rc2.rc2ParameterVersion),
rc2version) == NULL) break;
rc2.iv.data = rc2_params->iv;
rc2.iv.len = sizeof(rc2_params->iv);
newParams = SEC_ASN1EncodeItem(NULL, NULL, &rc2,
sec_rc2cbc_parameter_template);
PORT_Free(rc2.rc2ParameterVersion.data); if (newParams == NULL) break;
rv = SECSuccess; break;
case CKM_RC5_ECB: /* well not really... */ break; case CKM_RC5_CBC: case CKM_RC5_CBC_PAD:
rc5_params = (CK_RC5_CBC_PARAMS *)param->data; if (SEC_ASN1EncodeUnsignedInteger(NULL, &rc5.version, RC5_V10) == NULL) break; if (SEC_ASN1EncodeUnsignedInteger(NULL, &rc5.blockSizeInBits,
rc5_params->ulWordsize * 8) == NULL) {
PORT_Free(rc5.version.data); break;
} if (SEC_ASN1EncodeUnsignedInteger(NULL, &rc5.rounds,
rc5_params->ulWordsize * 8) == NULL) {
PORT_Free(rc5.blockSizeInBits.data);
PORT_Free(rc5.version.data); break;
}
rc5.iv.data = rc5_params->pIv;
rc5.iv.len = rc5_params->ulIvLen;
newParams = SEC_ASN1EncodeItem(NULL, NULL, &rc5,
sec_rc5cbc_parameter_template);
PORT_Free(rc5.version.data);
PORT_Free(rc5.blockSizeInBits.data);
PORT_Free(rc5.rounds.data); if (newParams == NULL) break;
rv = SECSuccess; break; case CKM_PBE_MD2_DES_CBC: case CKM_PBE_MD5_DES_CBC: case CKM_NSS_PBE_SHA1_DES_CBC: case CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC: case CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC: case CKM_NSS_PBE_SHA1_40_BIT_RC2_CBC: case CKM_NSS_PBE_SHA1_128_BIT_RC2_CBC: case CKM_NSS_PBE_SHA1_40_BIT_RC4: case CKM_NSS_PBE_SHA1_128_BIT_RC4: case CKM_PBE_SHA1_DES3_EDE_CBC: case CKM_PBE_SHA1_DES2_EDE_CBC: case CKM_PBE_SHA1_RC2_40_CBC: case CKM_PBE_SHA1_RC2_128_CBC: case CKM_PBE_SHA1_RC4_40: case CKM_PBE_SHA1_RC4_128: return PBE_PK11ParamToAlgid(algTag, param, arena, algid); default: if (pk11_lookup(type)->iv == 0) {
rv = SECSuccess;
newParams = NULL; break;
} case CKM_SEED_CBC: case CKM_CAMELLIA_CBC: case CKM_AES_CBC: case CKM_DES_CBC: case CKM_DES3_CBC: case CKM_IDEA_CBC: case CKM_CDMF_CBC: case CKM_CAST_CBC: case CKM_CAST3_CBC: case CKM_CAST5_CBC: case CKM_DES_CBC_PAD: case CKM_DES3_CBC_PAD: case CKM_IDEA_CBC_PAD: case CKM_CDMF_CBC_PAD: case CKM_CAST_CBC_PAD: case CKM_CAST3_CBC_PAD: case CKM_CAST5_CBC_PAD: case CKM_SKIPJACK_CBC64: case CKM_SKIPJACK_ECB64: case CKM_SKIPJACK_OFB64: case CKM_SKIPJACK_CFB64: case CKM_SKIPJACK_CFB32: case CKM_SKIPJACK_CFB16: case CKM_SKIPJACK_CFB8: case CKM_BATON_ECB128: case CKM_BATON_ECB96: case CKM_BATON_CBC128: case CKM_BATON_COUNTER: case CKM_BATON_SHUFFLE: case CKM_JUNIPER_ECB128: case CKM_JUNIPER_CBC128: case CKM_JUNIPER_COUNTER: case CKM_JUNIPER_SHUFFLE: if (param && param->len > 0) {
newParams = SEC_ASN1EncodeItem(NULL, NULL, param,
SEC_ASN1_GET(SEC_OctetStringTemplate)); if (newParams == NULL) break;
} else { /* if no parameters have been supplied, then use NULL params * The SECOID_SetAlgorithmID encoder will encode that as no * params (since params are optional) or with an explicit NULL * (for some historical cases where explicit NULL is expected).
*/
newParams = NULL;
}
rv = SECSuccess; break;
}
if (rv != SECSuccess) { if (newParams)
SECITEM_FreeItem(newParams, PR_TRUE); return rv;
}
/* turn an OID algorithm tag into a PKCS #11 mechanism. This allows us to * map OID's directly into the PKCS #11 mechanism we want to call. We find
* this mapping in our standard OID table */
CK_MECHANISM_TYPE
PK11_AlgtagToMechanism(SECOidTag algTag)
{
SECOidData *oid = SECOID_FindOIDByTag(algTag);
if (oid) return (CK_MECHANISM_TYPE)oid->mechanism; return CKM_INVALID_MECHANISM;
}
/* turn a mechanism into an oid. */
SECOidTag
PK11_MechanismToAlgtag(CK_MECHANISM_TYPE type)
{
SECOidData *oid = SECOID_FindOIDByMechanism((unsignedlong)type);
if (oid) return oid->offset; return SEC_OID_UNKNOWN;
}
/* Determine appropriate blocking mechanism, used when wrapping private keys * which require PKCS padding. If the mechanism does not map to a padding * mechanism, we simply return the mechanism.
*/
CK_MECHANISM_TYPE
PK11_GetPadMechanism(CK_MECHANISM_TYPE type)
{ switch (type) { case CKM_SEED_CBC: return CKM_SEED_CBC_PAD; case CKM_CAMELLIA_CBC: return CKM_CAMELLIA_CBC_PAD; case CKM_AES_CBC: return CKM_AES_CBC_PAD; case CKM_DES_CBC: return CKM_DES_CBC_PAD; case CKM_DES3_CBC: return CKM_DES3_CBC_PAD; case CKM_RC2_CBC: return CKM_RC2_CBC_PAD; case CKM_CDMF_CBC: return CKM_CDMF_CBC_PAD; case CKM_CAST_CBC: return CKM_CAST_CBC_PAD; case CKM_CAST3_CBC: return CKM_CAST3_CBC_PAD; case CKM_CAST5_CBC: return CKM_CAST5_CBC_PAD; case CKM_RC5_CBC: return CKM_RC5_CBC_PAD; case CKM_IDEA_CBC: return CKM_IDEA_CBC_PAD; default: break;
}
return type;
}
static PRBool
pk11_isAllZero(unsignedchar *data, int len)
{ while (len--) { if (*data++) { return PR_FALSE;
}
} return PR_TRUE;
}
switch (pPBEMechanism->mechanism) { case CKM_PBE_MD2_DES_CBC: case CKM_PBE_MD5_DES_CBC: case CKM_NSS_PBE_SHA1_DES_CBC:
pCryptoMechanism->mechanism = CKM_DES_CBC; goto have_crypto_mechanism; case CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC: case CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC: case CKM_PBE_SHA1_DES3_EDE_CBC: case CKM_PBE_SHA1_DES2_EDE_CBC:
pCryptoMechanism->mechanism = CKM_DES3_CBC;
have_crypto_mechanism:
pCryptoMechanism->pParameter = PORT_Alloc(iv_len);
pCryptoMechanism->ulParameterLen = (CK_ULONG)iv_len; if (pCryptoMechanism->pParameter == NULL) { return CKR_HOST_MEMORY;
}
PORT_Memcpy((unsignedchar *)(pCryptoMechanism->pParameter),
(unsignedchar *)(pPBEparams->pInitVector),
iv_len); break; case CKM_NSS_PBE_SHA1_40_BIT_RC4: case CKM_NSS_PBE_SHA1_128_BIT_RC4: case CKM_PBE_SHA1_RC4_40: case CKM_PBE_SHA1_RC4_128:
pCryptoMechanism->mechanism = CKM_RC4;
pCryptoMechanism->ulParameterLen = 0;
pCryptoMechanism->pParameter = CK_NULL_PTR; break; case CKM_NSS_PBE_SHA1_40_BIT_RC2_CBC: case CKM_PBE_SHA1_RC2_40_CBC:
rc2_key_len = 40; goto have_key_len; case CKM_NSS_PBE_SHA1_128_BIT_RC2_CBC:
rc2_key_len = 128;
have_key_len:
pCryptoMechanism->mechanism = CKM_RC2_CBC;
pCryptoMechanism->ulParameterLen = (CK_ULONG)sizeof(CK_RC2_CBC_PARAMS);
pCryptoMechanism->pParameter = (CK_RC2_CBC_PARAMS_PTR)
PORT_ZAlloc(sizeof(CK_RC2_CBC_PARAMS)); if (pCryptoMechanism->pParameter == NULL) { return CKR_HOST_MEMORY;
}
rc2_params = (CK_RC2_CBC_PARAMS_PTR)pCryptoMechanism->pParameter;
PORT_Memcpy((unsignedchar *)rc2_params->iv,
(unsignedchar *)pPBEparams->pInitVector,
iv_len);
rc2_params->ulEffectiveBits = rc2_key_len; break; default: return CKR_MECHANISM_INVALID;
}
return CKR_OK;
}
/* Make a Key type to an appropriate signing/verification mechanism */
CK_MECHANISM_TYPE
PK11_MapSignKeyType(KeyType keyType)
{ switch (keyType) { case rsaKey: return CKM_RSA_PKCS; case fortezzaKey: case dsaKey: return CKM_DSA; case ecKey: return CKM_ECDSA; case edKey: return CKM_EDDSA; case dhKey: default: break;
} return CKM_INVALID_MECHANISM;
}
SECOidTag
PK11_FortezzaMapSig(SECOidTag algTag)
{ switch (algTag) { case SEC_OID_MISSI_KEA_DSS: case SEC_OID_MISSI_DSS: case SEC_OID_MISSI_DSS_OLD: case SEC_OID_MISSI_KEA_DSS_OLD: case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST: return SEC_OID_ANSIX9_DSA_SIGNATURE; default: break;
} return algTag;
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.