in security/tpm/src/tpm.ts [354:417]
private _signData(dataToSign: Buffer, callback: (err: Error, signedData?: Buffer) => void): void {
/*Codes_SRS_NODE_TPM_SECURITY_CLIENT_06_013: [If `signWithIdentity` is invoked without a previous successful invocation of `activateIdentityKey`, the callback will be invoked with `err` of `InvalidOperationError`] */
if (!this._idKeyPub) {
return callback(new errors.InvalidOperationError('activateIdentityKey must be invoked before any signing is attempted.'));
}
this._getPropsAndHashAlg((err, idKeyHashAlg, props) => {
if (err) {
const secErr = new errors.SecurityDeviceError('Could not get TPM capabilities');
(<any>secErr).tpmError = err;
callback(secErr);
} else if (props.tpmProperty.length !== 1 || props.tpmProperty[0].property !== TPM_PT.INPUT_BUFFER) {
/*Codes_SRS_NODE_TPM_SECURITY_CLIENT_06_015: [If the tpm device is not properly configured, the callback will be invoked with `err` of `SecurityDeviceError`.] */
callback(new errors.SecurityDeviceError('Unexpected result of TPM2_GetCapability(TPM_PT.INPUT_BUFFER)'));
} else {
const maxInputBuffer: number = props.tpmProperty[0].value;
if (dataToSign.length <= maxInputBuffer) {
this._tpm.withSession(tss.NullPwSession).HMAC(TpmSecurityClient._idKeyPersistentHandle, dataToSign, idKeyHashAlg, (err: tss.TpmError, signature: Buffer) => {
const rc = err ? err.responseCode : TPM_RC.SUCCESS;
debug('HMAC returned: ' + TPM_RC[rc]);
if (rc === TPM_RC.SUCCESS) {
callback(null, signature);
} else {
callback(err);
}
});
} else {
let curPos: number = 0;
let bytesLeft: number = dataToSign.length;
let hSequence: TPM_HANDLE = null;
const loopFn = () => {
if (bytesLeft > maxInputBuffer) {
const sliceCurPos = curPos;
bytesLeft -= maxInputBuffer;
curPos += maxInputBuffer;
this._tpm.withSession(tss.NullPwSession).SequenceUpdate(hSequence, dataToSign.slice(sliceCurPos, sliceCurPos + maxInputBuffer), loopFn);
} else {
this._tpm.withSession(tss.NullPwSession).SequenceComplete(hSequence, dataToSign.slice(curPos, curPos + bytesLeft), new TPM_HANDLE(tss.TPM_RH.NULL), (err: tss.TpmError, resp: tss.SequenceCompleteResponse) => {
const rc = err ? err.responseCode : TPM_RC.SUCCESS;
debug('SequenceComplete returned: ' + TPM_RC[rc]);
if (rc === TPM_RC.SUCCESS) {
callback(null, resp.result);
} else {
callback(err);
}
});
}
};
this._tpm.withSession(tss.NullPwSession).HMAC_Start(TpmSecurityClient._idKeyPersistentHandle, Buffer.alloc(0), idKeyHashAlg, (err: tss.TpmError, hSeq: TPM_HANDLE) => {
const rc = err ? err.responseCode : TPM_RC.SUCCESS;
debug('HMAC_Start returned: ' + TPM_RC[rc]);
if (err) {
const secErr = new errors.SecurityDeviceError('Could not hash key');
(<any>secErr).tpmError = err;
callback(secErr);
} else {
hSequence = hSeq;
loopFn();
}
});
}
}
});
}