Key Export Features
The SafeNet Key Export HSM provides the feature(s) detailed in this section.
RSA Key Component Wrapping
The RSA Key Component Wrapping is a feature that allows an application to wrap any subset of attributes from an RSA private key with 3-DES. Access to the feature is through the PKCS #11 function C_WrapKey with the CKM_DES3_ECB mechanism. The wrapping key must be a CKK_DES2 or CKK_DES3 key with its CKA_WRAP attribute set to TRUE. The key to wrap must be an RSA private key with CKA_EXTRACTABLE set to TRUE and the FPV must have FPV_WRAPPING_TOKEN turned on.
The details of the wrapping format are specified with a format descriptor. The format descriptor is provided as the mechanism parameter to the CKM_DES3_ECB mechanism. This descriptor consists of a 32-bit format version, followed by a set of field element descriptors. Each field element descriptor consists of a 32-bit Field Type Identifier and optionally some additional data. The SafeNet firmware parses the set of field element descriptors and builds the custom layout of the RSA private key in an internal buffer. Once all field element descriptors are processed, the buffer is wrapped with 3-DES and passed out to the calling application. It is the responsibility of the calling application to ensure that the buffer is a multiple of 8 bytes.
The format descriptor version (the first 32-bit value in the format data) must always be set to zero.
The set of supported field element descriptor constants is as follows:
>#define KM_APPEND_STRING 0x00000000
>#define KM_APPEND_ATTRIBUTE 0x00000001
>#define KM_APPEND_REVERSED_ATTRIBUTE 0x00000002
>#define KM_APPEND_RFC1423_PADDING 0x00000010
>#define KM_APPEND_ZERO_PADDING 0x00000011
>#define KM_APPEND_ZERO_WORD_PADDING 0x00000012
>#define KM_APPEND_INV_XOR_CHECKSUM 0x00000020
>#define KM_DEFINE_IV_FOR_CBC 0x00000030
The meanings of the field element descriptors is as follows:
Field element descriptor | Description |
---|---|
KM_APPEND_STRING |
Appends an arbitrary string of bytes to the custom layout buffer. The field type identifier is followed by a 32-bit length field defining the number of bytes to append. The length field is followed by the bytes to append. There is no restriction of the length of data that may be appended, as long as the total buffer length does not exceed 3072 bytes. |
KM_APPEND_ATTRIBUTE |
Appends an RSA private key component into the buffer in big endian representation. The field type identifier is followed by a 32-bit CK_ATTRIBUTE_TYPE value set to one of the following: CKA_PRIVATE_EXPONENT, CKA_PRIME_1, CKA_PRIME_2, CKA_EXPONENT_1, CKA_EXPONENT_2, or CKA_COEFFICIENT.. The key component is padded with leading zeros such that the length is equal to the modulus length in the case of the private exponent, or equal to half of the modulus length in the case of the other 5 components. |
KM_APPEND_REVERSED_ATTRIBUTE |
Appends an RSA private key component into the buffer in little endian representation. The field type identifier is followed by a 32-bit CK_ATTRIBUTE_TYPE value set to one of the following: CKA_PRIVATE_EXPONENT, CKA_PRIME_1, CKA_PRIME_2, CKA_EXPONENT_1, CKA_EXPONENT_2, or CKA_COEFFICIENT. The key component is padded with trailing zeros such that the length is equal to the modulus length in the case of the private exponent, or equal to half of the modulus length in the case of the other 5 components. |
KM_APPEND_RFC1423_PADDING |
Applies RFC 1423 padding to the buffer (appends 1 to 8 bytes with values equal to the number of bytes, such that the total buffer length becomes a multiple of 8). This would typically be the last formatting element in a set, but this is not enforced. |
KM_APPEND_ZERO_PADDING |
Applies Zero padding to the buffer (appends 0 to 7 bytes with values equal to Zero, such that the total buffer length becomes a multiple of 8). This would typically be the last formatting element in a set, but this is not enforced. |
KM_APPEND_ZERO_WORD_PADDING | Zero pads the buffer to the next 32-bit word boundary. |
KM_APPEND_INV_XOR_CHECKSUM |
Calculates and adds a checksum byte to the buffer. The checksum is calculated as the complement of the bytewise XOR of the buffer being built. |
KM_DEFINE_IV_FOR_CBC |
Allows definition of an IV so that 3DES_CBC wrapping can be performed even though the functionality is invoked with the CKM_3DES_ECB mechanism. The field type identifier is followed by a 32-bit length field, which must be set to 8. The length is followed by exactly 8 bytes of data which are used as the IV for the wrapping operation. |
Examples
To wrap just the private exponent of an RSA key in big endian representation, the parameters would appear as follows:
NOTE Ensure that the packing alignment for your structures
uses one (1) byte boundaries.
struct { UInt32 version = 0; UInt32 elementType = KM_APPEND_ATTRIBUTE; CK_ATTRIBUTE_TYPE attribute = CKA_PRIVATE_EXPONENT; }
To wrap the set of RSA key components Prime1, Prime2, Coefficient, Exponent1, Exponent2 in little endian representation with a leading byte of 0x05 and ending with a CRC byte and then zero padding, the parameters would appear in a packed structure as follows:
struct { UInt32 version = 0; UInt32 elementType1 = KM_APPEND_STRING; UInt32 length = 1; UInt8 byteValue = 5; UInt32 elementType2 = KM_APPEND_REVERSED_ATTRIBUTE; CK_ATTRIBUTE_TYPE attribute1 = CKA_PRIME_1; UInt32 elementType3 = KM_APPEND_REVERSED_ATTRIBUTE; CK_ATTRIBUTE_TYPE attribute2 = CKA_PRIME_2; UInt32 elementType4 = KM_APPEND_REVERSED_ATTRIBUTE; CK_ATTRIBUTE_TYPE attribute3 = CKA_COEFFICIENT; UInt32 elementType5 = KM_APPEND_REVERSED_ATTRIBUTE; CK_ATTRIBUTE_TYPE attribute4 = CKA_EXPONENT_1; UInt32 elementType6 = KM_APPEND_REVERSED_ATTRIBUTE; CK_ATTRIBUTE_TYPE attribute5 = CKA_EXPONENT_2; UInt32 elementType7 = KM_APPEND_INV_XOR_CHECKSUM; UInt32 elementType8 = KM_APPEND_ZERO_PADDING; }