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).

devref 1 1

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

Mech_RSApPKCS1OAEP, Mech_RSApPKCS1OAEPhSHA224, Mech_RSApPKCS1OAEPhSHA256, Mech_RSApPKCS1OAEPhSHA384 or Mech_RSApPKCS1OAEPhSHA512 chosen based on size of key.

RSAPrivate

Mech_RSAhSHA1pPSS, Mech_RSAhSHA224pPSS, Mech_RSAhSHA256pPSS, Mech_RSAhSHA384pPSS or Mech_RSAhSHA512pPSS chosen based on size of key.

DHPublic

Mech_ElGamal

DSAPrivate

Mech_DSA, Mech_DSAhSHA224, Mech_DSAhSHA256, Mech_DSAhSHA384, or Mech_DSAhSHA512 chosen based on size of key.

ECDSAPrivate

Mech_ECDSA, Mech_ECDSAhSHA224, Mech_ECDSAhSHA256, Mech_ECDSAhSHA384, or Mech_ECDSAhSHA512 chosen based on size of key.

DES (not available in FIPS 140-2 Level 3 operational mode)

Mech_DESmCBCi64pPKCS5

Mech_DESmCBCMACi0pPKCS5

DES2

Mech_DES2mCBCi64pPKCS5

Mech_DES2mCBCMACi0pPKCS5

DES3

Mech_DES3mCBCi64pPKCS5

Mech_DES3mCBCMACi0pPKCS5

CAST

Mech_CASTmCBCi64pPKCS5

Mech_CASTmCBCMACi0pPKCS5

CAST256

Mech_CAST256mCBCi128pPKCS5

Mech_CAST256mCBCMACi0pPKCS5

ArcFour

Mech_ArcFourpNone

Rijndael

Mech_RijndaelmCBCi128pPKCS5

Mech_RijndaelmCBCMACi0pPKCS5

Blowfish

Mech_BlowfishmCBCi64pPKCS5

Mech_BlowfishmCBCMACi0pPKCS5

Twofish

Mech_TwofishmCBCi128pPKCS5

Mech_TwofishmCBCMACi0pPKCS5

Serpent

Mech_SerpentmCBCi128pPKCS5

Mech_SerpentmCBCMACi0pPKCS5

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

ArcFour

N/A

Y

Y

-

-

Blowfish

64

Y

Y

-

-

CBC MAC

-

-

Y

Y

ECB

Y

Y

-

-

CAST

64

CBC

Y

Y

-

-

CBC MAC

-

-

Y

Y

ECB

Y

Y

-

-

Cast256

128

CBC

Y

Y

-

-

CBC MAC

-

-

Y

Y

ECB

Y

Y

-

-

DES

64

CBC

Y

Y

-

-

CBC MAC

-

-

Y

Y

ECB

Y

Y

-

-

DES2

64

CBC

Y

Y

-

-

CBC MAC

-

-

Y

Y

ECB

Y

Y

-

-

Triple DES

64

CBC

Y

Y

-

-

CBC MAC

-

-

Y

Y

ECB

Y

Y

-

-

SEED

128

CBC

Y

Y

-

-

CBC MAC

-

-

Y

Y

ECB

Y

Y

-

-

Serpent

128

CBC

Y

Y

-

-

CBC MAC

-

-

Y

Y

ECB

Y

Y

-

-

Rijndael

128

CBC

Y

Y

-

-

CBC MAC

-

-

Y

Y

ECB

Y

Y

-

-

GCM

Y

Y

-

-

Twofish

128

CBC

Y

Y

-

-

CBC MAC

-

-

Y

Y

ECB

Y

Y

-

-

Diffie-Hellman

N/A

Key Exchange

-

Y

-

-

ElGamal

Y

Y

-

-

DSA

N/A

-

-

Y

Y

ECDSA

N/A

-

-

Y

Y

ECDH

N/A

Key Exchange

-

Y

-

-

KCDSA

-

-

Y

Y

RSA

N/A

-

-

Y

Y

HMAC

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

HMACTiger

-

-

Y

Y

Random

N/A

Template

N/A

-

-

-

-

Wrapped

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

Key data

typedef struct {
    M_ByteBlock k    data
} M_KeyType_Random_Data;

Key generation parameters

typedef struct {
    M_Word lenbytes;                            length in bytes
} M_KeyType_Random_GenParams;

Notes

The FIPS 46-3 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 Triple DES key that does not have the parity set correctly, the module returns Status_InvalidData.

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.

Key data

struct M_Mech_ArcFourpNONE_Cipher {
    M_ByteBlock cipher;                         192-bit key
};

Key generation parameters

typedef struct {
    M_Word lenbytes;                            length in bytes
} M_KeyType_Random_GenParams;

Mechanisms

Mech_ArcFourpNONE

The cipher text is a byte block. This mechanism has no IV.

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 data

typedef struct {
    M_ByteBlock k;                              data
} M_KeyType_Random_Data;

Key generation parameters

typedef struct {
    M_Word lenbytes;                            length in bytes
} M_KeyType_Random_GenParams;

Mechanisms

Mech_BlowfishmECBpNONE

ECB

Mech_BlowfishmCBCpNONE

CBC

Mech_BlowfishmCBCi64PKCS5

CBC

Mech_BlowfishmCBCMACi64PKCS5

CBC MAC see note

Mech_BlowfishmECBpPKCS5

ECB

Mech_BlowfishmCBCMACi0PKCS5

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

Mech_CASTmCBCi64pPKCS5

CBC

Mech_CASTmCBCMACi64pPKCS5

see note

Mech_CASTmECBpPKCS5

ECB

Mech_CASTmCBCMACi0pPKCS5

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

Mech_CAST256mCBCi128pPKCS5

CBC with PKCS #5 padding

Mech_CAST256mECBpPKCS5

ECB with PKCS #5 padding

Mech_CAST256mCBCpNONE

CBC with no padding

Mech_CAST256mECBpNONE

ECB with no padding

Mech_CAST256mCBCMACi128pPKCS5

see note

Mech_CAST256mCBCMACi0pPKCS5

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

Mech_DESmCBCpNONE

CBC no padding

Mech_DESmCBCi64pPKCS5

CBC with PKCS5 padding

Mech_DESmCBCMACi64pPKCS5

see note

Mech_DESmECBpNONE

ECB no padding

Mech_DESmECBpPKCS5

ECB with PKCS5 padding

Mech_DESmCBCMACi0pPKCS5

CBC MAC with PKCS5 padding

Mech_DESmCBCMACi0pNONE

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

Cipher text
typedef struct {
    M_ByteBlock cipher;
} M_Mech_Generic64_Cipher;
IV
typedef struct {
    M_Block64 iv;
} M_Mech_Generic64_IV;

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.

Key generation parameters

There are no key generation parameters.

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

Mech_DES2mCBCpNONE

CBC no padding

Mech_DES2mCBCi64pPKCS5

CBC with PKCS5 padding

Mech_DES2mCBCMACi64pPKCS5

see note

Mech_DES2mECBpNONE

ECB no padding

Mech_DES2mECBpPKCS5

ECB with PKCS5 padding

Mech_DES2mCBCMACi0pPKCS5

CBCMAC with PKCS5 padding

Mech_DES2mCBCMACi0pNONE

CBC MAC with no padding

The mechanism Mech_DES2mCBCMACi64pPKCS5 is deprecated and may be withdrawn in future versions.

CBC

Cipher text
typedef struct {
    M_ByteBlock cipher;
} M_Mech_Generic64_Cipher;
IV
typedef struct {
    M_Block64 iv;
} M_Mech_Generic64_IV;

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).

Key generation parameters

There are no key generation parameters.

Mechanisms

Mech_DES3mCBCi64pPKCS5

CBC with PKCS #5 padding

Mech_DES3mCBCMACi64pPKCS5

see note

Mech_DES3mCBCpNONE

CBC with no padding

Mech_DES3mECBpNONE

ECB with no padding

Mech_DES3mECBpPKCS5

ECB with PKCS #5 padding

Mech_DES3mCBCMACi0pPKCS5

CBCMAC with PKCS #5 padding

Mech_DES3mCBCMACi0pNONE

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

Mech_RijndaelmCBCpNONE

CBC

Mech_RijndaelmCBCi128pPKCS5

CBC with PKCS5 padding

Mech_RijndaelmCBCMACi128pPKCS5

see note

Mech_RijndaelmECBpNONE

ECB

Mech_RijndaelmECBpPKCS5

ECB with PKCS5 padding

Mech_RijndaelmCBCMACi128pPKCS5

CBC MAC with PKCS5 padding

Mech_RijndaelmCBCMACi128pNone

CBC MAC with no padding

Mech_RijndaelmGCM

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.

Key generation

Rijndael keys use the same key generation parameters and data format as the Random key type. They must be either 128, 192, or 256 bits (that is, 16, 24 or 32 bytes long).

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 data

typedef struct {
   M_ByteBlock k;                      fixed-length 128-bit key
} M_KeyType_SEED;

Key generation parameters

typedef struct {
   M_Word lenbytes;                            must be 16 bytes
} M_KeyType_SEED_GenParams;

Mechanisms

Mech_SEEDmECBpNONE

ECB with no padding

Mech_SEEDmECBpPKCS5

ECB with PKCS #5 padding

Mech_SEEDmCBCpNONE

CBC with no padding

Mech_SEEDmCBCi128pPKCS5

CBC with PKCS #5 padding

Mech_SEEDmCBCMACi128pPKCS5

see note

Mech_SEEDmCBCMACi0pPKCS5

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 data

typedef struct {
    M_ByteBlock k;                              data
} M_KeyType_Random_Data;

Key generation parameters

typedef struct {
    M_Word lenbytes;                            length in bytes
} M_KeyType_Random_GenParams;

Mechanisms

Mech_SerpentmECBpNONE

ECB with no padding

Mech_SerpentmCBCpNONE

CBC with no padding

Mech_SerpentmCBCi128PKCS5

CBC with PKCS #5 padding

Mech_SerpentmCBCMACi128PKCS5

see note

Mech_SerpentmECBpPKCS5

ECB with PKCS #5 padding

Mech_SerpentmCBCMACi0PKCS5

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 data

typedef struct {
    M_ByteBlock k    data
} M_KeyType_Random_Data;

Key generation parameters

typedef struct {
    M_Word lenbytes;                            length in bytes
} M_KeyType_Random_GenParams;

Mechanisms

Mech_TwofishmECBpNONE

ECB with no padding

Mech_TwofishmCBCpNONE

CBC with no padding

Mech_TwofishmCBCi128PKCS5

CBC with PKCS #5 padding

Mech_TwofishmCBCMACi128PKCS5

see note

Mech_TwofishmECBpPKCS5

ECB with PKCS #5 padding

Mech_TwofishmCBCMACi0PKCS5

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 specified DiscreteLogGroup 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 and P parameters, such that P 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 exponent X 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 of P will have no effect.

Mechanisms

Mech_DHKeyExchange

Mech_ElGamal

Mech_DLIESe3DEShSHA1

Mech_DLIESeAEShSHA1

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:

  1. Alice generates a DH key pair and exports her public key.

  2. Bob generates a DH key pair by using Alice’s G and P values and by setting the dlg_present bit in the flags to GenerateKeyPair. He then exports his public key.

  3. Alice takes Bob’s public key and passes it as a ciphertext to Decrypt using her private key. This returns, in bignum format:

    bobs public key decrypted

  4. Bob takes Alice’s public key and passes it to Decrypt using his private key. This returns, in bignum format:

    alices public key decrypted

    This result is the same as that which Alice derived.

  5. 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.

Cipher text

Diffie-Hellman
typedef struct {
    M_Bignum gx;
} M_Mech_DHKeyExchange_Cipher;
ElGamal
typedef struct {
    M_Bignum a    [gk mod p]
    M_Bignum b    M * (gxk) mod p
} M_Mech_ElGamal_Cipher;

where k is a random integer 1 < k < (p—1)

ElGamal signature creation and verification are not currently implemented.

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:

  1. When generating a DSAComm key, set the iv_present flag bit, and pass in the seed, counter, and h values.

  2. GenerateKey will follow the FIPS algorithm to generate a p, q, and g set, together with the associated h and counter values.

  3. You can now export the resulting DSAComm key and check that p, q, g, h, and counter are what you were expecting.

  4. GenerateKey will return Status_InvalidData if the given seed cannot be used to produce a valid p, q, or g 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 private key
typedef struct {
    M_DSADiscreteLogGroup dlg;
    M_Bignum x;
} M_KeyType_DSAPublic_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 of p—1;

  • g is h((p—1)/q, where h < p—1 and h((p—1)/q)mod p > 1.

  • This is the discrete logarithm group. These values may be shared between users.

  • A 160-bit number < q.

gxmod 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 specified DSADiscreteLogGroup.)

  • 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 supplying p, q, and g values and need to check them, or unless you require strict compliance with the FIPS 140-2 Level 3 standard. Setting the Strict 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 of p—1;

  • g is h((p—1)/q, where h < p—1 and h((p—1)/q)mod p > 1.

Cipher text

typedef struct {
    M_Bignum r;
    M_Bignum s;
} M_Mech_DSA_Cipher;

r is gk 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

Mech_DSA

Hash

Mech_DSAhSHA224

Hash28

SHA-224

Mech_DSAhSHA256

Hash32

SHA-256

Mech_DSAhSHA384

Hash48

SHA-384

Mech_DSAhSHA512

Hash64

SHA-512

Mech_DSAhRIPEMD160

Hash

RIPEMD-160

If the plain text format is Bytes, then the mechanism will hash the plain text itself before signing.

Mechanisms

Mech_DSA

10

Mech_DSAhSHA224

Mech_DSAhSHA256

Mech_DSAhSHA384

Mech_DSAhSHA512

Mech_DSAhRIPEMD160

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

Private keys
struct M_KeyType_ECPrivate_Data {
    M_EllipticCurve curve;
    M_Bignum d;
};
  • curve is the curve used.

  • d is an integer up to the order of the group.

Public keys
struct M_KeyType_ECPublic_Data {
    M_EllipticCurve curve;
    M_ECPoint Q;
};
  • curve is the curve used.

  • Q is a point on the curve.

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 x1 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

Mech_ECDSA

Hash

Mech_ECDSAhSHA224

Hash28

SHA-224

Mech_ECDSAhSHA256

Hash32

SHA-256

Mech_ECDSAhSHA384

Hash48

SHA-384

Mech_ECDSAhSHA512

Hash64

SHA-512

Mech_ECDSAhRIPEMD160

Hash

RIPEMD-160

Mechanisms

Mech_ECDSA
Mech_ECDH
Mech_ECDSAhSHA224
Mech_ECDSAhSHA256
Mech_ECDSAhSHA384
Mech_ECDSAhSHA512
Mech_ECDSAhRIPEMD160
Neither Mech_ECDSA nor Mech_ECDH handle normal representations.

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:

  1. When generating a KCDSAComm key, set the iv_present flag bit, and pass in the seed and counter values.

  2. GenerateKey will follow the KCDSA algorithm to generate a p, q, and g set.

  3. You can now export the resulting KCDSAComm key and check that p, q, and g are what you were expecting.

  4. GenerateKey will return Status_InvalidData if the given seed and counter cannot be used to produce a valid p, q, or g 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 is h((p—1)/q, where h < p—1 and h((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 is h((p—1)/q, where h < p—1 and h((p—1)/q)mod p > 1.

  • x is an arbitrary number where 0 < x < q.

  • y is g(1/x mod q)mod p (a number less than p).

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 is h((p—1)/q, where h < p—1 and h((p—1)/q)mod p > 1.

  • y is g(1/x mod q)mod p (a number less than p).

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 of p in bits, a multiple of 256 where 1024 ≤ plen ≤ 2048.

  • qlen is the length of q 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 specified KCDSADiscreteLogGroup.)

    • KeyType_KCDSAPrivate_GenParams_flags__allflags

  • plen is the length of p in bits.

  • qlen is the length of q 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 is h((p—1)/q, where h < p—1 and h((p—1)/q)mod p > 1.

Cipher text

typedef struct {
    M_ByteBlock r;
    M_Bignum s;
} M_Mech_KCDSA_Cipher;
  • r is h(gkmod p).

  • s is x(k - (rh (z||m))) mod q

The symbol ⊕ represents a bit-wise XOR operation. The symbol || represents concatenation of Byteblocks

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.

Mechanisms

Mech_KCDSAHAS160

110

Mech_KCDSASHA1

111

Mech_KCDSARIPEMD160

112

Mech_KCDSASHA224

Mech_KCDSASHA256

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 is D MODP -1

  • dmq1 is D MODQ -1

  • iqmp is Q-1MODP

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 and q are 'strong' - that is p+1, p-1, q+1 and q-1 each have at least one prime factor >2100

      • primes p and q each pass 8 iterations of the Rabin-Miller test followed by the Lucas test

      • p and q 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:

Mech_RSApPKCS1=

see note 1

Mech_RSAhSHA1pPKCS1=

see note 2

Mech_RSAhRIPEMD160pPKCS1=

see note 2

Mech_RSApPKCS1OAEP=

see note 3

Mech_RSApPKCS1OAEPhSHA224

Mech_RSApPKCS1OAEPhSHA256

Mech_RSApPKCS1OAEPhSHA384

Mech_RSApPKCS1OAEPhSHA512

Mech_RSAhSHA1pPSS

Mech_RSAhRIPEMD160pPSS

Mech_RSAhSHA224pPSS

Mech_RSAhSHA256pPSS

Mech_RSAhSHA384pPSS

Mech_RSAhSHA512pPSS

  1. This mechanism has the following behavior:

    • Encrypt

      • accepts plain text of the type Bignum or Bytes

      • 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 or Bytes

      • 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 or Bytes

      • 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 the Sign or Verify command. For PKCS #1 compatible signatures, the ObjectID that identifies the hash algorithm should be placed before the hash value itself to form a plain text of the type Bytes. Alternatively, you can use RSAhMD5pPKCS1 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.
  2. These mechanisms will Sign and Verify only. They have the following behavior:

    • Sign accepts plain text of the type Bignum, Bytes or appropriate hash.

      • for Bignum no padding is performed

      • for Bytes, Sign hashes this plain text with the selected hash function, adds the correct ObjectID, pads the result using PKCS #1 padding.

      • the hash must be the correct size for the hash mechanism specified: adds the correct ObjectID, pads the hash using PKCS #1 padding, the resulting padded string is then encrypted.

    • Verify accepts plain text of type Bytes and cipher text of the type M_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 and Sign commands.

  3. This mechanism performs encryption and decryption with OAEP padding. It implements the RSAES-OAEP-ENCRYPT and RSAES-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 a Bytes type plain text with a length from 0 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 the given_iv_present flag, and enter the encoding parameters as the IV. In order to pass encoding parameters to the Decrypt command, set the IV in the iv member of the cipher parameter. The IV is in the form of a byte block p, the length of which may be 0.

Cipher text - PKCS #11 padding

typedef struct {
    M_Bignum m;
} M_Mech_RSApPKCS1_Cipher;

Cipher text - OAEP padding

typedef struct {
    M_Bignum m;
} M_Mech_RSApSETOAEP_Cipher;

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 function NFastApp_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

DeriveMech_DESsplitXOR

see note 1

DeriveMech_DESjoinXOR

see note 2

DeriveMech_DES2splitXOR

see note 1

DeriveMech_DES2joinXOR

see note 2

DeriveMech_DES3splitXOR

see note 1

DeriveMech_DES3joinXOR

see note 2

DeriveMech_DESjoinXORsetParity

see note 2

DeriveMech_DES2joinXORsetParity

see note 2

DeriveMech_DES3joinXORsetParity

see note 2

DeriveMech_RandsplitXOR

see note 1

DeriveMech_RandjoinXOR

see note 2

DeriveMech_CASTsplitXOR

see note 1

DeriveMech_CASTjoinXOR

see note 2

DeriveMech_EncryptMarshalled

see note 3

DeriveMech_DecryptMarshalled

see note 3

DeriveMech_PKCS8Encrypt

see note 4

DeriveMech_PKCS8Decrypt

see note 4

DeriveMech_RawEncrypt

see note 5

DeriveMech_RawDecrypt

see note 5

DeriveMech_AESsplitXOR

see note 1

DeriveMech_AESjoinXOR

see note 2

DeriveMech_Any

DeriveMech_PublicFromPrivate

see note 6

DeriveMech_ECCMQV

DeriveMech_ConcatenateBytes

DeriveMech_ConcatenationKDF

DeriveMech_NISTKDFmCTRpRijndaelCMACr32

DeriveMech_RawEncryptZeroPad

DeriveMech_RawDecryptZeroPad

DeriveMech_AESKeyWrap

DeriveMech_AESKeyUnwrap

DeriveMech_ECKA

DeriveMech_ECIESKeyWrap

see note 7

DeriveMech_ECIESKeyUnwrap

see note 8

  1. These mechanisms take a base key of the specified type and a wrapping key of type Random to produce an output key of type Wrapped.

  2. These mechanisms take a base key of type Wrapped and a wrapping key of type Random to produce an output key of the specified type.

  3. The EncryptMarshalled and DecryptMarshalled mechanisms are provided to allow export of keys from a module in FIPS 140-2 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:

    1. Marshals an M_PlainText structure that represents the base key to produce a byte string.

    2. Turns the byte string into Bytes plaintext, and encrypts it with the wrapping key to produce ciphertext.

    3. Marshals the ciphertext into a further byte string.

    4. 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 and Wrapped keys can be imported into the module even in FIPS 140-2 Level 3 mode. The import must be authorized by a certificate signed by the nShield Security Officer’s key KNSO.

    The DecryptMarshalled mechanism performs the complementary operation: it unmarshals and decrypts a ciphertext represented as a Wrapped key, then unmarshals the resulting plaintext to recover the M_PlainText structure for the output key.

    An example of importing keys using the DecryptMarshalled mechanism:

    1. Generate an RSA key pair Kpub, Kpriv. Kpub must have export-as-plain permissions; Kpriv must have a DeriveKey action group that specifies a role of WrapKey and a mechanism of DecryptMarshalled. Export Kpub.

    2. Marshall the key Ki to be imported. Pad the result according to PKCS #1 and encrypt it with Kpub (for example, using the ModExp command).

    3. Marshal the ciphertext: write Mech_RSApPKCS1 as an M_Word (02 00 00 00), the length of the bignum, then the bytes in little-endian order. Import the resulting byteblock as a key Kw of type Wrapped.

    4. Create a template key Kt that contains the desired ACL for the key to be imported, and import it.

    5. Use DeriveKey with Kt as the template, the Kw as the base key, and Kpriv as the wrapper key.

      The resulting key is Ki imported with the correct ACL.

  4. The PKCS8Encrypt and PKCS8Decrypt 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 type RSAPrivate, DSAPrivate, ECDSAPrivate, ECDHPrivate or DHPrivate, 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 under Wrapping/unwrapping private keys.) The resulting byte block is encrypted, using the given iv, which includes a mechanism. The data of the ciphertext is converted into a key of type Wrapped.

    The PKCS8Decrypt mechanism performs the opposite process: it takes a Wrapped key type as the Base key and a symmetric key as the Wrapping key. The data is decrypted using the given iv and mechanism, and then BER-decodes to give a RSAPrivate, DSAPrivate, ECDSAPrivate or DHPrivate 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).

  5. The RawEncrypt and RawDecrypt mechanisms are provided to allow raw key data to be encrypted and decrypted using any key that accepts a cipher text as Bytes. Alternatively, for RawEncrypt 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:

    1. It extracts the key data of the Base key as a byte block.

    2. If an encryption mechanism is specified in the IV, the key data is encrypted using the Wrapping key, IV and the mechanism specified in the IV, 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 the IV, the key data is signed using the Wrapping key, IV and the mechanism specified in the IV, which must be a valid mechanism for the given Wrapping Key.
      If a hashing mechanism is specified in the IV, the key data is hashed using the Wrapping key (if the mechanism requires one), IV and the mechanism specified in the IV, 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.

    3. 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 the IV to be used when decrypting, are passed in the dst_type and iv 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 the IV 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 using RawDecrypt to produce a key of type Wrapped, and importing a Random key of the right length with all bytes zero. Then use the DESjoinXORsetParity mechanisms on these two keys to produce a DES key with correct parity bits.

  6. 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.

  7. The DeriveMech_ECIESKeyWrap mechanism takes a base key of the specified symmetric type and a wrapping key of type ECDHPublic to produce an output key of type Wrapped.

  8. The DeriveMech_ECIESKeyUnwrap mechanism takes a base key of type ciphertext and a wrapping key of type ECDHPrivate to produce an output key of type keytype.

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.

Mechanism

Mech_SHA1Hash

Reply

typedef struct {
    M_Hash20 h;
} M_Mech_SHA1Hash_Cipher;

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.

Mechanism

Mech_TigerHash

Reply

typedef struct {
    M_Hash24 h;
} M_Mech_TigerHash_Cipher;

SHA-224

SHA-224 is a member of the SHA-2 hash function family that yields a 28-byte result.

Mechanism

Mech_SHA224

Reply

typedef struct {
    M_Hash28 h;
} M_Mech_SHA224Hash_Cipher;

SHA-256

SHA-256 is a member of the SHA-2 hash function family that yields a 32-byte result.

Mechanism

Mech_SHA256

Reply

typedef struct {
    M_Hash32 h;
} M_Mech_SHA256Hash_Cipher;

SHA-384

SHA-384 is a member of the SHA-2 hash function family that yields a 48-byte result.

Mechanism

Mech_SHA384Hash

Reply

typedef struct {
    M_Hash48 h;
} M_Mech_SHA384Hash_Cipher;

SHA-512

SHA-512 is a member of the SHA-2 hash function family that yields a 64-byte result.

Mechanism

Mech_SHA512Hash

Reply

typedef struct {
    M_Hash64 h;
} M_Mech_SHA512Hash_Cipher;

MD2

MD2 is a hash function that was designed by Ron Rivest. MD2 returns a 16-byte hash.

Mechanism

Mech_MD2Hash

Reply

typedef struct {
    M_Hash16 h;
} M_Mech_MD2Hash_Cipher;

MD5

MD5 is a hash function that was designed by Ron Rivest. MD5 returns a 16-byte hash.

Mechanism

Mech_MD5Hash

Reply

typedef struct {
    M_Hash16 h;
} M_Mech_MD5Hash_Cipher;

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.

Mechanism

Mech_RIPEMD160Hash

Reply

typedef struct {
    M_Hash20 h;
} M_Mech_RIPEMD160Hash_Cipher;

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.

Mechanism

Mech_HAS160Hash                                     109

Reply

typedef struct {
    M_Hash20 h;
} M_Mech_HAS160Hash_Cipher;

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_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_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 each action.

    • 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 flags PermissionGroup_flags_certifier_present, PermissionGroup_flags_certmech_present, or PermissionGroup_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, use PermissionGroup_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 corresponding Cmd_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 key KNSO, 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, or PermissionGroup_flags_NSOCertified, the module returns Status_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 the certmech field. The certifier 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 a NULL pointer, indicating that no further authorization is required.

  • mech is the mechanism that is to be used to sign the certificate. You can specify Mech_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 the NewEnquiry 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 the DeriveKey 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 the LoadBlob 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 the fileId of the NVRAM file containing the use limit.

  • range is the memory range within the file for this limit.

  • maxlo and maxhi 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 LimitIDs 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 marked used, unless the ReadShare command sets the UseLimitsUnwanted flag.

    If any share is loaded - locally or remotely - when it is already marked used, the logical token is marked UseLimitsUnavailable. 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 and UseLimAuth_Old both use the new mechanism. However, the nfkmverify 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:

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 the KeyID 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 the MakeBlob command to encrypt a key blob or in the LoadBlob command to decrypt a key from a blob.

  • Act_OpPermissions_Details_perms_UseAsKM: Only DES3 keys can be used for module keys, KM.

  • 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 KM0. If this flag is not set, you must use KM0 or logical tokens based on KM0.

    • 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 KM0, you must set the AllowNonKM0 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 KM0, you must set the AllowNonKM0 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 - see Act_MakeBlob_Details_flags_kmhash_present above.

  • *kthash - see Act_MakeBlob_Details_flags_kthash_present above.

  • *ktparams - see Act_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 without kahash_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 or Mech_Any; for indirect blobs this specifies the mechanism which must be used to encrypt the session key. If set to Mech_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 the otherkeys 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 the Cmd_DeriveKey_Args_flags_WorldHashMech, which can be obtained via the GetKeyInfoEx 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 returns Status_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:

devref 1 4

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.

  1. Use the Import command with the following parameters to import a template key for an ACL that allows the use of DeriveKey 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 the NFastApp_MarshalACL() command.

    Such use of the Import command will return

    idka=                                         IDKA 0010
  2. 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
  3. Use the Import command with the following parameters to import a template key for an ACL that contains oppermissions 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 the NFastApp_MarshalACL() command.

      In order to create a nested ACL in Java, use the marshall() method from the M_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;
      ...
  4. 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
  5. 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
  6. Get this key’s hash by using the GetKeyInfo command:

    key        IDKA 0012

    This command returns:

    type       Random
    hash       HKA 0012
  7. 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
  8. 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
  9. 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.
  10. 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 its appdata and ACL from the template key that was created earlier: IDKA 0011
  11. 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
  12. 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.

  13. 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 the KeyID 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 the certsignmsg, which is signed with the private key that corresponds to pubkeydata.

  • 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 in messages-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 a certifier 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 in messages-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:

  1. 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.

  2. The access control system checks to ensure that the SEE World data was, in fact, signed by the specified key.

  3. If so, the certificate is accepted much as a signingkey certificate would be. However, because a signingkey certificate is always treated as fresh but an SEE certificate is not, the flag PermissionGroup_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.