code: public final void doFinal(byte[] output, int outOffset)
          throws ShortBufferException, IllegalStateException
      {
          chooseFirstProvider();
          if (initialized == false) {
              throw new IllegalStateException("MAC not initialized");
          }
          int macLen = getMacLength();
          if (output == null || output.length-outOffset < macLen) {
              throw new ShortBufferException
                  ("Cannot store MAC in output buffer");
          }
          byte[] mac = doFinal();
          System.arraycopy(mac, 0, output, outOffset, macLen);
          return;
      }
docs: Finishes the MAC operation.
  
  <p>A call to this method resets this <code>Mac</code> object to the
  state it was in when previously initialized via a call to
  <code>init(Key)</code> or
  <code>init(Key, AlgorithmParameterSpec)</code>.
  That is, the object is reset and available to generate another MAC from
  the same key, if desired, via new calls to <code>update</code> and
  <code>doFinal</code>.
  (In order to reuse this <code>Mac</code> object with a different key,
  it must be reinitialized via a call to <code>init(Key)</code> or
  <code>init(Key, AlgorithmParameterSpec)</code>.
  
  <p>The MAC result is stored in <code>output</code>, starting at
  <code>outOffset</code> inclusive.
  
  @param output the buffer where the MAC result is stored
  @param outOffset the offset in <code>output</code> where the MAC is
  stored
  
  @exception ShortBufferException if the given output buffer is too small
  to hold the result
  @exception IllegalStateException if this <code>Mac</code> has not been
  initialized.