CKM_BIP32_CHILD_DERIVE

Supported Operations

Encrypt and Decrypt Yes
Sign and Verify Yes
SignRecover and VerifyRecover Yes
Digest Yes
Generate Key/Key-Pair No
Wrap and Unwrap Yes
Derive Yes
Available in FIPS Mode No

Key Size Range (bits) and Parameters

Minimum 64
Maximum 571
Parameter CKM_BIP32_CHILD_DERIVE_PARAMS

Description

Generates a BIP32 Child node key pair from a BIP32 key.

The child derived keys need a BIP32 key as the base key to be effective. Private and hardened keys can only be derived using private keys.

When generating the child key, you need to specify the depth of the derived key with respect to the base key, as well as the index value at each level. The base key must have the following characteristics:

>CKK_BIP32 -- using any other key type as a base key will result in an error (CKR_KEY_TYPE_INCONSISTENT)

>128-512 bits of data -- using a seed outside of this range will result in an error (CKR_BIP32_MASTER_SEED_LEN_INVALID)

This mechanism has a parameter, a CKM_BIP32_CHILD_DERIVE_PARAMS structure, defined as follows:

typedef struct CK_BIP32_CHILD_DERIVE_PARAMS {
    CK_ATTRIBUTE_PTR pPublicKeyTemplate;
    CK_ULONG ulPublicKeyAttributeCount;
    CK_ATTRIBUTE_PTR pPrivateKeyTemplate;
    CK_ULONG ulPrivateKeyAttributeCount;
    CK_ULONG_PTR pulPath;
    CK_ULONG ulPathLen;
    CK_OBJECT_HANDLE hPublicKey;
    CK_OBJECT_HANDLE hPrivateKey;
    CK_ULONG ulPathErrorIndex;
} CK_BIP32_CHILD_DERIVE_PARAMS;
 

The fields of this structure are defined as follows:

pPublicKeyTemplate Points to the key attributes for the public key.
ulPublicKeyAttributeCount States the number of attributes in the public key template.
pPrivateKeyTemplate Points to the key attributes for the private key.
ulPrivateKeyAttributeCount States the number of key attributes in the private key template.
pulPath  
ulPathLen  
hPublicKey Returns the public object handle after a successful key derivation.
hPrivateKey Returns the private object handle after a successful key derivation.

If the attribute count is set to zero or the template is set to NULL, the public or private key will not be generated.

If both attribute count properties are set to zero and/or both key templates are set to NULL, an error will result (CKR_MECHANISM_PARAM_INVALID).

If ulPathLen is set to zero and/or pulPath is set to NULL, an error will result (CKR_MECHANISM_PARAM_INVALID).

The following restrictions apply to both templates:

>The CKA_KEY_TYPE value must be CKK_BIP32. Using any other key type will result in an error (CKR_TEMPLATE_INCONSISTENT).

>The only allowable curve for BIP32 is secp256k1. Setting an ECC curve will result in an error (CKR_TEMPLATE_INCONSISTENT).

If a step fails during the derivation, the depth at which the failure occurred will be stored in the ulPathErrorIndex parameter.

If a private key cannot be produced due to passing an invalid index, an error will result (CKR_BIP32_CHILD_INDEX_INVALID).

If a base public key is used to derive a private key, an error will result (CKR_ARGUMENTS_BAD).

If a base public key is used to derive a hardened key, an error will result (CKR_BIP32_INVALID_HARDENED_DERIVATION).

NOTE   For leaf children nodes, both the public and private keys must have the CKA_DERIVE attribute disabled to prevent further key derivations.

Sample

CK_RV generateChildKeyPair(
      CK_SESSION_HANDLE hPrivateSession
    , CK_OBJECT_HANDLE hParent
    , CK_OBJECT_HANDLE& hPubKey
    , CK_OBJECT_HANDLE& hPriKey
    )
{
    CK_RV retCode = CKR_OK;
    CK_BYTE no = 0;
    CK_BYTE yes = 1;
    CK_ULONG indexPath[] = {0,1,4};
 
    CK_NUMERIC kt = CKK_BIP32;
    CK_OBJECT_HANDLE tmpHandle;
 
    CK_ATTRIBUTE pubKeyTemplate[] = {
        {CKA_DERIVE,      &yes,         sizeof(yes)},
        {CKA_KEY_TYPE, &kt,sizeof(kt)  }
    };
 
    CK_ATTRIBUTE priKeyTemplate[] = {
        {CKA_DERIVE,      &yes,         sizeof(yes)},
        {CKA_KEY_TYPE, &kt,sizeof(kt)  }
    };
 
    CK_MECHANISM     deriveMech = { CKM_BIP32_CHILD_DERIVE, NULL_PTR, 0 };
    CK_BIP32_CHILD_DERIVE_PARAMS BIP32_Params;
 
    BIP32_Params.pPrivateKeyTemplate = priKeyTemplate;
    BIP32_Params.ulPrivateKeyAttributeCount = (sizeof(priKeyTemplate) / sizeof(CK_ATTRIBUTE));
    BIP32_Params.pPublicKeyTemplate = pubKeyTemplate;
    BIP32_Params.ulPublicKeyAttributeCount = (sizeof(pubKeyTemplate) / sizeof(CK_ATTRIBUTE));
    BIP32_Params.pulPath = indexPath;
    BIP32_Params.ulPathLen = 3;
 
    deriveMech.pParameter = &BIP32_Params;
    deriveMech.usParameterLen = sizeof(BIP32_Params);
 
    retCode = C_DeriveKey(hPrivateSession, (CK_MECHANISM_PTR)&deriveMech, hParent,
        (CK_ATTRIBUTE_PTR)priKeyTemplate, (sizeof(priKeyTemplate) / sizeof(CK_ATTRIBUTE)),
        &tmpHandle);
    hPubKey = BIP32_Params.hPublicKey;
    hPriKey = BIP32_Params.hPrivateKey;
    return retCode;
}
 

Return to SafeNet ProtectToolkit-C Mechanisms