Mechanisms

Conversions for pure-python dictionaries to C struct mechanisms.

To implement a new Mechanism:

  1. Create a new mechanism class, deriving from Mechanism

  2. Set REQUIRED_PARAMS as a class variable. REQUIRED_PARAMS should be a list of strings, defining required parameter keys.

    class IvMechanism(Mechanism):
        REQUIRED_PARAMS = ['iv']
    
  3. Override to_c_mech() on the new mechanism class. This function can access self.params to get passed-in parameters, and should create the C parameter struct required by the mechanism. This should also return self.mech (which is a CK_MECHANISM struct).

    Simple Example
    class IvMechanism(Mechanism):
        REQUIRED_PARAMS = ['iv']
    
        def to_c_mech(self):
            super(IvMechanism, self).to_c_mech()
            if len(self.params['iv']) == 0:
                LOG.debug("Setting IV to NULL (using internal)")
                iv_ba = None
                iv_len = 0
            else:
                iv_ba, iv_len = to_byte_array(self.params['iv'])
            self.mech.pParameter = iv_ba
            self.mech.ulParameterLen = iv_len
            return self.mech
    
    Example with a PARAMS struct
    class AESXTSMechanism(Mechanism):
        REQUIRED_PARAMS = ['cb', 'hTweakKey']
    
        def to_c_mech(self):
            super(AESXTSMechanism, self).to_c_mech()
            xts_params = CK_AES_XTS_PARAMS()
            xts_params.cb = (CK_BYTE * 16)(*self.params['cb'])
            xts_params.hTweakKey = CK_ULONG(self.params['hTweakKey'])
            self.mech.pParameter = cast(pointer(xts_params), c_void_p)
            self.mech.ulParameterLen = CK_ULONG(sizeof(xts_params))
            return self.mech
    

Helpers

Mechanism base class, as well as helper functions for parsing Mechanism arguments to pypkcs11 functions.

class pypkcs11.mechanism.helpers.Mechanism(mech_type='UNKNOWN', params=None)

Bases: object

Base class for pypkcs11 mechanisms. Performs checks for missing parameters w/ created mechs, and creates the base Mechanism Struct for conversion to ctypes.

REQUIRED_PARAMS = []
to_c_mech()

Create the Mechanism structure & set the mech type to the passed-in flavor.

Returns:CK_MECHANISM
exception pypkcs11.mechanism.helpers.MechanismException

Bases: Exception

Exception raised for mechanism errors. Ex: required parameters are missing

pypkcs11.mechanism.helpers.get_c_struct_from_mechanism(python_dictionary, params_type_string)

Gets a c struct from a python dictionary representing that struct

Parameters:
  • python_dictionary – The python dictionary representing the C struct, see CK_AES_CBC_PAD_EXTRACT_PARAMS for an example
  • params_type_string – A string representing the parameter struct. ex. for CK_AES_CBC_PAD_EXTRACT_PARAMS use the string CK_AES_CBC_PAD_EXTRACT_PARAMS
Returns:

A C struct

pypkcs11.mechanism.helpers.get_python_dict_from_c_mechanism(c_mechanism, params_type_string)

Gets a python dictionary from a c mechanism’s struct for serialization and easier test case writing

Parameters:
  • c_mechanism – The c mechanism to convert to a python dictionary
  • params_type_string – A string representing the parameter struct. ex. for CK_AES_CBC_PAD_EXTRACT_PARAMS use the string CK_AES_CBC_PAD_EXTRACT_PARAMS
Returns:

A python dictionary representing the c struct

pypkcs11.mechanism.helpers.parse_mechanism(mechanism_param)

Designed for use with any function call that takes in a mechanism, this will handle a mechanism parameter that is one of the following:

  1. CKM_ integer constant – will create a CK_MECHANISM with only mech_type set.

    parse_mechanism(CKM_RSA_PKCS)
    # Results in:
    mech = CK_MECHANISM()
    mech.mechanism = CK_MECHANISM_TYPE(CKM_RSA_PKCS)
    mech.pParameter = None
    mech.ulParameterLen = 0
    
  2. Dictionary with mech_type as a mandatory key, and params as an optional key. This will be passed into the Mechanism class for conversion to a CK_MECHANISM.

    parse_mechanism({'mech_type': CKM_AES_CBC,
                     'params': {'iv': list(range(8))}})
    # Results in:
    mech = CK_MECHANISM()
    mech.mechanism = CK_MECHANISM_TYPE(CKM_AES_CBC)
    iv_ba, iv_len = to_byte_array(list(range(8)))
    mech.pParameter = iv_ba
    mech.ulParameterLen = iv_len
    
  3. CK_MECHANISM struct – passed directly into the raw C Call.

  4. Mechanism class – will call to_c_mech() on the class, and use the results.

Note

You can look at REQUIRED_PARAMS on each mechanism class to see what parameters are required.

Parameters:mechanism_param – Parameter to convert to a C Mechanism.
Returns:CK_MECHANISM struct.

AES Mechanisms

AES-specific mechanism implementations.

class pypkcs11.mechanism.aes.AESCBCEncryptDataMechanism(mech_type='UNKNOWN', params=None)

Bases: pypkcs11.mechanism.helpers.Mechanism

AES CBC mechanism for deriving keys from encrypted data.

REQUIRED_PARAMS = ['iv', 'data']
to_c_mech()

Convert extra parameters to ctypes, then build out the mechanism.

Returns:CK_MECHANISM
class pypkcs11.mechanism.aes.AESCTRMechanism(mech_type='UNKNOWN', params=None)

Bases: pypkcs11.mechanism.helpers.Mechanism

AES CTR Mechanism param conversion.

REQUIRED_PARAMS = ['cb', 'ulCounterBits']
to_c_mech()

Convert extra parameters to ctypes, then build out the mechanism.

Returns:CK_MECHANISM
class pypkcs11.mechanism.aes.AESECBEncryptDataMechanism(mech_type='UNKNOWN', params=None)

Bases: pypkcs11.mechanism.helpers.Mechanism

AES mechanism for deriving keys from encrypted data.

REQUIRED_PARAMS = ['data']
to_c_mech()

Convert extra parameters to ctypes, then build out the mechanism.

Returns:CK_MECHANISM
class pypkcs11.mechanism.aes.AESGCMMechanism(mech_type='UNKNOWN', params=None)

Bases: pypkcs11.mechanism.helpers.Mechanism

Creates the AES-GCM specific param structure & converts python types to C types.

REQUIRED_PARAMS = ['iv', 'AAD', 'ulTagBits']
to_c_mech()

Convert extra parameters to ctypes, then build out the mechanism.

Returns:CK_MECHANISM
class pypkcs11.mechanism.aes.AESXTSMechanism(mech_type='UNKNOWN', params=None)

Bases: pypkcs11.mechanism.helpers.Mechanism

Creates the AES-XTS specific param structure & converts python types to C types.

REQUIRED_PARAMS = ['cb', 'hTweakKey']
to_c_mech()

Convert extra parameters to ctypes, then build out the mechanism.

Returns:CK_MECHANISM
class pypkcs11.mechanism.aes.Iv16Mechanism(mech_type='UNKNOWN', params=None)

Bases: pypkcs11.mechanism.helpers.Mechanism

Mech class for flavors that require an IV set in the mechanism. Will default to [1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8] if no IV is passed in

to_c_mech()

Convert extra parameters to ctypes, then build out the mechanism.

Returns:CK_MECHANISM
class pypkcs11.mechanism.aes.IvMechanism(mech_type='UNKNOWN', params=None)

Bases: pypkcs11.mechanism.helpers.Mechanism

Mech class for flavors that require an IV set in the mechanism. Will default to [0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38] if no IV is passed in

to_c_mech()

Convert extra parameters to ctypes, then build out the mechanism.

Returns:CK_MECHANISM

Generic Mechanisms

Generic Mechanisms conversions.

class pypkcs11.mechanism.generic.AutoMech(mech_type='UNKNOWN', params=None)

Bases: pypkcs11.mechanism.helpers.Mechanism

An attempt to examine underlying C Struct and fill in the appropriate fields, making some assumptions about the data. This works best with parameter structs that only have CK_ULONGs within them (though there is a best-effort attempt to handle arrays).

Warning

Do not use this if the mechanism is already defined!

to_c_mech()

Attempt to handle generic mechanisms by introspection of the structure.

Returns:CK_MECHANISM
class pypkcs11.mechanism.generic.ConcatenationDeriveMechanism(mech_type='UNKNOWN', params=None)

Bases: pypkcs11.mechanism.helpers.Mechanism

Mechanism class for key derivations. This will take in a second key handle in the parameters, and use it in the resulting Structure.

Warning

This mechanism is disabled in later versions of PCKS11.

REQUIRED_PARAMS = ['h_second_key']
to_c_mech()

Add in a pointer to the second key in the resulting mech structure.

Returns:CK_MECHANISM
class pypkcs11.mechanism.generic.NullMech(mech_type='UNKNOWN', params=None)

Bases: pypkcs11.mechanism.helpers.Mechanism

Class that creates a mechanism from a flavor with null parameters. Used mostly for signing mechanisms that really don’t need anything else.

to_c_mech()

Simply set the pParameter to null pointer.

Returns:CK_MECHANISM
class pypkcs11.mechanism.generic.StringDataDerivationMechanism(mech_type='UNKNOWN', params=None)

Bases: pypkcs11.mechanism.helpers.Mechanism

Mechanism class for key derivation using passed in string data.

REQUIRED_PARAMS = ['data']
to_c_mech()

Convert data to bytearray, then use in the resulting mech structure.

Returns:CK_MECHANISM

RC Mechanisms

RC-related Mechanism implementations

class pypkcs11.mechanism.rc.RC2CBCMechanism(mech_type='UNKNOWN', params=None)

Bases: pypkcs11.mechanism.helpers.Mechanism

Creates required RC2CBC Param structure & converts python data to C data.

REQUIRED_PARAMS = ['usEffectiveBits', 'iv']
to_c_mech()

Convert extra parameters to ctypes, then build out the mechanism.

Returns:CK_MECHANISM
class pypkcs11.mechanism.rc.RC2Mechanism(mech_type='UNKNOWN', params=None)

Bases: pypkcs11.mechanism.helpers.Mechanism

Sets the mechanism parameter to the usEffectiveBits

REQUIRED_PARAMS = ['usEffectiveBits']
to_c_mech()

Convert extra parameters to ctypes, then build out the mechanism.

Returns:CK_MECHANISM
class pypkcs11.mechanism.rc.RC5CBCMechanism(mech_type='UNKNOWN', params=None)

Bases: pypkcs11.mechanism.helpers.Mechanism

Creates required RC5CBC Param structure & converts python data to C data.

REQUIRED_PARAMS = ['ulWordsize', 'ulRounds', 'iv']
to_c_mech()

Convert extra parameters to ctypes, then build out the mechanism.

Returns:CK_MECHANISM
class pypkcs11.mechanism.rc.RC5Mechanism(mech_type='UNKNOWN', params=None)

Bases: pypkcs11.mechanism.helpers.Mechanism

Creates required RC5 Param structure & converts python data to C data.

REQUIRED_PARAMS = ['ulWordsize', 'ulRounds']
to_c_mech()

Convert extra parameters to ctypes, then build out the mechanism.

Returns:CK_MECHANISM

RSA Mechanisms

RSA-related Mechanism implementations.

class pypkcs11.mechanism.rsa.RSAPKCSOAEPMechanism(mech_type='UNKNOWN', params=None)

Bases: pypkcs11.mechanism.helpers.Mechanism

Create the required RSA_PKCS_OAEP param structure & convert python data to C data.

REQUIRED_PARAMS = ['hashAlg', 'mgf']
to_c_mech()

Convert extra parameters to ctypes, then build out the mechanism.

Returns:CK_MECHANISM
class pypkcs11.mechanism.rsa.RSAPKCSPSSMechanism(mech_type='UNKNOWN', params=None)

Bases: pypkcs11.mechanism.helpers.Mechanism

Create the required RSA_PKCS_PSS param structure & convert python data to C data.

REQUIRED_PARAMS = ['hashAlg', 'mgf']
to_c_mech()

Uses default salt length of 8. Can be overridden w/ a parameter though.

Returns:CK_MECHANISM

Unbound Mechanisms

Unbound vendor specific mechanisms.

class pypkcs11.mechanism.unbound.EcdsaBipDeriveMechanism(isHardened, childNum)

Bases: pypkcs11.mechanism.helpers.Mechanism

ECDSA BIP key derivation mechanism Parameters for ECDSA BIP Derive :param Boolean isHardened :param int childNum: The child derivation index.

REQUIRED_PARAMS = ['hardened', 'ulChildNumber']
to_c_mech()

Create the Param structure, then convert the data into byte arrays.

Returns:CK_MECHANISM