private _signData()

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();
            }
          });
        }
      }
    });
  }