3GPP Mechanisms for 5G Mobile Networks

This section describes the C-based PKCS#11 interface to the 3GPP functions in the HSM firmware. The mechanisms described below are also represented in JCPROV..

NOTE   This feature requires minimum Luna HSM Firmware 7.4.2 (Luna HSM Firmware 7.7.0 for Luna PCIe HSM) and Luna HSM Client 10.2.0 (or a patched Luna HSM Client 7.4.0). You require a backup HSM with minimum Luna Backup HSM 7 Firmware 7.7.1 to back up these objects.




>Storage Key (SK)

>See also Luna Key Translation.



As with all the 3GPP crypto operations, the C_SignInit/C_Sign function calls are made.

    CK_SESSION_HANDLE hSession,		// the session's handle
    CK_MECHANISM_PTR  pMechanism,	// the signature mechanism
                      mechanism		// mechanism type   CKM_MILENAGE
                      pParameter	// pointer to the milenage mechanism CK_MILENAGE_SIGN_PARAMS
                      ulParameterLen	// length (sizeof) in bytes of the parameter

    CK_OBJECT_HANDLE  hKey		// AES storage key used to encrypt/decrypt Ki and OP (optional)

    CK_SESSION_HANDLE hSession,	// the session's handle
    CK_BYTE_PTR       pData,		// should be NULL for CKM_MILENAGE (see CKM_MILENAGE_RESYNC)
    CK_ULONG          ulDataLen,	// should be set to zero for CKM_MILENAGE
    CK_BYTE_PTR       pSignature,	// gets the signature – see OUTPUT response string below
    CK_ULONG_PTR      pulSignatureLen	// gets signature length


Parameter Structure:

typedef struct CK_MILENAGE_SIGN_PARAMS {
    CK_ULONG          ulMilenageFlags;
    CK_ULONG          ulEncKiLen;
    CK_BYTE_PTR       pEncKi;
    CK_ULONG          ulEncOPcLen;
    CK_BYTE_PTR       pEncOPc;		// Encrypted or plain – see flags
    CK_OBJECT_HANDLE  hSecondaryKey;	// optional OP object handle – see flags
    CK_OBJECT_HANDLE  hRCKey;		// optional R and C params – see flags
    CK_BYTE           sqn[6];
    CK_BYTE           amf[2];


The ulMilenageFlags can consist of one or more of the following:

#define LUNA_5G_OPC                 0x00000001      // OPC is provided rather than OP
#define LUNA_5G_ENCRYPTED_OP        0x00000002      // OP or OPC is encrypted by Storage Key
#define LUNA_5G_OP_OBJECT           0x00000004      // OP or OPC is an object in HSM partition
#define LUNA_5G_USE_TLV             0x00000008      // Use the Tag/Len/Val format in response
#define LUNA_5G_USER_DEFINED_RC     0x00000010      // User defined R and C constants

NOTE   If the LUNA_5G_OP_OBJECT flag is specified, then the hSecondaryKey parameter should contain the handle of the generic secret object which holds the OP string. As well, if the LUNA_5G_USER_DEFINED_RC flag is set, then set the hRCKey to point to the RC generic secret object.

Although the R and C values are hard-coded (per the 3GPP specification) the Luna implementation allows the user to define his own constants. It is first necessary to create a generic secret object on the HSM where the CKA_VALUE attribute contains a concatenation of the R and C fields as follows:

C1[16 bytes], C2[16 bytes], C3[16 bytes], C4[16 bytes], C5[16 bytes], R1[1 byte], R2[1 byte], R3[1 byte], R4[1 byte], R5[1 byte]

TIP   Use a hex editor to create the binary RC file. Use the API or the ckdemo utility to encrypt the file with the SK, and subsequently unwrap it onto the HSM as an 85 byte generic secret object.

Output: The signature (output) produced from the above function call will contain the following data (note the exact function as per the 3GPP spec is show in parentheses):

| RANDOM | XRES(f2) | CK(f3) | IK(f4) | AUTN |  where AUTN = | SQN xor AK(f5) | AMF | MAC-A(f1) |

Although by default the data is returned as one concatenated binary string, the user may have the data returned in TLV (Tag/Length/Value) format by setting the “LUNA_5G_USE_TLV” flag. The output will appear as follows:

| Tag (UINT8) | Length (UINT8) | Value | Tag (UINT8) | Length (UINT8) | Value | …

The tag values are defined as follows:

#define LUNA_5G_TAG_RANDOM          0x00000001      // Random data generated in HSM
#define LUNA_5G_TAG_RES             0x00000002      // Response string
#define LUNA_5G_TAG_CK              0x00000003      // Confidentiality Key
#define LUNA_5G_TAG_IK              0x00000004      // Integrity Key
#define LUNA_5G_TAG_SQN_XOR_AK      0x00000005      // Sequence # xor'd with Anonymity Key (AK)
#define LUNA_5G_TAG_AMF             0x00000006      // Authentication Management Field
#define LUNA_5G_TAG_MAC             0x00000007      // MAC-A for authentication
#define LUNA_5G_TAG_SEQUENCE        0x00000008      // Sequence # in resynch operation


C_SignInit and C_Sign function calls same as Authentication.


Parameter Structure: same as for Authentication.

The API allows the USIM to resynchronize with a new SQN number in the event that a message was lost. The SQN is not sent in the clear however; rather it is XOR’ed with the AK (f5*). As well the MAC-S (f1*) is also sent to verify that this request is coming from a legitimate subscriber. This requires that the USIM sends the random data and an AUTS (Auth string) to the AUC which contains the following:

AUTS = | SQN xor AK | MAC-S |

The user should format the pData (data to sign in the C_Sign call) as follows:

pData = | RAND | AUTS |

This mechanism uses the same mechanism parameter structure as for authentication, as the Ki, OP and AMF are required to generate the sequence number. (The sqn[] field in the param structure will be ignored.) The LUNA_5G_OP_OBJECT, LUNA_5G_USE_TLV, and LUNA_5G_USER_DEFINED_RC are valid flags.

Output: The HSM will first generate the new SQN number but will check the MAC-S signature to ensure the legitimacy of the request. If the MAC-S signature passed in is not equal to the signature calculated by the HSM, the HSM will return the error CKR_SIGNATURE_INVALID. If the return code is CKR_OK, the signature will contain the new 6 byte SQN number.

AUTS Generation (Testing Only)

The HSM supports generating the AUTS string for the purpose of testing the Resynchronization operation.

C_SignInit and C_Sign function calls same as Authentication.


Parameter Structure: same as for Authentication. The user should pass in the random string in the pData field of the C_Sign function call.

Output: The signature returned from the HSM will be a concatenation of the Random string plus the AUTS as follows (no TLV):

| RAND | SQN xor AK | MAC-S |

This string may be fed directly into the pData field of the C_Sign call when doing the RESYNC operation.



TUAK is similar to MILENAGE in respect to the output data however the calculated components are largely based upon the Keccak (SHA-3) hashing scheme. In addition, TUAK allows some variability in the lengths of the output components. The desired lengths can be specified in input parameter structure as follows:

typedef struct CK_TUAK_SIGN_PARAMS {
    CK_ULONG             ulTuakFlags;
    CK_ULONG             ulEncKiLen;
    CK_BYTE_PTR          pEncKi;
    CK_ULONG             ulEncTOPcLen;
    CK_BYTE_PTR          pEncTOPc;       // Encrypted or plain – see flags
    CK_ULONG             ulIterations;   // # of Keccak iterations
    CK_OBJECT_HANDLE     hSecondaryKey;  // optional OP key handle
    CK_ULONG             ulResLen;       // length of expected response (XRES)
    CK_ULONG             ulMacALen;      // length of MAC
    CK_ULONG             ulCkLen;        // length of crypto key CK
    CK_ULONG             ulIkLen;        // length of identity key IK
    CK_BYTE              sqn[6];
    CK_BYTE              amf[2];


The ulTuakFlags are the same as the MILENAGE flags with the exception of the LUNA_5G_USER_DEFINED_RC flag which is not applicable to TUAK.

Output: same as MILENAGE authentication output.



Parameter Structure: same as for authentication, although some fields are not be required (key length fields, for example).

Format of the input data, and the resulting output are the same as MILENAGE.

AUTS Generation (Testing Only)

As with MILENAGE, this function supports generation of the AUTS string for subsequent testing of the RESYNC operation.



The Comp128 algorithms supports device authentication for the legacy GSM 2/2.5 mobile networks.

Mechanism: CKM_COMP128

Parameter Structure:

typedef struct CK_COMP128_SIGN_PARAMS {
    CK_ULONG            ulVersion;		// Version of Comp128
    CK_ULONG            ulEncKiLen;
    CK_BYTE_PTR         pEncKi;


This API supports the 3 versions of the COMP128 algorithm. This is passed in via the ulVersion field.

As with the other mechanisms, it is expected that the Ki will be encrypted under the Storage Key (SK) – the handle for this key is passed in as the signing key in C_SignInit function call.

Output: The signature (output) produced from the above function call will contain the following data:

| RANDOM | SRES | Kc |

NOTE   Unlike MILENAGE and TUAK, the output is only in binary form, and the TLV formatting is not supported at this time. Only a single triplet output is supported via this API.

Storage Key (SK)

It is assumed that under the security constraints imposed by the HSM, the subscribers key (Ki) will always be encrypted by the HSM resident Storage Key (SK). The SK is an AES key and can be any size although a 256 bit (32 byte) value is recommended. Currently, the encryption/decryption mechanism used is the NIST approved CKM_AES_KWP (PKCS#11 definition) and where the default IV (per NIST SP800-38F) is used. The Ki (and optionally the OP) must be encrypted using this mechanism for later use in the authentication and resynchronization operations.