java.lang.Object
net.i2p.crypto.HMACGenerator
net.i2p.crypto.HMAC256Generator

public final class HMAC256Generatorextends HMACGenerator
HMAC-SHA256 message authentication code generator for I2P cryptographic operations.

This class provides HMAC-SHA256 calculation using the standard JCA Mac interface, ensuring compatibility with javax.crypto.Mac.getInstance("HmacSHA256"). It offers both one-shot calculation and streaming operations for different use cases.

Key features:

  • HMAC-SHA256 algorithm implementation for message authentication
  • Thread-safe operation with Mac instance pooling
  • Optimized for both small and large data processing
  • Integration with I2P's session key management

Compatibility Note: As of 0.9.12, this class uses the standard javax.crypto.Mac implementation for improved security and compatibility.

  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    (package private) static final class 
    Performance-optimized SecretKey implementation for HMAC operations.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private final LinkedBlockingQueue<Mac>
    Initialized MACs ready for reuse.
    private static final boolean
    Whether initialized MACs are pooled.
    private static final int
    MACs held for reuse.
  • Constructor Summary

    Constructors
    Constructor
    Description
    Create a new HMAC256Generator.
  • Method Summary

    Public Methods
    Modifier and Type
    Method
    Description
    (package private) Mac
    Package private for HKDF.
    void
    calculate(byte[] key, byte[] data, int offset, int length, byte[] target, int targetOffset)
    Calculate the HMAC of the data with the given key.
    void
    calculate(SessionKey key, byte[] data, int offset, int length, byte[] target, int targetOffset)
    Calculate the HMAC of the data with the given key.
    (package private) void
    release(Mac mac)
    Release a Mac back to the pool.
    boolean
    verify(SessionKey key, byte[] curData, int curOffset, int curLength, byte[] origMAC, int origMACOffset, int origMACLength)
    Verify the MAC inline, reducing some unnecessary memory churn.

    Methods inherited from class HMACGenerator

    acquireTmp, releaseTmp
    Modifier and Type
    Method
    Description
    protected byte[]
    32 bytes from the byte array cache.
    protected void
    releaseTmp(byte[] tmp)
    Release a temporary array back to the cache.

    Methods inherited from class Object

    clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

  • Constructor Details

    • HMAC256Generator

      public HMAC256Generator(I2PAppContext context)
      Create a new HMAC256Generator.
      Parameters:
      context - not read; the generator keeps no reference to it
  • Method Details

    • calculate

      public void calculate(SessionKey key, byte[] data, int offset, int length, byte[] target, int targetOffset)
      Calculate the HMAC of the data with the given key. Outputs 32 bytes to target starting at targetOffset.
      Specified by:
      calculate in class HMACGenerator
      Parameters:
      key - the session key
      data - the data to HMAC
      offset - the starting offset in data
      length - how much data do we want to run the HMAC over
      target - out parameter the first 16 bytes contain the HMAC, the last 16 bytes are zero
      targetOffset - offset into target to put the hmac
      Throws:
      UnsupportedOperationException - if the JVM does not support it
      IllegalArgumentException - for bad key or target too small
    • calculate

      public void calculate(byte[] key, byte[] data, int offset, int length, byte[] target, int targetOffset)
      Calculate the HMAC of the data with the given key. Outputs 32 bytes to target starting at targetOffset.
      Parameters:
      key - first 32 bytes used as the key
      data - the data to calculate the HMAC over
      offset - offset into data
      length - number of bytes to include
      target - receives the 32 byte MAC, so it needs 32 bytes of room
      targetOffset - where in target to write the MAC
      Throws:
      UnsupportedOperationException - if the JVM does not support it
      IllegalArgumentException - for bad key or target too small
    • verify

      public boolean verify(SessionKey key, byte[] curData, int curOffset, int curLength, byte[] origMAC, int origMACOffset, int origMACLength)
      Verify the MAC inline, reducing some unnecessary memory churn.
      Specified by:
      verify in class HMACGenerator
      Parameters:
      key - session key to verify the MAC with
      curData - MAC to verify
      curOffset - index into curData to MAC
      curLength - how much data in curData do we want to run the HMAC over
      origMAC - what do we expect the MAC of curData to equal
      origMACOffset - index into origMAC
      origMACLength - how much of the MAC do we want to verify, use 32 for HMAC256
      Returns:
      true if the MAC matches
    • acquire

      Mac acquire()
      Package private for HKDF.
      Returns:
      cached or a Mac for "HmacSHA256"
    • release

      void release(Mac mac)
      Release a Mac back to the pool. Mac will be reset, discarding any accumulated message state. Per the JCA contract, Mac.reset() "resets this Mac object to the state it was in when previously initialized via a call to init(Key)", so it clears the message state without re-running the ipad/opad key schedule that Mac.init(java.security.Key) does. That is all a pooled Mac needs, because every caller of acquire() must init() before use, and engineInit() overwrites all 64 bytes of both k_ipad and k_opad, so the previous key schedule cannot leak into the next operation. Package private for HKDF.
      Parameters:
      mac - the Mac to release