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 please refer to the 13.4 version of the User Guide. Older versions of the User Guides are available on the Entrust website. Since CEF was the only format of audit logs available prior to the release of Security World 13.5 older versions of this User Guide 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.
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 thenew-world
command -
Specifying the
--mode=common-criteria-cmts
option in thenew-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:
-
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.
The signature on the logs can be verified using a tool such as ncore-audit-verify.py
.
Verification tools require access to the public KML
. Since KML
changes when the HSM is initialized it is important to have verified all audit log records before initializing the HSM.
Alternatively keep a record of the public KML
for all audit logs produced by each HSM.
Audit log administration
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 follow the procedures at
Upgrading firmware
you will receive an error message.
You may either finalize the audit log and repeat the command or use the hsmadmin upgrade
command with the --force
option to over-ride the warning.
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 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 Manage the system clock of an nShield 5s for more information on setting the system clock.