Audit Logging

Aims of audit logging

Audit Logging on nShield HSMs provides the means to log administrative operations and key usage events across your estate of HSMs.

Some events are always logged and some events are logged only if certain conditions are met. Details of which events are logged, the conditions for logging the event, and the main information in those logs is described in Commands audited.

Logs are accurately time-stamped to allow correlation of these logs with other systems that may form part of your security or network environments.

Logs are signed and can be verified by the tools provided so that any attempts to alter the contents of the logs can be detected.

Audit logging is a compliance requirement of some certification schemes such as Common Criteria but can optionally be used with any Security World. The option must be specified when the World is created and cannot be added later.

Audit logging and CEF audit logging

There are two different audit log formats which differ depending on the firmware loaded on the HSM.

HSMs loaded with firmware versions prior to 13.5 will produce audit logs in CEF format and this guide refers to the production of logs in that format as 'CEF audit logging'.

HSMs loaded with firmware versions of 13.5 or later will produce audit logs in a new format and this guide refers to the production of logs in this format as 'audit logging'.

For a description of CEF audit logging and how to manage it, see the following v13.4 guides:

Since CEF was the only format of audit logs available prior to the release of Security World 13.5 older versions of the User Guides refer to CEF audit logging simply as 'audit logging'.

If your Security World uses a mix of HSMs with firmware before and after 13.5 you will receive logs in both formats. These logs are essentially independent and you must manage them separately.

Configuring audit logging

Enabling audit logging

Audit Logging is enabled on an HSM when it is added to a Security World that is configured for audit logging.

Since accurate time-stamps are important for audit logging Entrust recommends that you ensure that the system clock has been accurately set before enabling audit logging. See Manage the system clock of an nShield 5s for help managing the system clock on nShield 5s HSMs.

The Security World is configured for audit logging when it is created. This can be done in one of two ways:

  • Specifying the --audit-logging or -G option in the new-world command

  • Specifying the --mode=common-criteria-cmts option in the new-world command

For the overall procedure, see Creating a Security World using new-world.

The --mode=common-criteria-cmts option will create a Security World supporting Common Criteria PP 419 221-5 which imposes other restrictions not related to audit logging. Only use this option if you require compliance to Common Criteria

There are some differences in the conditions that must be met for particular events to be audited depending on which of the two options above has been used to create the Security World. These differences are explained in Commands audited.

Disabling audit logging

Audit Logging is set for the lifetime of the Security World.

To disable Audit Logging on an HSM:

  1. Reinitialize the HSM using initunit. See Erasing a module with initunit

Before removing the HSM from the Security World you should check that you have exported and verified all the logs that you require. Once the HSM has been erased it may not be possible to obtain and verify any logs that had not yet been exported.

Key usage logging

By default Audit Logging does not log usage of keys for cryptographic operations such as sign, verify, encrypt and decrypt or their usage in channels for these purposes. The capability to log these operations is determined on a per-key basis by the LogKeyUsage permission group flag on the ACL group authorizing the operation for which logging is desired.

See the nCore Developer Tutorial for further information on ACLs.

The generatekey utility (see Key generation options and parameters) provides the ability to set this permission group flag when a key is generated by either:

  • Specifying logkeyusage=yes as an option on the command line

  • Answering yes to the logkeyusage question if the command is being used interactively.

When generatekey is used this flag is applied to all permission groups but is only checked by the HSM on the group authorizing the desired action.

The following example shows this set on permission group 0 of a key’s ACL.

groups[    0].flags= LogKeyUsage
                     .n_limits= 0
                     .n_actions= 2
                     .actions[    0].type= OpPermissions
                                        .details.oppermissions.perms= DuplicateHandle
ExportAsPlain GetAppData SetAppData
   ReduceACL ExpandACL Encrypt Verify UseAsBlobKey GetACL

The table in Commands audited shows which commands implement conditional key usage logging.

Commands audited

The table below shows which nCore commands may produce audit logs. The column titled 'Logged?' specifies if the logging is conditional or not. An entry in that column of 'ALWAYS' means that the command is unconditionally logged. An entry in that column of 'CONDITIONAL' means that logging is conditional according to the criteria below:

Conditional items:

(a) means the command is logged if an ACL check on a supplied key involves the LogKeyUsage bit, see Key usage logging

(b) means the command may need NSO permissions or (for files/shares with their own ACLs) some other certifier. If the command is certified using a CertType_SigningKey entry, a log record may be generated as a result of an ACL check (for UseAsCertificate permission) on that key.

(c) means the command is logged if the object involved is "loggable". Note that keys are always loggable if the Security World was created with --mode=common-criteria-cmts, see Enabling audit logging

(d) means this command becomes 'Always Logged' if the Security World was created with --mode=common-criteria-cmts, see Enabling audit logging

(e) means this command is logged if it accesses a (local or remote) smartcard

Commands marked "(a),(c)" will therefore generate audit-log records if either one of the "input" keys requires logging as part of an ACL check, or one of the "output" keys is a loggable object.

The other two columns in the table refer to the information that is logged for that command. See Audit log contents for more information.

Command Logged? CmdAuditInfo contents Extra AuditInfo entries

Cmd_ChangeShareGroupPIN

ALWAYS

SlotID slot table: ShareInfo shares

ObjectUse(cert) TokenID

Cmd_ChangeSharePIN

ALWAYS

SlotID slot ShareInfo share

ObjectUse(cert) TokenID

Cmd_ChannelOpen

CONDITIONAL (a)

ChannelMode mode

ObjectUse(key,cert)

Cmd_CheckUserAction

CONDITIONAL (a)

-

ObjectUse(key,cert)

Cmd_CreateSEEConnection

ALWAYS

UUID containerid

-

Cmd_Decrypt

CONDITIONAL (a)

-

ObjectUse(key,cert)

Cmd_DeriveKey

CONDITIONAL (a),(c),(d)

-

ObjectUse(key,cert) ObjectNew

Cmd_Destroy

CONDITIONAL (c)

AuditObjectID objid Word refcount

-

Cmd_Duplicate

CONDITIONAL (a),(c), (d)

-

ObjectUse(key,cert) ObjectNew

Cmd_DynamicSlotCreateAssociation

ALWAYS

SlotID slot

-

Cmd_DynamicSlotsConfigure

ALWAYS

Word slot

-

Cmd_Encrypt

CONDITIONAL (a)

-

ObjectUse(key,cert)

Cmd_EraseFile

CONDITIONAL (b),(e)

-

ObjectUse(cert) TokenID

Cmd_EraseShare

ALWAYS

SlotID slot Word i ShortHash hkt

ObjectUse(cert) TokenID

Cmd_Export

CONDITIONAL (a),(d)

-

ObjectUse(key,cert)

Cmd_FileCopy

CONDITIONAL (b),(e)

-

ObjectUse(cert) TokenID

Cmd_FileCreate

CONDITIONAL (b),(e)

-

ObjectUse(cert) TokenID

Cmd_FileErase

CONDITIONAL (b),(e)

-

ObjectUse(cert) TokenID

Cmd_FileOp

CONDITIONAL (b),(e)

-

ObjectUse(cert) TokenID

Cmd_FormatToken

ALWAYS

SlotID slot optional: KeyHashEx auth_key

ObjectUse(cert) TokenID

Cmd_GenerateKey

CONDITIONAL (c),(d)

-

ObjectUse(cert) ObjectNew

Cmd_GenerateKeyPair

CONDITIONAL (c),(d)

-

ObjectUse(cert) ObjectNew (x 2)

Cmd_GenerateLogicalToken

ALWAYS

-

ObjectUse(key,cert) ObjectNew

Cmd_GetACL

CONDITIONAL (a)

-

ObjectUse(key,cert)

Cmd_GetAppData

CONDITIONAL (a)

-

ObjectUse(key,cert)

Cmd_GetRTC

CONDITIONAL (b)

-

ObjectUse(cert)

Cmd_GetTicket

CONDITIONAL (c)

AuditObjectID objid

-

Cmd_ImpathKXBegin

ALWAYS

optional: ASCIIString esn

ObjectNew

Cmd_ImpathKXFinish

ALWAYS

-

ObjectUse(imp)

Cmd_Import

CONDITIONAL (c),(d)

-

ObjectNew

Cmd_InitialiseUnit

ALWAYS

=InitialiseUnitEx

-

Cmd_InitialiseUnitEx

ALWAYS

InitModeFlags initmodeflags KMLType kmltype

Startup

Cmd_InsertSoftToken

ALWAYS

SlotID slot

-

Cmd_LoadBlob

CONDITIONAL (a),(c),(d)

-

ObjectUse(lt,key,cert) ObjectNew

Cmd_LoadLogicalToken

ALWAYS

-

ObjectUse(lt,cert) ObjectNew

Cmd_MakeBlob

CONDITIONAL (a)

-

ObjectUse(key,cert)

Cmd_NVMemAlloc

CONDITIONAL (b)

-

ObjectUse(cert)

Cmd_NVMemFree

CONDITIONAL (b)

-

ObjectUse(cert)

Cmd_NVMemOp

CONDITIONAL (b)

-

ObjectUse(cert)

Cmd_ReadFile

CONDITIONAL (b),(e)

-

ObjectUse(cert) TokenID

Cmd_ReadShare

ALWAYS

SlotID slot Word i Word sharesleft

ObjectUse(cert,lt) TokenID

Cmd_ReceiveKey

ALWAYS

-

ObjectNew ObjectUse(imp)

Cmd_ReceiveShare

ALWAYS

Word i Word sharesleft

ObjectUse(imp,lt)

Cmd_RedeemTicket

CONDITIONAL (c)

AuditObjectID objid Word refcount

-

Cmd_RemoveKM

ALWAYS

=RemoveKMEx

ObjectUse(cert)

Cmd_RemoveKMEx

ALWAYS

KeyHashEx hkm

ObjectUse(cert)

Cmd_RemoveSoftToken

ALWAYS

SlotID slot

-

Cmd_SendKey

ALWAYS

-

ObjectUse(imp,key,cert)

Cmd_SendShare

ALWAYS

SlotId slot Word i KeyHashEx hkm TokenHash hkt

ObjectUse(imp,cert) TokenID

Cmd_SetACL

CONDITIONAL (a),(d)

-

ObjectUse(key,cert)

Cmd_SetAppData

CONDITIONAL (a),(d)

-

ObjectUse(key,cert)

Cmd_SetKM

CONDITIONAL (a),(d)

-

ObjectUse(key,cert)

Cmd_SetNSOPerms

ALWAYS

=SetNSOPermsEx

-

Cmd_SetNSOPermsEx

ALWAYS

NSOPermsModeFlags nsoflags KeyHashEx hknso NSOPerms publicperms

-

Cmd_SetRTC

ALWAYS

RTCTime oldtime RTCTime newtime

-

Cmd_Sign

CONDITIONAL (a)

-

ObjectUse(key,cert)

Cmd_SignModuleState

CONDITIONAL (a)

-

ObjectUse(key,cert)

Cmd_StartAuditLogging

ALWAYS

ByteBlock nonce

Startup

Cmd_StaticFeatureEnable

ALWAYS

FeatureInfo info

-

Cmd_StopAuditLogging

ALWAYS

-

Shutdown

Cmd_Verify

CONDITIONAL (a)

-

ObjectUse(key,cert)

Cmd_WriteFile

CONDITIONAL (b),(e)

-

ObjectUse(cert) TokenID

Cmd_WriteShare

ALWAYS

SlotID slot Word i

ObjectUse(lt,cert) TokenID

Cmd_CreateBuffer (Solo-XC only)

CONDITIONAL (a)

-

ObjectUse(key,cert)

Cmd_CreateSEEWorld (Solo-XC only)

ALWAYS

-

-

Cmd_ForeignTokenOpen (Solo-XC only)

ALWAYS

SlotID slot

-

Cmd_SetSEEMachine (Solo-XC only)

ALWAYS

-

-

Audit log contents

Audit log information is recorded in audit records. Audit records are sent from the HSM within a data structure called an audit segment. Each audit segment starts with an AuditSegmentHeader and ends with a signature block signed by a key KML. See Audit log verification for further information on this signature and how to verify it.

The number of audit records contained within an audit segment is variable and depends upon factors such as the processing load of the HSM and the number of auditable events being triggered.

Audit logs exported by the system are not in human readable format unless converted using a suitable tool such as ncore-audit-verify.py. Examples shown below have been converted to JSON format.

Audit segment header contents

The AuditSegmentHeader contains the following information:

  • The ESN of the HSM that produced the audit segment

  • The logID (KML hash) of the HSM that produced the audit segment

  • The runID. This changes each time the system boots

  • The start and end audit indices

  • A timestamp of when the audit segment was started in milliseconds since January 1 1970

  • A timestamp of when the audit segment was signed in milliseconds since January 1 1970

  • A hash of the audit logs contained within the segment

An example AuditSegmentHeader is shown below:

"header": {
            "v": 0,
            "flags": "0x0",
            "esn": "14BD-B089-E078",
            "logID": "33133940 fb686dc5 4184a726 b670b7c1 508a8ea1",
            "runID": 4,
            "startIndex": 3458,
            "endIndex": 3458,
            "starttime": 1690801099591,
            "signtime": 1690801099591,
            "datahash": {
                "mech": "SHA256Hash",
                "data": {
                    "h": "2dcd7912 b9f0edd3 82df65f7 9ccdf289 4470a569 078638bf 20158eb1 e4c6aa6f"
                }
            }

Audit index

Each audit log record has an audit log index which increments by one for each log created since the start of audit logging. The AuditSegmentHeader shows the index for the first and last audit log contained in the segment.

In normal operation no audit records are lost and there will be no gaps in the audit index sequence.

If an abnormal shutdown occurs there is a possibility that some records may have been lost. This will be indicated by a gap in the audit index sequence and also by an AbnormalShutdown entry associated with the StartAuditLogging command.

It is not possible to tell exactly how many audit records were lost due to an abnormal shutdown. The gap in the audit index sequence indicates the maximum number that could have been lost based on the load of the HSM at the time of the abnormal shutdown but the actual number lost could be fewer than this and could even be zero.

Audit log contents

Each audit log produced will contain information as shown in the CmdAuditInfo contents column of the table in Commands audited. All audit logs contain basic information to indicate the name of the command that triggered the audit log and a status that indicates the outcome of that command, as in the extract below from an audit log produced by a GenerateKeyPair command.

{
      "type": "Command",
      "body": {
            "flags": "0x0",
            "cmd": "GenerateKeyPair",
            "info": {},
            "status": "OK"
      }
}

If the CmdAuditInfo contents column shows other information that will appear in the info section.

If the Extra AuditInfo entries column of the table in Commands audited contains entries these will appear as separate log entries, as in the extract below.

{
     "type": "ObjectUse",
    "body": {
         "v": 0,
        "objid": 137,
        "action": {
            "type": "MakeBlob",
            "details": {
                "flags": "0x0"
            }
        }
    }
}

Object identification

Objects are identified by an Objid. A new ID is assigned when the object is created and will appear in the ObjectNew record as shown in the example below.

An object identifier is unique whilst the system runs uninterrupted but values may be reused if the system reboots. The combination of RunID from the audit segment header and ObjID is always unique.

 {
     "type": "ObjectNew",
    "body": {
        "v": 0,
        "objid": 135,
        "type": "Key",
        "details": {
            "type": "RSAPrivate",
            "hash": {
                "mech": "SHA1Hash",
                "data": {
                    "hash": "bb6b1e71 1cc06123 853af0d6 ff781cb0 b7a4b515"
                }
            }
        }
    }
}

The same ID will appear in ObjectUse records and other command records relating to the same object allowing you to trace the object through the audit log. If an object is copied the new object will have its own ID so that you can keep track of each copy. When the copy is created you can identify the object being copied by its hash.

Audit log verification

As described in Audit log contents audit log records are protected by a signature across the audit segment in which they are delivered. The signature is made using KML which is a secret key unique to the HSM and protected by the HSM.

Each time the HSM is re-initialized (e.g. after upgrading firmware and re-loading the Security World) the previous KML is destroyed and a new KML is created. The hash of KML is used as the logID for the audit log.

You can print the KML hash of the current Security World using nfkminfo and looking for hkml. If you have more than one HSM connected nfkminfo will show the hkml for each HSM.

Audit log administration

Reading the audit logs

Audit logs are read as described in the nShield Audit Log Service.

Audit logging and firmware upgrade

The audit log should be finalized before upgrading the firmware on an HSM enrolled in an audit logging Security World. To finalize the audit log, see Disabling audit logging

If you do not finalize the audit log before attempting to upgrade the firmware of a PCIe or USB HSM, you will receive an error message. You can either finalize the audit log and repeat the command, or use one of the following commands to override the warning:

  • nShield Solo, Solo XC, and Edge HSMs: The loadrom command with the --noauditcheck option.

  • nShield 5s HSMs: The hsmadmin upgrade command with the --force option.

Upgrading the firmware without finalizing the audit log will result in there being no final audit log record. This means it will not be possible to prove completeness of the audit log.

Audit logging and the system clock

It is important that the timestamps in the audit logs are accurate so that events can be correlated across the whole network in which the HSM is operating.

If the system clock is lost, for instance due to the HSM running on battery power for an extended period of time, ncoreapi commands that would result in an audit log being generated will be inhibited until the system clock is restored:

See Setting the system clock for more information on setting the system clock on nShield 5s HSMs.