Key structures
This chapter describes the data structures used by the nShield module to represent keys and their ACLs. It includes information about:
-
mechanisms
which are the combination of algorithm, padding, and mode that are used to transform plain text into cipher text or cipher text into plain text. -
plain texts
which are the messages being processed. This chapter lists the plain text formats that are supported by the nShield module. -
keys
which are the secret and public values used in an algorithm. The section of this chapter about keys describes:-
the format for each key type
-
the mechanisms supported for that key type
-
the parameters required to generate a key or key pair of this type.
-
-
hash functions
which return a fixed-length string from arbitrary-length input. Hash functions can be used to identify a document without revealing its contents. -
Access Control Lists (ACLs)
which describe the actions that can be performed with a specific key. This chapter describes the format of an ACL. -
certificates
which are used to authorize actions on keys.
Mechanisms
A mechanism is a combination of padding, algorithm, mode, and so forth, which, together with a key, transforms a plaintext into a ciphertext (or a ciphertext into a plaintext).
Each mechanism has a single ciphertext format represented by M_CipherText
, a tagged union type for which the tag is an M_Mech
.
A mechanism may accept or generate various different plain text formats.
The details of the padding and other processing may vary depending on the plain text format supplied or requested.
Mechanisms with similar forms share the same member name in this union. For example, the 64-bit block ciphers all use Mech_Generic64 . |
union M_Mech__Cipher {
M_Mech_SHA384Hash_Cipher sha384hash;
M_Mech_DSA_Cipher dsa;
M_Mech_SHA256Hash_Cipher sha256hash;
M_Mech_DLIESe3DEShSHA1_Cipher dliese3deshsha1;
M_Mech_TigerHash_Cipher tigerhash;
M_Mech_DHKeyExchange_Cipher dhkeyexchange;
M_Mech_HAS160Hash_Cipher has160hash;
M_Mech_ECDHKeyExchange_Cipher ecdhkeyexchange;
M_Mech_RSApPKCS1_Cipher rsappkcs1;
M_Mech_Imech_Cipher imech;
M_Mech_ArcFourpNONE_Cipher arcfourpnone;
M_Mech_Generic256MAC_Cipher generic256mac;
M_Mech_ElGamal_Cipher elgamal;
M_Mech_RSApPKCS1pPKCS11_Cipher rsappkcs1ppkcs11;
M_Mech_BlobCrypt_Cipher blobcrypt;
M_Mech_Generic128_Cipher generic128;
M_Mech_Generic192MAC_Cipher generic192mac;
M_Mech_ECDSA_Cipher ecdsa;
M_Mech_Generic64_Cipher generic64;
M_Mech_SHA512Hash_Cipher sha512hash;
M_Mech_SHA224Hash_Cipher sha224hash;
M_Mech_Generic256_Cipher generic256;
M_Mech_Generic192_Cipher generic192;
M_Mech_KCDSAHAS160_Cipher kcdsahas160;
M_Mech_Generic64MAC_Cipher generic64mac;
M_Mech_GenericGCM128_Cipher genericgcm128;
M_Mech_RIPEMD160Hash_Cipher ripemd160hash;
M_Mech_Generic128MAC_Cipher generic128mac;
M_Mech_MD5Hash_Cipher md5hash;
M_Mech_SHA1Hash_Cipher sha1hash;
};
Mech_Any
Instead of explicitly specifying a mechanism, you can let the module select the mechanism by specifying Mech_Any
.
The nShield module selects the mechanism as follows:
-
for decryption or signature verification, the module uses the mechanism that is defined in the cipher text
-
for encryption or signature generation, the module selects an appropriate mechanism based on the key type and the operation as listed in the following table.
Key Type | Encryption mechanism | Signing mechanism |
---|---|---|
RSAPublic |
|
|
RSAPrivate |
|
|
DHPublic |
|
|
DSAPrivate |
|
|
ECDSAPrivate |
|
|
DES (not available in FIPS 140 Level 3 operational mode) |
|
|
DES2 |
|
|
DES3 |
|
|
CAST |
|
|
CAST256 |
|
|
ArcFour |
|
|
Rijndael |
|
|
Blowfish |
|
|
Twofish |
|
|
Serpent |
|
|
Key Types
The following sections list the keys types for the different algorithms and mechanisms that are supported by the module. The table below shows which mechanisms are supported by which key types.
Key type | Block size | Encrypt | Decrypt | Sign | Verify |
---|---|---|---|---|---|
|
N/A |
Y |
Y |
- |
- |
|
64 |
||||
Y |
Y |
- |
- |
||
CBC MAC |
- |
- |
Y |
Y |
|
ECB |
Y |
Y |
- |
- |
|
|
64 |
||||
CBC |
Y |
Y |
- |
- |
|
CBC MAC |
- |
- |
Y |
Y |
|
ECB |
Y |
Y |
- |
- |
|
|
128 |
||||
CBC |
Y |
Y |
- |
- |
|
CBC MAC |
- |
- |
Y |
Y |
|
ECB |
Y |
Y |
- |
- |
|
|
64 |
||||
CBC |
Y |
Y |
- |
- |
|
CBC MAC |
- |
- |
Y |
Y |
|
ECB |
Y |
Y |
- |
- |
|
|
64 |
||||
CBC |
Y |
Y |
- |
- |
|
CBC MAC |
- |
- |
Y |
Y |
|
ECB |
Y |
Y |
- |
- |
|
|
64 |
||||
CBC |
Y |
Y |
- |
- |
|
CBC MAC |
- |
- |
Y |
Y |
|
ECB |
Y |
Y |
- |
- |
|
|
128 |
||||
CBC |
Y |
Y |
- |
- |
|
CBC MAC |
- |
- |
Y |
Y |
|
ECB |
Y |
Y |
- |
- |
|
|
128 |
||||
CBC |
Y |
Y |
- |
- |
|
CBC MAC |
- |
- |
Y |
Y |
|
ECB |
Y |
Y |
- |
- |
|
|
128 |
||||
CBC |
Y |
Y |
- |
- |
|
CBC MAC |
- |
- |
Y |
Y |
|
ECB |
Y |
Y |
- |
- |
|
GCM |
Y |
Y |
- |
- |
|
|
128 |
||||
CBC |
Y |
Y |
- |
- |
|
CBC MAC |
- |
- |
Y |
Y |
|
ECB |
Y |
Y |
- |
- |
|
|
N/A |
||||
Key Exchange |
- |
Y |
- |
- |
|
ElGamal |
Y |
Y |
- |
- |
|
|
N/A |
- |
- |
Y |
Y |
|
N/A |
- |
- |
Y |
Y |
|
N/A |
||||
Key Exchange |
- |
Y |
- |
- |
|
|
- |
- |
Y |
Y |
|
|
N/A |
- |
- |
Y |
Y |
|
N/A |
||||
HMACMD2 |
- |
- |
Y |
Y |
|
HMACMD5 |
- |
- |
Y |
Y |
|
HMACSHA-1 |
- |
- |
Y |
Y |
|
HMACRIPEMD160 |
- |
- |
Y |
Y |
|
HMACSHA224 |
- |
- |
Y |
Y |
|
HMACSHA256 |
- |
- |
Y |
Y |
|
HMACSHA384 |
- |
- |
Y |
Y |
|
HMACSHA512 |
- |
- |
Y |
Y |
|
HMACSHA3b224 |
- |
- |
Y |
Y |
|
HMACSHA3b256 |
- |
- |
Y |
Y |
|
HMACSHA3b384 |
- |
- |
Y |
Y |
|
HMACSHA3b512 |
- |
- |
Y |
Y |
|
HMACTiger |
- |
- |
Y |
Y |
|
|
N/A |
||||
|
N/A |
- |
- |
- |
- |
|
N/A |
- |
- |
- |
- |
For each key type, the tables below list:
-
the data that is stored in the key (separately for public and private halves of key pairs)
-
the parameters required to generate the key (or key pair):
typedef struct {
M_KeyType type;
union M_KeyType__Data data;
} M_PlainText ;
typedef struct {
M_KeyType type;
union M_KeyType__GenParams params;
} M_KeyGenParams;
Key types with similar forms for key data or generation parameters share the same member name in these unions.
For example, keys whose data is a single block of random bytes (CAST, ArcFour, Random, HMACMD2, HMACMD5, HMACRIPEMD160, and Wrapped) all use the Random members of these unions.
|
Random
ArcFour
This key type is a symmetric algorithm that is compatible with Ron Rivest’s RC4 cipher.
It uses the key data M_KeyType_Random_Data
.
Blowfish
Blowfish uses the key data M_KeyType_Random_Data
.
The key data length must be at least one byte.
The maximum permitted key data length is 56 bytes.
Recommended key lengths are 16, 24, 32 and 56 bytes.
Key generation parameters
typedef struct {
M_Word lenbytes; length in bytes
} M_KeyType_Random_GenParams;
Mechanisms
|
ECB |
|
CBC |
|
CBC |
|
CBC MAC see note |
|
ECB |
|
CBC MAC |
The mechanism Mech_BlowfishmCBCMACi64PKCS5 is deprecated and may be withdrawn in future firmware.
|
CAST
This key type uses the key data M_KeyType_Random_Data
, with a key length from 5 to 16 bytes as specified in RFC2144.
Mechanisms
|
CBC |
|
see note |
|
ECB |
|
CBC MAC |
The mechanism Mech_CASTmCBCMACi64pPKCS5 is deprecated and may be withdrawn in future firmware.
|
The cipher text and initialization vectors are the same as for the equivalent DES mechanisms.
CAST256
This uses the same key generation parameters and data as KeyType_Random
, and allows key lengths of 16, 20, 24, 28 or 32 bytes as specified in RFC2612.
Mechanisms
|
CBC with PKCS #5 padding |
|
ECB with PKCS #5 padding |
|
CBC with no padding |
|
ECB with no padding |
|
see note |
|
CBC MAC |
The mechanism Mech_CAST256mCBCMACi128pPKCS5
is deprecated and may be withdrawn in future versions.
DES
The implementation of DES that is used in the nShield module has been validated by NIST as conforming to FIPS 46-2 and FIPS 81, certificate number 24. |
Key data
typedef struct {
M_DESKey k; 64 bit key
} M_KeyType_DES_Data;
typedef union {
unsigned char bytes[8];
M_Word words[2];
} M_DESKey;
56 bits plus 8 parity bits |
Key generation parameters
typedef struct {
M_Word lenbytes; length in bytes
} M_KeyType_Random_GenParams;
Notes
The FIPS 46-2 validation requires DES keys to have valid parity bits for which bit 0 of each byte is set to give odd parity.
If you attempt to import a DES key that does not have the parity set correctly, the module will return Status_InvalidData
.
Mechanisms
|
CBC no padding |
|
CBC with PKCS5 padding |
|
see note |
|
ECB no padding |
|
ECB with PKCS5 padding |
|
CBC MAC with PKCS5 padding |
|
CBC MAC with no padding |
PKCS5 padding is 1 to 8 bytes, valued 1 to 8
The mechanism Mech_DESmCBCMACi64pPKCS5 is deprecated and may be withdrawn in future versions.
|
CBC MAC
Cipher text
typedef struct {
M_Block64 mac;
} M_Mech_Generic64MAC_Cipher;
The DESmCBCMACi0pPKCS5 mechanism uses an IV of all zero bytes.
This replaces the DESmCBCMACi64pPKCS5 mechanism, which required the IV to be passed in.
This mechanism is deprecated: if an attacker is able to manipulate this data he is able to forge a message.
For this reason, if you use -i64 mechanisms you must ensure the IV data is fixed.
|
DES2
The implementation of DES used in the nShield module has been validated by NIST as conforming to FIPS 46-3 certificate numbers 24 and 173. |
Key data
typedef struct {
M_DES2Key k; 128 bit key
} M_KeyType_DES2_Data;
typedef union {
unsigned char bytes[16];
M_Word words[4];
} M_DESKey;
112 bit plus 16 parity bits. |
Notes
The FIPS 46-2 validation requires DES2 keys to have valid parity bits for which bit 0 of each byte is set to give odd parity.
If you attempt to import a DES2 key that does not have the parity set correctly, the module will return Status_InvalidData
.
Mechanisms
|
CBC no padding |
|
CBC with PKCS5 padding |
|
see note |
|
ECB no padding |
|
ECB with PKCS5 padding |
|
CBCMAC with PKCS5 padding |
|
CBC MAC with no padding |
The mechanism Mech_DES2mCBCMACi64pPKCS5 is deprecated and may be withdrawn in future versions.
|
Triple DES
The implementation of DES used in the module has been validated by NIST as conforming to FIPS 46-3 certificate numbers 24 and 173. |
Key data
typedef struct {
M_DES3Key k 192 bit key
} M_KeyType_DES3_Data;
typedef union {
unsigned char bytes[24];
M_Word words[6];
} M_DES3Key;
The key is 3 x(56+8) bits. nShield performs Triple DES as encrypt, decrypt, and encrypt (using separate keys for each stage). |
Mechanisms
|
CBC with PKCS #5 padding |
|
see note |
|
CBC with no padding |
|
ECB with no padding |
|
ECB with PKCS #5 padding |
|
CBCMAC with PKCS #5 padding |
|
CBC MAC with no padding |
The mechanism Mech_DES3mCBCMACi64pPKCS5 is deprecated and may be withdrawn in future versions.
|
The cipher text and initialization vectors are the same as for the equivalent DES mechanisms.
nShield uses outer CBC. |
Rijndael
Rijndael is now FIPS approved as the AES. The implementation has been validated by NIST as conforming to FIPS 197, certificate number 15. |
This key type uses the key data M_KeyType_Random_Data
.
Mechanisms
|
CBC |
|
CBC with PKCS5 padding |
|
see note |
|
ECB |
|
ECB with PKCS5 padding |
|
CBC MAC with PKCS5 padding |
|
CBC MAC with no padding |
|
GCM |
The mechanism Mech_RijndaelmCBCMACi128pPKCS5 is deprecated and may be withdrawn in future versions.
|
These mechanisms use the Generic128 cipher text and initialization vectors, except Mech_RijndaelmGCM
which uses GenericGCM128.
SEED
The SEED algorithm was developed by KISA (Korea Information Security Agency) and a group of experts. SEED is a Korean national industrial association standard (TTA KO-12.0004, 1999) and was set as a Korean Information Communication Standard (KICS) in the year 2000. This standard is promoted by the Korean Ministry of Information and Communication.
SEED has been optimized for the security systems most widely used in Korea, in particular the S-boxes and configurations associated with current computing technology.
If you wish to use the SEED algorithm, you must order and enable it as part of the nShield KISAAlgorithms feature, as described in the User Guide.
|
Key generation parameters
typedef struct {
M_Word lenbytes; must be 16 bytes
} M_KeyType_SEED_GenParams;
Mechanisms
|
ECB with no padding |
|
ECB with PKCS #5 padding |
|
CBC with no padding |
|
CBC with PKCS #5 padding |
|
see note |
|
CBCMAC |
The mechanism Mech_SEEDmCBCMACi128pPKCS5 is deprecated and may be withdrawn in future versions.
|
Serpent
Serpent uses the key data M_KeyType_Random_Data
.
The maximum permitted key data length is 32 bytes.
Recommended key lengths are 16, 24 and 32 bytes.
A change was made to the interpretation of the Serpent algorithm specification regarding byte ordering, which occurred between versions 2.12.x and earlier, and 2.18.x and later, of module firmware. Thus, later versions of firmware are incompatible with earlier versions when using Serpent mechanisms. |
Key generation parameters
typedef struct {
M_Word lenbytes; length in bytes
} M_KeyType_Random_GenParams;
Mechanisms
|
ECB with no padding |
|
CBC with no padding |
|
CBC with PKCS #5 padding |
|
see note |
|
ECB with PKCS #5 padding |
|
CBCMAC |
The mechanism Mech_SerpentmCBCMACi128PKCS5 is deprecated and may be withdrawn in future versions.
|
Twofish
Twofish uses the key data M_KeyType_Random_Data
.
The maximum permitted key data length is 32 bytes.
Recommended key lengths are 16, 24 and 32 bytes.
Key generation parameters
typedef struct {
M_Word lenbytes; length in bytes
} M_KeyType_Random_GenParams;
Mechanisms
|
ECB with no padding |
|
CBC with no padding |
|
CBC with PKCS #5 padding |
|
see note |
|
ECB with PKCS #5 padding |
|
CBCMAC |
The mechanism Mech_TwofishmCBCMACi128PKCS5 is deprecated and may be withdrawn in future versions.
|
Diffie-Hellman and ElGamal
Diffie-Hellman key exchange shares a common key type with ElGamal encryption and decryption.
Private key
typedef struct {
M_DiscreteLogGroup dlg;
M_Bignum x;
} M_KeyType_DHPrivate_Data
M_DiscreteLogGroup
is a discrete log group that may be shared between users.
Public key
typedef struct {
M_DiscreteLogGroup dlg;
M_Bignum gx;
} M_KeyType_DHPublic_Data
M_DiscreteLogGroup
is a discrete log group that may be shared between users.
Key generation parameters
typedef struct {
M_Word flags;
M_Word plength;
M_Word xlength;
M_DiscreteLogGroup *dlg;
} M_KeyType_DHPrivate_GenParams;
-
The following
flags
are defined:-
KeyType_DHPrivate_GenParams_flags_dlg_present
(If this is set, the specifiedDiscreteLogGroup
will be used.) -
KeyType_DHPrivate_GenParams_flags_SafePrimes
(If this is set, the module will generate the key, so that the key validation code can verify that the key has known good sub-group.) -
KeyType_DHPrivate_GenParams_flags__allflags
-
-
plength
is key size in bits up to a maximum of 4096.The present implementation uses the DSA/FIPS algorithm for generating G
andP
parameters, such thatP
must be a multiple of 64 bits in length and at least 512 bits long. -
xlength
is the length in bits of private key X . DSA specifies 160 bits.There is no upper limit on the length of
P
.(P - 1)
will have one prime factor of at least 160 bits, which is required in order to make Pohlig-Hellman discrete logs unworkable. The length of the private exponentX
can be specified separately. -
M_DiscreteLogGroup
is a discrete log group that may be shared between users.typedef struct { M_Bignum p prime M_Bignum g generator mod P } M_DiscreteLogGroup;
DSA considers an exponent of 160 bits to be sufficient for security. An attempt to make the length of X
greater than the length ofP
will have no effect.
Mechanisms
|
|
|
|
Diffie-Hellman
There is only one cryptographic operation, Decrypt
, which is supported with the mechanism DHKeyExchange
and the key type DHPrivate
.
A Diffie-Hellman key exchange goes as follows:
-
Alice generates a DH key pair and exports her public key.
-
Bob generates a DH key pair by using Alice’s
G
andP
values and by setting thedlg_present
bit in the flags toGenerateKeyPair
. He then exports his public key. -
Alice takes Bob’s public key and passes it as a ciphertext to
Decrypt
using her private key. This returns, in bignum format: -
Bob takes Alice’s public key and passes it to Decrypt using his private key. This returns, in bignum format:
This result is the same as that which Alice derived.
-
The session key can then be derived from this multi-precision number.
ElGamal
At present, ElGamal encryption only takes nShield bignums as the plain text input and the output format.
DLIES
The DLIESe3DEShSHA1
and DLIESeAEShSHA1
mechanisms implement the DLIES encryption and decryption primitive as described in IEEE P1363A (Draft 11, December 16 2002), with the following options:
-
DLSVDP-DH as the secret value derivation primitive
-
KDF2 key derivation function, using SHA-1 as the underlying hash function
-
Triple-DES-CBC-IV0 with 24-byte keys (
Mech_DLIESe3DEShSHA1
) or AES256-CBC-IV0 with 16-byte keys (Mech_DLIESeAEShSHA1
) as the symmetric encryption scheme -
MAC1 based on SHA-1 as the message authentication scheme, with 160-bit output length and 160-bit key length
The Asymmetric Encryption Scheme (DHAES) mode is not used. |
DSA
DSA enables users to share Discrete Log parameters, with each user having their own public and private key.
DSA has 'communities', which are sets of keys that share a common DSADiscreteLogGroup
but that have different (x, y) pairs.
These are represented by the key type DSAComm
, which consists of a DSADiscreteLogGroup
set of values together with the initialization values (seed
, h
, and counter
) from which the DSADiscreteLogGroup
values were derived (as specified by the FIPS DSA specification).
A DSAComm
key can be generated once, and then the DSADiscreteLogGroup
from this DSAComm
generation can be used in subsequent DSAPrivate
generations.
DSAComm
key generation also allows seed values to be checked as follows:
-
When generating a
DSAComm
key, set theiv_present
flag bit, and pass in theseed
,counter
, andh
values. -
GenerateKey
will follow the FIPS algorithm to generate ap
,q
, andg
set, together with the associatedh
andcounter
values. -
You can now export the resulting
DSAComm
key and check thatp
,q
,g
,h
, andcounter
are what you were expecting. -
GenerateKey
will returnStatus_InvalidData
if the given seed cannot be used to produce a validp
,q
, org
value.
The implementation of DSA that is used in modules has been validated by NIST as conforming to FIPS 186, certificate number 11. |
DSA keys
DSA common key
typedef struct {
M_DSAInitValues iv;
M_DSADiscreteLogGroup dlg;
} M_KeyType_DSAComm_Data;
DSA public key
typedef struct {
M_DSADiscreteLogGroup dlg;
M_Bignum y;
} M_KeyType_DSAPrivate_Data;
M_DSAInitValues
:
typedef struct {
M_Hash seed seed
M_Word counter counter
M_Word h h
} M_DSAInitValues;
These are the initialization values, which can be used to check that the discrete logarithm parameters have been generated correctly.
M_DSADiscreteLogGroup
:
typedef struct {
M_Bignum p
M_Bignum q
M_Bignum g
} M_DSADiscreteLogGroup;
where
-
p
is a 512-bit to 1024-bit prime number; -
q
is a 160-bit prime factor ofp—1
; -
g
ish
((p—1)/q, whereh < p—1
andh
((p—1)/q)mod p > 1
. -
This is the discrete logarithm group. These values may be shared between users.
-
A 160-bit number
< q
.
g
xmod p
(a p
-bit number).
DSA common generation parameters
typedef struct {
M_Word flags;
M_Word lenbits;
M_DSAInitValues *iv;
} M_KeyType_DSAComm_GenParams;
The following flags
are defined:
-
KeyType_DSAComm_GenParams_flags_iv_present
-
KeyType_DSAComm_GenParams_flags__allflags
lenbits
is the length in bits
M_DSAInitValues
:
typedef struct {
M_Hash seed seed
M_Word counter counter
M_Word h h
} M_DSAInitValues;
These are the initialization values, which can be used to check that the discrete logarithm parameters have been generated correctly.
DSA private key generation parameters
typedef struct {
M_Word flags;
M_Word lenbits;
M_DSADiscreteLogGroup *dlg;
} M_KeyType_DSAPrivate_GenParams;
The following flags
are defined:
-
KeyType_DSAPrivate_GenParams_flags_dlg_present
(If this flag is set,GenerateKey
will use the specifiedDSADiscreteLogGroup
.) -
KeyType_DSAPrivate_GenParams_flags_Strict
(If this flag is set, the generated key is subjected to extra consistency tests at the expense of efficiency. There is normally no need to set this flag, unless you are supplyingp
,q
, andg
values and need to check them, or unless you require strict compliance with the FIPS 140 Level 3 standard. Setting theStrict
flag limits the maximum key size to 1024 bits. Otherwise, there is no maximum limit on key size.) -
KeyType_DSAPrivate_GenParams_flags__allflags
M_DSADiscreteLogGroup
is the discrete logarithm group.
These values may be shared between users.
typedef struct {
M_Bignum p;
M_Bignum q;
M_Bignum g;
} M_DSADiscreteLogGroup;
where:
-
p
is a 512-bit to 1024-bit prime number; -
q
is a 160-bit prime factor ofp—1
; -
g
ish
((p—1)/q, whereh < p—1
andh
((p—1)/q)mod p > 1
.
Cipher text
typedef struct {
M_Bignum r;
M_Bignum s;
} M_Mech_DSA_Cipher;
r
is g
k mod p mod q
s
is k
-1(H(m)+xr)) mod q
Plain text
Because DSA is defined to sign a SHA-1 hash directly, it has no separate raw plain text format.
Instead, the format Hash
is used to indicate that the plain text which has been provided is the SHA-1 hash.
Mech | Unhashed plain text type | Hash used for bytes plaintext |
---|---|---|
|
Hash |
|
|
Hash28 |
SHA-224 |
|
Hash32 |
SHA-256 |
|
Hash48 |
SHA-384 |
|
Hash64 |
SHA-512 |
|
Hash |
RIPEMD-160 |
If the plain text format is Bytes
, then the mechanism will hash the plain text itself before signing.
Elliptic Curve ECDH and ECDSA
The module supports key exchange, ECDH, and signature mechanisms.
The module supports a wide range of curves, including all the the curves listed in FIPS 186-2 and some curves from X9.62. It also allows a user to specify a custom curve.
The implementation of ECDSA over curves recommended for US Government use has been validated by NIST, as conforming to FIPS 186-2, certificate 2. |
When you create a key, you must create it as either an ECDSA key or an ECDH key. However, both keys use the same underlying structure. This ensures keys are used for the correct purpose and prevents inadvertent use of a signing key for key exchange, or an exchange key for signing message.
Elliptic Curve keys
Key generation parameters
struct M_KeyType_ECPrivate_GenParams {
M_EllipticCurve curve;
};
-
curve
is the curve used.
Cipher text - ECDH
struct M_Mech_ECDHKeyExchange_Cipher {
M_ECPoint gd;
};
-
gd
is the public point provided in the public key supplied in the key exchange.
Cipher text - ECDSA
struct M_Mech_ECDSA_Cipher {
M_Bignum r;
M_Bignum s;
};
r
is x
1 mod n
s
is s = k
-1(e + dr) mod n
.
Plain text - ECDH
Mech ECDHKeyExchange
can return plaintext as:
-
M_ECPoint
the canonical form; -
M_Bignum
the x coordinate of the point; -
M_Byteblock
in uncompressed octet string representation.
Plain text - ECDSA
ECDSA can accept plain text as either hash
or bytes
.
Mech | Unhashed plain text type | Hash used for bytes plaintext |
---|---|---|
|
Hash |
|
|
Hash28 |
SHA-224 |
|
Hash32 |
SHA-256 |
|
Hash48 |
SHA-384 |
|
Hash64 |
SHA-512 |
|
Hash |
RIPEMD-160 |
KCDSA
KCDSA is a Korean algorithm that has been standardized by the Korean government as KCS221. The compliance of nShield’s implementation compliance to this standard has not been independently verified.
If you wish to use the KCDSA algorithm, you must order and enable it as part of the KISAAlgorithms feature, as described in the User Guide.
If you are outside Korea, contact for information about obtaining the appropriate export licence.
|
KCDSA enables users to share Discrete Log parameters, with each user having their own public and private key.
KCDSA has communities, which are sets of keys that share a common KCDSADiscreteLogGroup
but that have different (x, y) pairs.
These are represented by the key type KCDSAComm
, which consists of a KCDSADiscreteLogGroup
set of values together with the initialization values (seed
and counter
) from which the KCDSADiscreteLogGroup
values were derived (as specified by the KCDSA specification).
A KCDSAComm
key can be generated once, and then the KCDSADiscreteLogGroup
from this KCDSAComm
generation can be used in subsequent KCDSAPrivate
generations.
KCDSAComm
key generation also allows seed values to be checked as follows:
-
When generating a
KCDSAComm
key, set theiv_present
flag bit, and pass in theseed
andcounter
values. -
GenerateKey
will follow the KCDSA algorithm to generate ap
,q
, andg
set. -
You can now export the resulting
KCDSAComm
key and check thatp
,q
, andg
are what you were expecting. -
GenerateKey
will returnStatus_InvalidData
if the givenseed
andcounter
cannot be used to produce a validp
,q
, org
value.
KCDSA keys
KCDSA common key
typedef struct {
M_KCDSAInitValues iv;
M_KCDSADiscreteLogGroup dlg;
} M_KeyType_KCDSAComm_Data;
M_KCDSAInitValues
typedef struct {
M_ByteBlock seed; seed
M_Word counter counter
} M_KCDSAInitValues;
These are the initialization values, which can be used to check that the discrete logarithm parameters have been generated correctly.
M_KCDSADiscreteLogGroup
is the discrete logarithm group.
These values may be shared between users.
typedef struct {
M_Bignum p;
M_Bignum q;
M_Bignum g;
} M_KCDSADiscreteLogGroup;
where:
-
p
is a 1024-bit to 2048-bit prime number which is a multiple of 256 bits long; -
q
is always 160 bits long; -
g
ish
((p—1)/q, whereh < p—1
andh
((p—1)/q)mod p > 1
.
KCDSA private key
typedef struct {
M_KCDSADiscreteLogGroup dlg;
M_Bignum y;
M_Bignum x;
} M_KeyType_KCDSAPublic_Data;
M_KCDSADiscreteLogGroup
is the discrete logarithm group.
These values may be shared between users.
typedef struct {
M_Bignum p;
M_Bignum q;
M_Bignum g;
} M_KCDSADiscreteLogGroup;
where:
-
p
is a 1024-bit to 2048-bit prime number which is a multiple of 256 bits long; -
q
is always 160 bits long; -
g
ish
((p—1)/q, whereh < p—1
andh
((p—1)/q)mod p > 1
. -
x
is an arbitrary number where0 < x < q
. -
y
isg
(1/x mod q)mod p
(a number less thanp
).
KCDSA public key
typedef struct {
M_KCDSADiscreteLogGroup dlg;
M_Bignum y;
} M_KeyType_KCDSAPrivate_Data;
M_KCDSADiscreteLogGroup
is the discrete logarithm group.
These values may be shared between users.
typedef struct {
M_Bignum p;
M_Bignum q;
M_Bignum g;
} M_KCDSADiscreteLogGroup;
where:
-
p
is a 1024-bit to 2048-bit prime number which is a multiple of 256 bits long; -
q
is always 160 bits long; ; -
g
ish
((p—1)/q, whereh < p—1
andh
((p—1)/q)mod p > 1
. -
y
isg
(1/x mod q)mod p
(a number less thanp
).
Key generation parameters
KCDSA common generation parameters
typedef struct {
M_Word flags;
M_Word plen;
M_Word qlen;
M_KCDSAInitValues *iv;
} M_KeyType_KCDSAComm_GenParams;
-
The following
flags
are defined:-
KeyType_KCDSAComm_GenParams_flags_iv_present
-
KeyType_KCDSAComm_GenParams_flags__allflags
-
-
plen
is the length ofp
in bits, a multiple of 256 where 1024 ≤plen
≤ 2048. -
qlen
is the length ofq
in bits, a multiple of 32 where 160 ≤qlen
≤256. This value must currently be 160.
M_KCDSAInitValues
typedef struct {
M_ByteBlock seed; seed
M_Word counter counter
} M_KCDSAInitValues;
These are the initialization values, which can be used to check that the discrete logarithm parameters have been generated correctly.
KCDSA private key generation parameters
typedef struct {
M_Word flags;
M_Word plen;
M_Word qlen;
M_KCDSADiscreteLogGroup *dlg;
} M_KeyType_KCDSAPrivate_GenParams;
-
The following
flags
are defined:-
KeyType_KCDSAPrivate_GenParams_flags_dlg_present
(If this flag is set,GenerateKey
will use the specifiedKCDSADiscreteLogGroup
.) -
KeyType_KCDSAPrivate_GenParams_flags__allflags
-
-
plen
is the length ofp
in bits. -
qlen
is the length ofq
in bits. -
M_KCDSADiscreteLogGroup
is the discrete logarithm group. These values may be shared between users.
typedef struct {
M_Bignum p;
M_Bignum q;
M_Bignum g;
} M_KCDSADiscreteLogGroup;
where:
-
p
is a 1024-bit to 2048-bit prime number which is a multiple of 256 bits long; -
q
is always 160 bits long; ; -
g
ish
((p—1)/q, whereh < p—1
andh
((p—1)/q)mod p > 1
.
Cipher text
typedef struct {
M_ByteBlock r;
M_Bignum s;
} M_Mech_KCDSA_Cipher;
-
r
ish(g
kmod p)
. -
s
isx(k - (r
⊕h (z||m))) mod q
The symbol ⊕ represents a bit-wise XOR operation.
The symbol || represents concatenation of Byteblock s
|
Plain text
See Key Types for a list of plain text formats. |
KCDSA hashes the message m
as h(z||m)
, where z
is derived from the public key.
For short messages, m
may be supplied directly as PlainTextType_Bytes
.
For longer messages, the hash h(z||m)
may be computed externally and supplied as PlainTextType_Hash
.
RSA
Public key
typedef struct {
M_Bignum e Exponent
M_Bignum n Modulus
} M_KeyType_RSAPublic_Data;
RSA public keys contain exponent and modulus only.
The exponent is usually simple, reducing the complexity of the modular exponentiation.
RSA keys generated by an nShield module have the public exponent 0x10001
by default.
Private key
typedef struct {
M_Bignum p
M_Bignum q
M_Bignum dmp1
M_Bignum dmq1
M_Bignum iqmp
M_Bignum e
} M_KeyType_RSAPrivate_Data;
-
dmp1
isD MOD
P -1 -
dmq1
isD MOD
Q -1 -
iqmp
isQ
-1MOD
P
RSA private keys, for which the exponent is usually large, contain additional information that enables the modular exponentiation to be optimized by using the Chinese Remainder Theorem.
Generation parameters
Generation parameters
typedef struct {
M_Word flags;
M_Word lenbits;
M_Bignum *given_e;
M_Word *nchecks;
} M_KeyType_RSAPrivate_GenParams;
-
The following
flags
are defined:-
KeyType_RSAPrivate_GenParams_flags_given_e_present
If this flag is set, the user can specify which public exponent is to be used. If this flag is not set, the public exponent will be set to
0x10001
or, for very short keys,0x11
. -
KeyType_RSAPrivate_GenParams_flags_nchecks_present
If this flag is set, the user can specify the number of Rabin-Miller checks that are to be done on the primes. The default for this number varies with key size to give a
2
-100 probability of error. -
KeyType_RSAPrivate_GenParams_flags_UseStrongPrimes
Setting this flag requests key generation in accordance with ANSI X9.31 requirements. Specifically:
-
the key length must be at least 1024 bits, and a multiple of 256 bits
-
primes
p
andq
are 'strong' - that isp+1
,p-1
,q+1
andq-1
each have at least one prime factor >2100 -
primes
p
andq
each pass 8 iterations of the Rabin-Miller test followed by the Lucas test -
p
andq
differ somewhere in their most significant 100 bits.
-
-
KeyType_RSAPrivate_GenParams_flags__allflags
-
-
*given_e
specifies the public exponent to be used. This must be an odd value greater than 1 and less than half the requested key length. -
*nchecks
specifies the number of Rabin-Miller checks to be performed.
Mechanisms
For RSAPublic and RSAPrivate keys, the following mechanisms are provided:
|
see note 1 |
|
see note 2 |
|
see note 2 |
|
see note 3 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
This mechanism has the following behavior:
-
Encrypt
-
accepts plain text of the type
Bignum
orBytes
-
for plaintext type
Bytes
pads and encrypts the message according to PKCS #1 -
for plaintext type
Bignum
encrypts the input directly -
returns a cipher text of the type
M_Mech_RSApPKCS1_Cipher
-
-
Decrypt
-
accepts cipher text of the appropriate type
M_Mech_RSApPKCS1_Cipher
-
decrypts the message and strips the padding
-
returns plain text in format
Bytes
-
-
Sign
-
accepts plain text of the type
Bignum
orBytes
-
for plaintext type
Bytes
pads and encrypts the message according to PKCS #1 -
for plaintext type
Bignum
signs the input directly -
returns a cipher text of the type
M_Mech_RSApPKCS1_Cipher
-
-
Verify
-
accepts plain text of the type
Bignum
orBytes
-
accepts cipher text of the type
M_Mech_RSApPKCS1_Cipher
, which is decrypted and compared to the appropriate hash of the plain text.
-
This mechanism does not hash the message before signing it. You should use the
Hash
command in order to produce a hash to pass to theSign
orVerify
command. For PKCS #1 compatible signatures, theObjectID
that identifies the hash algorithm should be placed before the hash value itself to form a plain text of the typeBytes
. Alternatively, you can useRSAhMD5pPKCS1
and similar mechanisms that hash the plaintext first.Although the RSApPKCS1
mechanism will accept a hash plain text for signature or verification, this operation will not result in a valid PKCS #1 signature. -
-
These mechanisms will
Sign
andVerify
only. They have the following behavior:-
Sign
accepts plain text of the typeBignum
,Bytes
or appropriate hash.-
for
Bignum
no padding is performed -
for
Bytes
,Sign
hashes this plain text with the selected hash function, adds the correctObjectID
, pads the result using PKCS #1 padding. -
the
hash
must be the correct size for the hash mechanism specified: adds the correctObjectID
, pads the hash using PKCS #1 padding, the resulting padded string is then encrypted.
-
-
Verify
accepts plain text of typeBytes
and cipher text of the typeM_Mech_RSApPKCS1_Cipher
, which is decrypted, has its padding stripped, and is then compared to the plain text.You must make sure that the message fits into a single command block. If the message is too large to fit into a single block, the server will use channel commands to pass the command, which will fail because channel commands do not support RSA. If you are not certain that the data will fit into a single command block, use separate
Hash
andSign
commands.
-
-
This mechanism performs encryption and decryption with OAEP padding. It implements the
RSAES-OAEP-ENCRYPT
andRSAES-OAEP-DECRYPT
primitives as given in PKCS #1 v2.0, using SHA-1 as the Hash option and MGF1-with-SHA1 as the MGF function.This is similar in concept to, but in practice totally incompatible with, the OAEP as used in SET. The input to the
Encrypt
function must be aBytes
type plain text with a length from0
to(modulus length in bytes minus 42)
bytes inclusive.Thus, a 512-bit modulus (of 64 bytes) will be able to encode up to 22 bytes of information.
This quantity is insufficient to make a direct blob. You must use at least a 528-bit modulus to make a direct blob. Unlike the SET OAEP mechanism, PKCS #1 OAEP preserves the length of the plain text block.
RSAES-OAEP defines an encoding parameters string,
p
. This string is a byte block that is used as extra padding. In order to pass encoding parameters to the Encrypt command, set thegiven_iv_present
flag, and enter the encoding parameters as the IV. In order to pass encoding parameters to theDecrypt
command, set the IV in theiv
member of thecipher
parameter. The IV is in the form of a byte blockp
, the length of which may be 0.
DeriveKey
DKTemplate
A DKTemplate
is a template key whose key data contains a marshalled ACL and application data.
DKTemplate
keys cannot be created with GenerateKey
because this would produce a random ACL.
You must Import
the key.
typedef struct {
M_ByteBlock appdata;
M_ByteBlock nested_acl;
} M_KeyType_DKTemplate_Data;
-
appdata
specifies application data for the new key. -
nested_acl
is the marshalled ACL for the new key. Use the functionNFastApp_MarshalACL()
in order to produce an ACL in the correct format.
Wrapped
A wrapped key contains encrypted key data as a byte block. A wrapped key has the same structure as a random key, but is a separate type.
You can generate a wrapped key by generating two random numbers and XORing them together to create a key.
If you randomly generate both halves of a DES or a triple DES key, you must use one of the mechanisms that sets the parity of the resultant key: DeriveMech_DESjoinXORsetParity
or DeriveMech_DES3joinXORsetParity
.
Alternatively, you can marshal keys, as described in Mechanisms.
Generation parameters
typedef struct {
M_Word flags;
M_Word length;
} M_KeyType_Wrapped_GenParams;
-
No
flags
are defined. -
length
specifies the length in bytes:-
8 bytes for a wrapped DES key
-
24 bytes for a wrapped Triple DES key
-
Derive Key Mechanisms
|
see note 1 |
|
see note 2 |
|
see note 1 |
|
see note 2 |
|
see note 1 |
|
see note 2 |
|
see note 2 |
|
see note 2 |
|
see note 2 |
|
see note 1 |
|
see note 2 |
|
see note 1 |
|
see note 2 |
|
see note 3 |
|
see note 3 |
|
see note 4 |
|
see note 4 |
|
see note 5 |
|
see note 5 |
|
see note 1 |
|
see note 2 |
|
|
|
see note 6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
see note 7 |
|
see note 8 |
-
These mechanisms take a base key of the specified type and a wrapping key of type
Random
to produce an output key of typeWrapped
. -
These mechanisms take a base key of type
Wrapped
and a wrapping key of typeRandom
to produce an output key of the specified type. -
The
EncryptMarshalled
andDecryptMarshalled
mechanisms are provided to allow export of keys from a module in FIPS 140 Level 3 mode and import into a module in the same mode.The
EncryptMarshalled
mechanism takes a template key, a base key of any marshallable type, and a wrapping key of any type capable of encrypting, and does the following:-
Marshals an
M_PlainText
structure that represents the base key to produce a byte string. -
Turns the byte string into
Bytes
plaintext, and encrypts it with the wrapping key to produce ciphertext. -
Marshals the ciphertext into a further byte string.
-
Creates a key of the type
Wrapped
that has the ACL given in the template key and contains the byte string from step c as data. That is, the wrapped data is a marshalled ciphertext which is an encryption of the marshalled key data.All marshalling is done in module-internal format (little-endian arrays of little-endian words).
Template
andWrapped
keys can be imported into the module even in FIPS 140 Level 3 mode. The import must be authorized by a certificate signed by the nShield Security Officer’s keyK
NSO.The
DecryptMarshalled
mechanism performs the complementary operation: it unmarshals and decrypts a ciphertext represented as aWrapped
key, then unmarshals the resulting plaintext to recover theM_PlainText
structure for the output key.An example of importing keys using the
DecryptMarshalled
mechanism:-
Generate an RSA key pair
Kpub
,Kpriv
.Kpub
must have export-as-plain permissions.Kpriv
must have aDeriveKey
action group that specifies a role ofWrapKey
and a mechanism ofDecryptMarshalled
. ExportKpub
. -
Marshall the key
Ki
to be imported. Pad the result according to PKCS #1 and encrypt it withKpub
(for example, using theModExp
command). -
Marshal the ciphertext: write
Mech_RSApPKCS1
as anM_Word (02 00 00 00)
, the length of the bignum, then the bytes in little-endian order. Import the resulting byteblock as a keyKw
of typeWrapped
. -
Create a template key
Kt
that contains the desired ACL for the key to be imported, and import it. -
Use
DeriveKey
withKt
as the template, theKw
as the base key, andKpriv
as the wrapper key.The resulting key is
Ki
imported with the correct ACL.
-
-
The
PKCS8Encrypt
andPKCS8Decrypt
mechanisms are provided to allow private key data for asymmetric algorithms to be imported and exported.This mechanism is not intended for secure transport of key data between nShield modules. It has a number of security weaknesses, not least poor protection of key integrity. It is provided only as an aid to interoperating with other systems when more secure methods are not available. The PKCS8Encrypt and
PKCS8Decrypt
mechanisms have the following structure:struct M_DeriveMech_PKCS8Encrypt_DKParams { M_IV iv; }; struct M_DeriveMech_PKCS8Decrypt_DKParams { M_IV iv; };
The
PKCS8Encrypt
mechanism takes a Base key of typeRSAPrivate
,DSAPrivate
,ECDSAPrivate
,ECDHPrivate
orDHPrivate
, and a Wrap key of any symmetric type capable of encrypting byte streams. The private key data is BER-encoded according to PKCS #8. (This process is also described in the PKCS #11 specification underWrapping/unwrapping private keys
.) The resulting byte block is encrypted, using the giveniv
, which includes a mechanism. The data of the ciphertext is converted into a key of typeWrapped
.The
PKCS8Decrypt
mechanism performs the opposite process: it takes aWrapped
key type as the Base key and a symmetric key as the Wrapping key. The data is decrypted using the giveniv
and mechanism, and then BER-decodes to give aRSAPrivate
,DSAPrivate
,ECDSAPrivate
orDHPrivate
output key.The following errors may indicate mechanism-specific problems:
-
TypeMismatch
: The ciphertext type for the given mechanism is not a simple byteblock, and so cannot be converted to or from a Wrapped key type. -
NotYetImplemented
: During encoding, this error indicates that the Base key is not of a type for which BER-encoding is supported. During decoding, this error indicates that an element has been encountered which is not used for the supported key types (for example, a negative integer value). This may indicate the data has been corrupted. -
UnknownParameter
: During decoding, this error indicates that a key type other than those supported, or an unknown 'version' integer, has been encountered. -
Malformed
: The BER-decoding has been unsuccessful, probably due to corrupted data, for example, because the data is too short, or because an illegal byte value has been encountered).
-
-
The
RawEncrypt
andRawDecrypt
mechanisms are provided to allow raw key data to be encrypted and decrypted using any key that accepts a cipher text as Bytes. Alternatively, forRawEncrypt
only, a signing or hashing mechanism can be provided instead of an encrypt one. In these cases, the raw key data is signed or hashed instead.This mechanism is not intended for secure transport of key data between nShield modules. It has a number of security weaknesses, not least poor protection of key integrity. It is provided only as an aid to interoperating with other systems when more secure methods are not available. These mechanisms have the following structure:
struct M_DeriveMech_RawEncrypt_DKParams { M_IV iv; }; struct M_DeriveMech_RawDecrypt_DKParams { M_IV iv; M_KeyType dst_type; };
The
RawEncrypt
mechanism processes the key as follows:-
It extracts the key data of the Base key as a byte block.
-
If an encryption mechanism is specified in the
IV
, the key data is encrypted using the Wrapping key,IV
and the mechanism specified in theIV
, which must be a valid mechanism for the given Wrapping Key. Mechanisms that do not perform padding cannot encrypt plain texts which are not multiples of the block length. For example,DESmECBpNONE
can encrypt only base keys that are a multiple of 8 bytes in length.
If a signing mechanism is specified in theIV
, the key data is signed using the Wrapping key,IV
and the mechanism specified in theIV
, which must be a valid mechanism for the given Wrapping Key.
If a hashing mechanism is specified in theIV
, the key data is hashed using the Wrapping key (if the mechanism requires one),IV
and the mechanism specified in theIV
, which must be a valid mechanism for the given Wrapping Key. HMAC mechanisms require a wrapping key and others do not. For more information see HMAC signatures. -
The resulting ciphertext, signature or
hash
is converted directly into a Wrapped key. No mechanism,IV
, or base key type information is saved with the Wrapped data. This data must be transported separately.
RawDecrypt
performs the reverse process.The type of the key to be created, and theIV
to be used when decrypting, are passed in thedst_type
andiv
fields, respectively.The following errors have specific meanings:
-
TypeMismatch
: The chosen Base key type is not a DES or simple ByteBlock key type (for example, an RSAPrivate key), so it cannot be converted to or from a byte block plaintext. Alternatively, the specified mechanism in theIV
does not use a byte block for its ciphertext (for example, it uses ciphertexts containing Bignums) so the ciphertext cannot be converted to or from Wrapped key data. -
InvalidData
: The data cannot be made into a key of the given type. For example, the decrypted data was too short or too long for the given destination key type, or the destination key type was a DES, DES2 or DES3 key and the decrypted data had parity errors. You can force the parity to be set correctly, by usingRawDecrypt
to produce a key of type Wrapped, and importing a Random key of the right length with all bytes zero. Then use theDESjoinXORsetParity
mechanisms on these two keys to produce a DES key with correct parity bits.
-
-
DeriveMech_PublicFromPrivate
constructs the corresponding public key given one private key of any type.
The following is a non-exhaustive list of common error returns specific to this key derivation mechanism:-
TypeMismatch
: given key is not a private key. -
InvalidParameter
: more than one key supplied.
-
-
The
DeriveMech_ECIESKeyWrap
mechanism takes a base key of the specified symmetric type and a wrapping key of typeECDHPublic
to produce an output key of typeWrapped
. -
The
DeriveMech_ECIESKeyUnwrap
mechanism takes a base key of typeciphertext
and a wrapping key of typeECDHPrivate
to produce an output key of typekeytype
.
Hash functions
Hash functions take an input of arbitrary length and return an output of fixed length.
The Hash
function supports the RIPEMD-160, SHA-1, SHA-256, SHA-384, SHA-512, Tiger, MD2, and MD5 mechanisms.
All the hashes that the module uses internally employ the SHA-1 algorithm.
SHA-1
SHA-1 is a hash function that has been approved by NIST. SHA-1 returns a 20-byte result.
The implementation of SHA-1, SHA-256, SHA-384 and SHA-512 in the nShield module has been validated by NIST as conforming to FIPS 18-2, certificate 255. |
Tiger
Tiger is a hash function designed by Ross Anderson and Eli Biham. It is designed to be efficient on 64-bit processors and to be no slower than MD5 on 32-bit processors.
RIPEMD 160
RIPEMD 160 is a hash function that was developed as part of the European Union’s RIPE project. RIPEMD 160 returns a 20-byte hash.
HAS160
HAS160 is a hash function designed for use with the KCDSA algorithm. (See KCDSA.) HAS160 returns a 20-byte hash.
If you wish to use the HAS160 hash function, you must order and enable it as part of the KISAAlgorithms feature, as described in the User Guide.
|
HMAC signatures
The sign
and verify
commands can create and verify MACs that have been created with the HMAC procedure and any supported hashing algorithm.
See RFC2104 for a description of HMAC.
The nShield implementations of HMAC SHA-1, HMAC SHA-224, HMAC SHA-256, HMAC SHA-384 and HMAC SHA-512 have been validated by NIST as conforming to FIPS 198, certificate 3. |
The following key types are defined:
-
KeyType_HMACMD2
-
KeyType_HMACMD5
-
KeyType_HMACSHA1
-
KeyType_HMACRIPEMD160
-
KeyType_HMACSHA224
-
KeyType_HMACSHA256
-
KeyType_HMACSHA384
-
KeyType_HMACSHA512
-
KeyType_HMACSHA3b224
-
KeyType_HMACSHA3b256
-
KeyType_HMACSHA3b384
-
KeyType_HMACSHA3b512
-
KeyType_HMACTiger
All these key types contain random data that is stored in byte blocks of variable length.
They use the key type Random
for their data and key generation parameters.
The following mechanisms are defined:
-
Mech_HMACMD2
-
Mech_HMACMD5
-
Mech_HMACSHA1
-
Mech_HMACRIPEMD160
-
Mech_HMACSHA224
-
Mech_HMACSHA256
-
Mech_HMACSHA384
-
Mech_HMACSHA512
-
Mech_HMACSHA3b224
-
Mech_HMACSHA3b256
-
Mech_HMACSHA3b384
-
Mech_HMACSHA3b512
-
Mech_HMACTiger
ACLs
An ACL is a list of actions that are permitted for this object. An ACL consists of a list of permission groups.
Each permission group is a list of actions combined with an optional set of limits, either numerical limits or time limits, and optionally the hash of the key needed to authorize these actions.
By creating multiple permission groups with different use limits
and certifiers
you create an ACL:
typedef struct {
int n_groups
M_PermissionGroup *groups;
} M_ACL;
-
n_groups
is the number of groups. -
*groups
This is a list of permission groups. Each permission group consists of the following items:-
optionally, the key hash of a key that must be used to certify all operations within this permission group. The given key must be used to produce a certificate that accompanies the request. This certificate can also be required to be fresh. If no key hash is given, this is a public permission group and defines operations available without a certificate.
-
0 or more
use limits
for this permission group. If a permission group has use limits, operations permitted by this group are only allowed if the use limits have not been exhausted. If a permission group has no use limits, these actions are always permitted.Each use limit specifies either an identifier for a counter or a time limit. If a permission group specifies both a counter and a time limit, the action will fail if either limit is exhausted. Performing any of the
actions
listed as action elements for this permission group decreases the count of the specified counter by 1 for eachaction
. -
one or more
action
elements. These specify the operations to which the use limits apply.typedef struct { M_Word flags; int n_limits; M_UseLimit *limits; int n_actions; M_Action *actions; M_KeyHash *certifier; M_KeyHashAndMech *certmech; M_ASCIIString *moduleserial; } M_PermissionGroup;
-
-
The following
flags
are defined:-
PermissionGroup_flags_certmech_present
Set this flag if actions in this group must be certified with a key that matches the given hash and mechanism. -
PermissionGroup_flags_certifier_present
Set this flag if actions in this group must be certified with a key that matches the given hash. If none of flagsPermissionGroup_flags_certifier_present
,PermissionGroup_flags_certmech_present
, orPermissionGroup_flags_NSOCertified
have been set, then this is a public permission group, and actions can be performed without a certificate.The PermissionGroup_flags_certifier_present
flag is included for backwards compatibility only. If you are creating a new ACL, usePermissionGroup_flags_certmech_present
. -
PermissionGroup_flags_FreshCerts
Set this flag if the certificate must be freshly produced. If this flag is not set, certificates may be reused indefinitely. -
PermissionGroup_flags_LogKeyUsage
Set this flag if Sign, Verify, Encrypt or Decrypt (and correspondingCmd_ChannelOpen
) actions in this group should be logged by the nShield Audit Logging capability.If Audit Logging is not enabled for the module attempting to use a key with PermissionGroup_flags_LogKeyUsage set the module returns Status_InvalidACL. -
PermissionGroup_flags_moduleserial_present
Set this flag if the actions in this group can only be performed on a specific module, whose serial number matches the given serial number. -
PermissionGroup_flags_NSOCertified
Set this flag if the actions in this group must be certified by the Security Officer’s keyK
NSO, whatever that is set to for this module at this time.
If you set more than one of PermissionGroup_flags_certifier_present
,PermissionGroup_flags_certmech_present
, orPermissionGroup_flags_NSOCertified
, the module returnsStatus_InvalidACL
. -
-
n_limits
is the number of limits. -
*limits
is a list of use limits, defined below. -
If more than one set of use limits is defined:
-
if the use limits are in the same permissions group, all counters and time limits must be valid, and all referenced counters are decreased by 1
-
if the use limits are in different permission groups, the module uses the first permission group that permits the action.
-
-
n_actions
is the number of actions. -
*actions
is the list of actions to which the use limits apply. -
*certifier
is either the hash of the key that is required to authorize the use of this ACL entry or a NULL pointer indicating that no further authorization is required.The certifier
field is included for backwards compatibility only. You are encouraged to use thecertmech
field. Thecertifier
field may be removed in future releases.
*certmech
: M_KeyHashAndMech
has the following structure:
typedef struct {
M_KeyHash hash;
M_PlainText mech;
} M_KeyHashAndMech;
-
hash
is the hash of the key that is required to authorize the use of this ACL entry or aNULL
pointer, indicating that no further authorization is required. -
mech
is the mechanism that is to be used to sign the certificate. You can specifyMech_Any
, in which case the ACL will behave exactly as if you had used the certifier field.
Signingkey certificates do not check the mechanism.
|
-
*moduleserial
is the serial number of the module on which the actions in this permission group must be performed. This must be the exact string returned by theNewEnquiry
command for the module.
Use limits
Use limits
typedef struct {
M_UseLim type;
union M_UseLim__Details details;
} M_UseLimit;
The following Uselim types
are defined:
-
UseLim_Global
-
UseLim_AuthOld
-
UseLim_Time
-
UseLim_NonVolatile
-
UseLim_Auth
The details
depend on the action type:
union M_UseLim__Details {
M_UseLim_Global_Details global;
M_UseLim_Time_Details time;
M_UseLim_NonVolatile_Details nonvolatile;
M_UseLim_Auth_Details auth;
};
A global
use limit has the following structure:
typedef struct {
M_LimitID id;
M_Word max;
} M_UseLim_Global_Details;
-
id
is a unique 20-byte identifier for the counter for this use limit. When a counter is created, it is set to 0. Any time a user performs an action that requires a use limit, the module compares the value of the counter to the limit in the ACL. If the counter value is less than the limit, the action is permitted and the counter’s value is increased by 1. Otherwise, the action is prohibited.Global and per-authorization counters are stored separately on the module. Therefore, a global use limit may have the same hash as a per-authorization use limit, and these hashes will refer to separate counters.
Global counters are stored separately for each key, and per-authorization counters are stored separately for each logical token.
This means that the two matching
LimitID
s will only refer to the same counter if either:-
they are both in Global use limits in the same ACL
-
they are both in Auth use limits for keys loaded using the same logical token.
-
-
max
is the absolute maximum number of times that the actions specified in this permission group can be performed. Global limit counters are created when a key object is imported, generated or derived using theDeriveKey
command. They are destroyed when that object is destroyed. They are never reset.When a key is duplicated (using the
Duplicate
command), or loaded with theLoadBlob
command, all permission groups containing Global use limits are removed from its ACL. This is to ensure that actions subject to Global use limits can only be performed when the key was originally imported, generated or derived.
A time
limit has the following structure:
typedef struct {
M_Word seconds;
} M_UseLim_Time_Details;
-
seconds
is a per authorization limit that sets the length of time, in seconds, during which the actions specified in this permission group can be performed before the key needs to be reauthorized. Time limits only apply to keys protected by a logical token. The time is taken from the point at which the token was recreated.If you specify more than one time limit within an ACL, the shortest time limit will apply. If you specify a time limit and a use count limit, both must be valid in order for an action to be authorized.
If you apply a time limit to a key that is not loaded from a logical token protected blob, all permission groups with time limits will be unavailable and attempting to use these limits will return Status_AccessDenied
.
nonvolatile
limits are only available on nShield modules.
The use limit is stored in a NVRAM file.
A non-volatile limit has the following structure:
struct M_UseLim_NonVolatile_Details {
M_UseLim_NonVolatile_Details_flags flags;
M_FileID file;
M_NVMemRange range;
M_Word maxlo;
M_Word maxhi;
M_Word prefetch;
};
-
No
flags
are defined. -
file
is thefileId
of the NVRAM file containing the use limit. -
range
is the memory range within the file for this limit. -
maxlo
andmaxhi
are the values for the limit stored as two 32-bit words. -
prefetch
: In order to reduce the number of NVRAM write cycles, you can specify a number of limits to prefetch. The module will update the limit by this number and decrement an in-memory counter for each use. When the counter reaches zero the NVRAM value will again update the NVRAM.
A per-authorization use limit (auth
) has the following structure:
typedef struct {
M_LimitID id;
M_Word max;
} M_UseLim_Auth_Details;
-
id
is a unique 20-byte identifier for the counter for this use limit. When a counter is created, it is set to 0. Any time a user performs an action that requires a use limit, the module compares the value of the counter to the limit in the ACL. If the counter value is less than the limit, the action is permitted and the counter’s value is increased by 1. Otherwise, the action is prohibited.Global and per-authorization counters are stored separately on the module. Therefore, a global use limit may have the same hash as a per-authorization use limit, and these hashes will refer to separate counters.
Global counters are stored separately for each key, and per-authorization counters are stored separately for each logical token.
This means that the two matching
LimitID
s will only refer to the same counter if either:-
they are both in Global use limits in the same ACL
-
they are both in Auth use limits for keys loaded using the same logical token.
-
-
max
is the number of times that the actions specified in this permission group can be performed before the logical token needs to be reauthorized.Per-authorization limit counters are created when a key is loaded from a token blob, unless a counter with the same
LimitID
already exists for this token (in which case, the existing counter is used). This can mean that all the per-authorization use limits for a key have been exhausted already when it is loaded. In such a case, you must reload the logical token.Keys that have been loaded from blobs under different tokens have separate counters even if they have the same
LimitID
.Firmware versions 2.12.0 or later contain logic to prevent an attacker loading the same logical token twice and thereby gaining two separate sets of counters. It works as follows:
Every time a smart card is inserted, all the logical token shares on it are marked
available
. When a share is loaded for use in a logical token, it is markedused
, unless theReadShare
command sets theUseLimitsUnwanted
flag.If any share is loaded - locally or remotely - when it is already marked
used
, the logical token is markedUseLimitsUnavailable
. No per-authorization use limits are allowed for any keys loaded using this second logical token. This ensures only one set of use limits counters can be created for each physical insertion of a token.The mechanism for controlling per-authorization limits changed in firmware 2.12.0 to prevent a possible attack which may have resulted in the limit being circumvented. On new firmware ACLs using UseLim_Auth
andUseLimAuth_Old
both use the new mechanism. However, thenfkmverify
program will note use of the old style limit as this will use the old behavior on old firmware.Although it is possible to load a logical token on several modules, using remote slots, only one copy of the logical token can be allocated the per-authorization use limits.
Actions
typedef struct {
M_Act type;
union M_Act__Details details;
} M_Action;
type
must be one of the actions listed below:
-
Act_NoAction=
-
Act_OpPermissions=
- see OpPermissions -
Act_MakeBlob=
- see MakeBlob -
Act_MakeArchiveBlob=
- see MakeArchiveBlob -
Act_NSOPermissions=
- see NSO -
Act_DeriveKey=
- see DeriveKey and DeriveKeyEx -
Act_DeriveKeyEx=
- see DeriveKey and DeriveKeyEx -
Act_NVMemOpPerms=
- see NVRAM -
Act_FeatureEnable=
- see NVRAM -
Act_NVMemUseLimit=
-
Act_SendShare=
- see SendShare -
Act_ReadShare=
- see ReadShare -
Act_StaticFeatureEnable=
-
Act_UserAction=
- see UserAction -
Act_FileCopy=
- see FileCopy
details
depend on the chosen action type:
union M_Act__Details {
M_Act_FeatureEnable_Details featureenable;
M_Act_DeriveKey_Details derivekey;
M_Act_DeriveKeyEx_Details derivekeyex;
M_Act_SendShare_Details sendshare;
M_Act_NVMemUseLimit_Details nvmemuselimit;
M_Act_NVMemOpPerms_Details nvmemopperms;
M_Act_StaticFeatureEnable_Details staticfeatureenable;
M_Act_NSOPermissions_Details nsopermissions;
M_Act_OpPermissions_Details oppermissions;
M_Act_FileCopy_Details filecopy;
M_Act_MakeArchiveBlob_Details makearchiveblob;
M_Act_MakeBlob_Details makeblob;
M_Act_UserAction_Details useraction;
M_Act_ReadShare_Details readshare;
};
Action types
OpPermissions
typedef struct {
M_Word perms;
} M_Act_OpPermissions_Details;
The following flags (perms
) are defined:
-
Act_OpPermissions_Details_perms_DuplicateHandle
: Setting this flag grants permission to create a copy of the key with the same ACL. Duplicating a key does not enable you to perform any further actions, because both copies use the same use counters. -
Act_OpPermissions_Details_perms_UseAsCertificate
: Setting this flag allows use of theKeyID
to authorize a command that requires a certificate. -
Act_OpPermissions_Details_perms_ExportAsPlain
-
Act_OpPermissions_Details_perms_GetAppData
-
Act_OpPermissions_Details_perms_SetAppData
-
Act_OpPermissions_Details_perms_ReduceACL
-
Act_OpPermissions_Details_perms_ExpandACL
-
Act_OpPermissions_Details_perms_Encrypt
-
Act_OpPermissions_Details_perms_Decrypt
-
Act_OpPermissions_Details_perms_Verify
-
Act_OpPermissions_Details_perms_UseAsBlobKey
: Setting this flag allows use of this key either in theMakeBlob
command to encrypt a key blob or in theLoadBlob
command to decrypt a key from a blob. -
Act_OpPermissions_Details_perms_UseAsKM
: OnlyDES3
keys can be used for module keys,K
M. -
Act_OpPermissions_Details_perms_UseAsLoaderKey
: When this flag is set, an encryption key is only permitted to perform decryption when loading an SEE machine or SEE World onto the module. -
Act_OpPermissions_Details_perms_Sign
-
Act_OpPermissions_Details_perms_GetACL
-
Act_OpPermissions_Details_perms_SignModuleCert
-
Act_OpPermissions_Details_perms__allflags
MakeBlob
This action type allows the creation of module key, or token, key blobs with the given key (see also MakeArchiveBlob
).
typedef struct {
M_Word flags;
M_KMHash *kmhash;
M_TokenHash *kthash;
M_TokenParams *ktparams;
M_MakeBlobFilePerms *blobfile;
} M_Act_MakeBlob_Details;
-
The following
flags
are defined:-
Act_MakeBlob_Details_flags_AllowKmOnly
If this flag is set, you can create blobs directly under a module key or under a logical token. If this flag is not set, you must use a logical token.
-
Act_MakeBlob_Details_flags_AllowNonKm0
If this flag is set, you can create blobs for this key using module keys, or logical tokens based on module keys, except for the internally generated
K
M0. If this flag is not set, you must useK
M0 or logical tokens based onK
M0. -
Act_MakeBlob_Details_flags_kmhash_present
Set this flag in order to restrict the blobs that can be made with this key to blobs that use the module key whose hash is specified or to logical tokens that are based on this module key. If this flag is not set, any module key may be used. If this hash is not
K
M0, you must set theAllowNonKM0
flag. -
Act_MakeBlob_Details_flags_kthash_present
Set this flag in order to restrict the blobs that can be made with this key to blobs that use the token whose hash is specified. If this flag is not set, any token may be used. If this token is not based on
K
M0, you must set theAllowNonKM0
flag. -
Act_MakeBlob_Details_flags_ktparams_present
Set this flag in order to restrict the blobs that can be made with this key to blobs that use a token with either the given parameters or with more restrictive ones. If this flag is not set, any token can be used.
-
Act_MakeBlob_Details_flags_AllowNullKmToken
If this flag is set, the user can create token blobs for this key with a token protected by the null module key.
-
Act_MakeBlob_Details_flags_blobfile_present
If this flag is set the blob will be stored in the NVRAM or smart card file specified - it will not be returned to the host.
-
Act_MakeBlob_Details_flags__allflags
The key blob must meet the requirements of all the flags. -
-
*kmhash
- seeAct_MakeBlob_Details_flags_kmhash_present
above. -
*kthash
- seeAct_MakeBlob_Details_flags_kthash_present
above. -
*ktparams
- seeAct_MakeBlob_Details_flags_ktparams_present
above. -
*blobfile
The following structure specifies the NVRAM or smart card files to which you want to restrict writing the blob.
struct M_MakeBlobFilePerms { M_MakeBlobFilePerms_flags flags; M_PhysToken *devs; M_KeyHash *aclhash; };
-
The following
flags
are defined:-
MakeBlobFilePerms_flags_devs_present
If set, the blob may only be stored in the storage devices specified by the
M_FileDeviceFlags
word. -
MakeBlobFilePerms_flags_aclhash_present
Set this flag if the structure contains a
M_KeyHash
.
-
-
*devs
is the device on which to store the blob. -
*aclhash
is the hash of a Template Key defining the ACL to use for the file storing the key. The key must be provided when making the blob.
If you want to restrict the making of blobs to a set of module keys, or to a set of tokens, then you must include a
MakeBlob
entry for each module or token hash. -
MakeArchiveBlob
This action type allows the creation of direct and indirect archive key blobs with the given key.
typedef struct {
M_Word flags;
M_PlainText mech;
M_KMHash *kahash;
M_MakeBlobFilePerms *blobfile;
} M_Act_MakeArchiveBlob_Details;
-
The following
flags
are defined:-
Act_MakeArchiveBlob_Details_flags_kahash_present
If this flag is set, you can make an archive key blob for this key with the key whose hash is specified. If this flag is not set, any archive key may be used.
Including an Act_MakeArchiveBlob
entry withoutkahash_present
in an open permission group creates a security loophole. -
Act_MakeArchiveBlob_Details_flags_blobfile_present
If this flag is set the blob will be stored in the NVRAM or smart card file specified - it will not be returned to the host.
-
-
mech
For making direct archive blobs, this must be
Mech_DES3mCBCi64pPKCS5
orMech_Any
; for indirect blobs this specifies the mechanism which must be used to encrypt the session key. If set toMech_Any
, any mechanism appropriate for the type of the archiving key is allowed. See Mechanisms. -
*kahash
is the key hash. -
*blobfile
— see MakeBlob
NSO
This action type is used only in certificates that approve critical functions that have been defined in the SetKNSO
command.
It should not be used in an ACL for a key.
typedef struct {
M_NSOPerms perms;
} M_Act_NSOPermissions_Details;
M_NSOPerms
has the following structure:
typedef struct {
M_Word ops;
} M_NSOPerms;
The following flags (ops
) are defined.
These are identical to those used in the SetNSOPerms
command.
-
NSOPerms_ops_LoadLogicalToken
-
NSOPerms_ops_ReadFile
-
NSOPerms_ops_WriteShare
-
NSOPerms_ops_WriteFile
-
NSOPerms_ops_EraseShare
-
NSOPerms_ops_EraseFile
-
NSOPerms_ops_FormatToken
-
NSOPerms_ops_SetKM
-
NSOPerms_ops_RemoveKM
-
NSOPerms_ops_GenerateLogToken
-
NSOPerms_ops_ChangeSharePIN
-
NSOPerms_ops_OriginateKey
-
NSOPerms_ops_NVMemAlloc
-
NSOPerms_ops_NVMemFree
-
NSOPerms_ops_GetRTC
-
NSOPerms_ops_SetRTC
-
NSOPerms_ops_DebugSEEWorld
-
NSOPerms_ops_SendShare
-
NSOPerms_ops_ForeignTokenOpen
-
NSOPerms_ops__allflags
NVRAM
This action type allows operations to be performed upon files that have been stored in the nonvolatile memory or on a smart card or soft token.
struct M_Act_NVMemOpPerms_Details {
M_Act_NVMemOpPerms_Details_perms perms;
M_NVMemRange *subrange;
M_NVMemRange *exactrange;
M_Word *incdeclimit;
};
-
The following operations (
perms
) are defined.-
Act_NVMemOpPerms_Details_perms_Read
-
Act_NVMemOpPerms_Details_perms_Write
-
Act_NVMemOpPerms_Details_perms_Incr
-
Act_NVMemOpPerms_Details_perms_Decr
-
Act_NVMemOpPerms_Details_perms_BitSet
-
Act_NVMemOpPerms_Details_perms_BitClear
-
Act_NVMemOpPerms_Details_perms_Free
-
Act_NVMemOpPerms_Details_perms_subrange_present
-
Act_NVMemOpPerms_Details_perms_exactrange_present
-
Act_NVMemOpPerms_Details_perms_incdeclimit_present
-
Act_NVMemOpPerms_Details_perms_GetACL
-
Act_NVMemOpPerms_Details_perms_LoadBlob
This permission allows the contents to be used as a blob by the
Loadblob
command. -
Act_NVMemOpPerms_Details_perms_Resize
-
-
*subrange
This specifies the subrange to which this operation can be applied; the operation can apply to any part of the specified range in the ACL.
-
*exactrange
This is a subrange to which this operation can be applied only if the range exactly matches the specified range in the ACL.
-
*incdeclimit
This is the maximum amount that this range can be increased or decreased in one operation.
ReadShare
This action type enables a logical token share to be read normally using the ReadShare
command.
typedef struct {
M_ReadShareDetails rsd;
} M_Act_ReadShare_Details;
typedef struct {
M_ReadShareDetails_flags flags; No flags are defined
} M_ReadShareDetails;
SendShare
This action type enables a logical token share to be read remotely and sent over an impath.
typedef struct {
M_Act_SendShare_Details_flags flags;
M_RemoteModule *rm;
M_ReadShareDetails *rsd;
} M_Act_SendShare_Details;
-
The following
flags
are currently defined:-
Act_SendShare_Details_flags_rm_present
This flag is set if the action contains a
RemoteModule
structure. -
Act_SendShare_Details_flags_rsd_present
This flag is set if the action contains a
ReadShareDetails
structure.
-
-
*rm
The impath over which the share data is to be sent must match this
RemoteModule
structure. -
*rsd
— see ReadShare
FileCopy
This action permits files stored on a smart card, soft token or in NVRAM to be copied to another location. The action specifies which location the file can be copied to and from.
struct M_Act_FileCopy_Details {
M_Act_FileCopy_Details_flags flags;
M_PhysToken to;
M_PhysToken from;
};
The following flag
is defined: Act_FileCopy_Details_flags_ChangeName
.
If set the new file may have a different FileID
from the original file.
UserAction
This action does not permit any operations.
Instead it can be checked by the CheckUserAction
command.
This enables applications to make use of all modules ACl checking features - including use limits, time limits, certifiers and so on - to restrict actions in their own code.
struct M_Act_UserAction_Details {
M_UserActionInfo allow;
};
DeriveKey and DeriveKeyEx
These action types enable the key to be used in the DeriveKey
command.
They allow the key to be used in a single specific role.
If you want to create a key that can be used in more than one role, you must include a separate action entry for each role.
If the Cmd_DeriveKey_Args_flags_WorldHashMech
flag has been set in the DeriveKey
command, then the DeriveKeyEx
action should be used.
typedef struct {
M_Word flags;
M_DeriveRole role;
M_DeriveMech mech;
int n_otherkeys;
M_KeyRoleID *otherkeys;
M_DKMechParams *params;
} M_Act_DeriveKey_Details;
typedef struct {
M_Act_DeriveKeyEx_Details_flags flags;
M_DeriveRole role;
M_DeriveMech mech;
int n_otherkeys;
M_vec_KeyRoleIDEx otherkeys;
M_DKMechParams *params;
} M_Act_DeriveKeyEx_Details;
-
The following
flags
are defined:-
Act_DeriveKey_Details_flags_params_present
-
Act_DeriveKeyEx_Details_flags_params_present
-
-
role
can be one of the following:-
DeriveRole_TemplateKey
(template) -
DeriveRole_BaseKey
(base key) -
DeriveRole_WrapKey
(wrapping key)
-
-
mech
— see Mechanisms. -
n_otherkeys
- the number of keys in theotherkeys
table -
*otherkeys
The following keys can be used in the other roles of the DeriveKey command:
typedef struct { M_DeriveRole role; M_KeyHash hash; } M_KeyRoleID;
typedef struct { M_DeriveRole role; M_KeyHashEx hash; } M_KeyRoleIDEx;
-
role
You can define keys for any or all of the roles. You can specify one or more keys for each role. If you do not specify a key for a particular role, then any key can be used in that role.
-
hash
is either SHA-1 or a stronger hash determined by theCmd_DeriveKey_Args_flags_WorldHashMech
, which can be obtained via theGetKeyInfoEx
command.
-
-
*params
The mechanism parameters to use for the
DeriveKey
operation.struct M_DKMechParams { M_DeriveMech mech; union M_DeriveMech__DKParams params; };
-
mech
The mechanism to use. The module will not permit you to set a
M_DKMechParams
with a mechanism that is different to that previously defined in the ACL. If you attempt this the module returnsStatus_InvalidACL
. -
params
The derive key mechanism parameters— see Derive Key Mechanisms.
The module applies the following rules to determine which derive key operations are permitted:
-
If any of the requested or allowed
DeriveMech
values mismatch, the operation is never allowed. -
If the allowed
DKMechParams
are not present, any requested parameters are allowed. -
If the mechanism has an empty
DKParams
, the operation is allowed -
For other mechanisms, this comparison is not at present defined. The module will return
NotYetImplemented
for attempts to set, in a key’s ACL,DKMechParams
with mechanisms for which this is the case.
-
Using DeriveKey — an example
The following example shows how to use the DeriveKey
command to split a DES key into two random halves and then recombine these halves to recreate the original key.
The following diagram illustrates this process:
First, import the two template keys.
A template key contains an ACL and an Appdata
file that can be applied to the results of the DeriveKey
operation.
By importing these elements first, their key hashes can be determined, and these hashes can be referenced in the ACLs for the remaining keys.
This ensures that the two derived keys will have the correct ACL.
Next, create the wrapping key.
Determine its hash and then that of the base key.
After all the input keys have been have created, use the DeriveKey
command to combine the base key and the wrapping key.
Finally, unwrap the wrapped key. Check that the new DES key has the same hash, and therefore the same data, as the original. Also check that the new DES key has correctly inherited the ACL and application data from the template key.
-
Use the
Import
command with the following parameters to import a template key for an ACL that allows the use ofDeriveKey
with this key as the base key, any mechanism, and any other keys:module
1
type
DKTemplate
appdata
02020202
nested_acl
01000000 00000000 00000000 02000000 01000000 6c200000 05000000 00000000 01000000 00000000 00000000
ACL
n_groups
1
groups[ 0]
flags
0x0
n_limits
0
n_actions
1
actions[ 0]
type
DeriveKey
flags
0x0
role
TemplateKey
mech
Any
n_otherkeys
0
appdata
0
Create the
nested_acl
by using theNFastApp_MarshalACL()
command.Such use of the
Import
command will returnidka= IDKA 0010
-
Get this key’s hash by using the
GetKeyInfo
command with the following parameters:flags; 0x0 key; IDKA 0010
This command returns
type; DKTemplate hash; HKA 0010
-
Use the
Import
command with the following parameters to import a template key for an ACL that containsoppermissions
as follows:-
ExportAsPlain GetAppData Encrypt Decrypt Verify Sign GetACL
module
1
type
DKTemplate
appdata
01010101
nested_acl
01000000 00000000 00000000 01000000 01000000 8c330000
ACL
n_groups
1
groups[ 0]
flags
0x0
n_limits
0
n_actions
1
actions[ 0]
type
DeriveKey
flags
0x0
role
TemplateKey
mech
Any
n_otherkeys
0
appdata
0
Such use of the
Import
command will return:key IDKA 0011
In order to create a
nested_acl
in C, use theNFastApp_MarshalACL()
command.In order to create a nested ACL in Java, use
the marshall()
method from theM_ACL
class.The following Java fragment demonstrates the use of this method:
... M_ACL acl; MarshallContext tempMctx; M_ByteBlock bb; M_KeyType_Data_Template data; acl = yourACL; tempMctx = new MarshallContext(); acl.marshall(tempMctx); bb = new M_ByteBlock (tempMctx.getBytes()); data = new M_KeyType_Data_Template(); data.nested_acl = bb; ...
-
-
Get this key’s hash by using the
GetKeyInfo
command with the following parameters:key IDKA 0011
This command returns:
type DKTemplate hash HKA 0011
-
Make a wrapping key by using the
GenerateKey
command:-
When wrapping, insist on using template HKA 0010
-
When unwrapping, insist on using template HKA 0011.
flags
0x0
module
1
type
Random
lenbytes
8
ACL
n_groups
1
groups[ 0]
flags
0x0
n_limits
0
n_actions
3
actions[ 0]
type
OpPermissions
perms
DuplicateHandle ExportAsPlain ReduceACL GetACL
actions[ 1]
type
DeriveKey
flags
0x0
role
WrapKey
mech
DESsplitXOR
n_otherkeys
1
role
TemplateKey
hash
HKA 0010
actions[ 2]
type
DeriveKey
flags
0x0
role
WrapKey
mech
DESjoinXOR
n_otherkeys
1
role
TemplateKey
hash
HKA 0011
Such use of the
GenerateKey
command returns:key IDKA 0012
-
-
Get this key’s hash by using the
GetKeyInfo
command:key IDKA 0012
This command returns:
type Random hash HKA 0012
-
Use the
GenerateKey
command with the following parameters to generate a DES key that can only be wrapped using:-
The
DESsplitXOR
mechanism -
HKA 0012 as the wrapping key
module
1
type
DES
n_groups
1
groups[ 0]
flags
0x0
n_limits
0
n_actions
2
actions[ 0]
type
OpPermissions
perms
ReduceACL GetACL
actions[ 1]
type
DeriveKey
flags
0x0
role
BaseKey
mech
DESsplitXOR
n_otherkeys
1
role
WrapKey
hash
HKA 0012
This returns:
key IDKA 0013
-
-
Get this key’s hash by using the
GetKeyInfo
command with the following parameters:key IDKA 0013
This command returns:
type DES hash HKA 0013
-
The DES key can now be combined with the random key to produce a second random key by using the
DeriveKey
command with the following parameters:flags
0x0
mech
DESsplitXOR
n_keys
3
keys[ 0]
IDKA 0010
keys[ 1]
IDKA 0013
keys[ 2]
IDKA 0012
This command returns:
key IDKA 0014
At this point, this process has produced:
-
A
DES
key IDKA 0013 -
Two random keys: IDKA 0012 and IDKA 0014
The two random keys can be combined to recreate the key data in the DES key. This can be demonstrated by combining the keys that use the DeriveKey
command and then using the GetKeyInfo to check that the hash of the new key matches the hash of the DES key that was determined in Step 8. -
-
Use the
DeriveKey
command with the following parameters to combine the keys:flags
0x0
mech
DESjoinXOR
n_keys
3
keys[ 0]
IDKA 0011
keys[ 1]
IDKA 0014
keys[ 2]
IDKA 0012
This command returns:
key IDKA 0015
This is a new KeyID
because this is a new instance of the key. This instance of the key has taken itsappdata
andACL
from the template key that was created earlier:IDKA 0011
-
Get the hash of this new key by using the
GetKeyInfo
command with the following parameters:key IDKA 0015
This command returns:
type DES hash HKA 0013
This is the same hash as before, which proves that the key has been combined correctly -
Check that the new key has inherited the application data from the template key by using the
GetAppData
command with the following parameters:key IDKA 0015
This command returns:
appdata 01010101
This is the application data that was provided by the template key.
-
Check that the new key has inherited the ACL from the nested ACL in the template key by using the
GetACL
command with the following parameters:key IDKA 0015
This command returns
acl.n_groups
1
groups[ 0]
flags
none 0x00000000
n_limits
0
n_actions
1
actions[ 0]
type
OpPermissions
perms
ExportAsPlain GetAppData Encrypt Decrypt Verify Sign GetACL
Certificates
The nShield module uses certificates to enable a given user to authorize another user to perform an action.
A certificate is a signed message. The key that is used to sign the certificate must match the key hash in the ACL it is authorizing. The message can contain an ACL; this ACL can be used to restrict the operation to be approved by the certificate, or it can be used to require a further certificate.
Certificates can be either fresh or reusable.
A fresh certificate includes a challenge value.
This is a random number that was generated previously by the module with the GetChallenge
command.
The module remembers a maximum of 126 challenges. These challenges automatically expire after 30 seconds or on redemption. Expired challenges are removed from the modules memory.
If the module memory contains more than 40 challenges, it delays the issuance of new challenges.
This means that with 40 or fewer challenges outstanding, it issues new challenges instantly.
With more than 40 challenges outstanding, you get a successful response after a two-second delay.
If the module memory is full, it fails after a delay of four seconds unless an existing outstanding challenge expires or is redeemed during the delay period.
In this situation, if an outstanding challenge expires or is redeemed during the delay, you get a successful response.
These delays apply to each Cmd_GetChallenge
independently.
When a user presents a fresh certificate, the module deletes the matching challenge from the list. If the same certificate is presented a second time, it will be rejected.
The list of challenges is cleared whenever the unit is reset.
Therefore, a fresh certificate:
-
can only be used once
-
must be used on the module that generated the challenge
-
may become invalid if left too long before it is used
If you submit a certificate containing a challenge that is not on the module’s list of current challenges, the server returns the status Status_UnknownChallenge
.
A reusable certificate does not contain a challenge and can be used as often as is required. It can also be used on any module.
An ACL can specify that the required certificate must be fresh. If you present a reusable certificate when the ACL requires a fresh certificate, the certificate will be rejected.
If you possess the required key, you can always create a fresh certificate.
However, this requires a certain amount of processing, both on the module and on the host.
In order to prevent unnecessary load, you can authorize a command by presenting a certificate that contains the required key’s KeyID
.
In order for this certificate to be valid, you must have loaded the key yourself.
You cannot pass the KeyID
to another user.
In order to authorize another user, you must create a properly signed certificate.
Code executing in the SEE can be signed by one or more keys by using the signature tools provided with the CodeSafe Developer Kit
.
By presenting a certificate of the type CertType_SEECert
, code signed in this way can perform any operation for which the signing key has permission.
Using a certificate to authorize an action
If you are given a certificate, you must include it with the command it authorizes, after all the arguments for that command.
For situations in which you are presenting a single certificate:
-
it must not require further authorization
-
the hash of the key that signed the certificate must match the hash that is specified in the ACL
For situations in which you need to present a chain of certificates, the first certificate must not require any further authorization. For every certificate in the chain, the module checks to see that the hash of the signing key matches the hash given in the certifier field of the ACL that is included in the next certificate or, if this is the last certificate in the chain, the certifier field of the ACL for the key being authorized. The ACL in each certificate in the chain must permit the operation to be performed.
If a certificate, or any certificate in a certificate chain, does not authorize the requested action, the module will return the status Status_AccessDenied
.
Generating a certificate to authorize another operation
It is the responsibility of the cryptographic application to build certificates.
This process is assisted by the NFast_BuildCmdCert()
function that is provided in the generic stub library.
Structure
typedef struct {
M_KeyHash keyhash;
M_CertType type;
union M_CertType__CertBody body;
} M_Certificate;
-
keyhash
is the hash of the key that is used to sign the certificate. This hash must match the hash that is specified in the key’s ACL or in the previous certificate in the chain. -
The following
type
values are defined:-
CertType_Invalid
-
CertType_SigningKey
-
CertType_SingleCert
-
CertType_SEECert
-
-
The certificate body (
body
) has one of the following formats:union M_CertType__CertBody { M_CertType_SigningKey_CertBody signingkey; M_CertType_SingleCert_CertBody singlecert; };
-
A
signingkey
has the following body:typedef struct { M_KeyID key; } M_CertType_SigningKey_CertBody;
-
Where:
-
key
is theKeyID
of the key that must be loaded in order to authorize this command. The key must have the following properties: -
the hash of the key must match the hash that was given in the ACL
-
the key must have
UseAsCertificate
permission set in its ACL in an open group.
-
-
A
singlecert
certificate has the following body:typedef struct { M_PlainText pubkeydata; M_CipherText signature; M_ByteBlock certsignmsg; } M_CertType_SingleCert_CertBody;
-
signature
is thecertsignmsg
, which is signed with the private key that corresponds topubkeydata
.
-
-
A
certsignmsg
has the following structure, which must be marshalled into a byte block:typedef struct { M_MagicValue header; M_Word flags; int n_hks; M_KeyHash *hks; M_Nonce *nonce; M_ACL *acl; M_MagicValue footer; } M_CertSignMessage;
-
header
This must be set to the value
MagicValue_CertMsgHeader
, defined inmessages-ags-dh.h
. -
flags
The following flags are defined:
-
CertSignMessage_flags_nonce_present
-
CertSignMessage_flags_acl_present
-
CertSignMessage_flags_do_not_cache
-
-
n_hks
and*hks
This table can be used to restrict the keys to which this certificate applies. If there are entries in this table, then the hash of the key object used—or, for an NSO certificate, the hash of the module key used—must also be in this table. If the table is empty (
n_hks = 0
), then the certificate can be used to authorize any operations on a key with a matching ACL. -
*nonce
This is a nonce returned by the
GetChallenge
command. -
*acl
Optionally, this is a valid ACL that authorizes the action to be performed. If this ACL contains a
certmech
or acertifier
field in a permission group, then a valid certificate signed by the key whose hash is in the permission group must precede this certificate in the chain. -
footer
This must be set to the value
MagicValue_CertMsgFooter
, defined inmessages-ags-dh.h
.
The certsgnmsg
block should be passed to a suitable signature algorithm.
For RSA signature keys, use a mechanism that hashes the block first (for example, RSAhSHA1pPKCS1
).
The module checks all of the above and returns:
-
Status_BadCertKeyHash
if the verification key does not match the given hash -
Status_VerifyFailed
if the signature cannot be verified with the given key -
Status_UnknownChallenge
if the nonce was not one that the module had issued recently -
Status_AccessDenied
if the ACL still does not permit your request for some other reason.
The certificate type CertType_SEECert
, however, has an empty CertBody
.
In order to use certificates of this type:
-
Specify in the
M_Certificate
structure the hash of the signing key that was used to sign the SEE World data that authorized the action. -
The access control system checks to ensure that the SEE World data was, in fact, signed by the specified key.
-
If so, the certificate is accepted much as a
signingkey
certificate would be. However, because asigningkey
certificate is always treated as fresh but an SEE certificate is not, the flagPermissionGroup_flags_FreshCerts
must not be set in the next ACL in the stack.
Thus, code executing within the SEE can authorize itself to perform an action requiring authorization from a key that signed the code.
It can do this by creating an M_Certificate
, setting its key hash appropriately, and setting its type to SEECert
.