示例#1
0
 private void gHASHPartial(byte[] Y, byte[] b, int off, int len) {
   GCMUtil.xor(Y, b, off, len);
   multiplier.multiplyH(Y);
 }
示例#2
0
  /**
   * NOTE: MAC sizes from 32 bits to 128 bits (must be a multiple of 8) are supported. The default
   * is 128 bits. Sizes less than 96 are not recommended, but are supported for specialized
   * applications.
   */
  @Override
  public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException {
    this.forEncryption = forEncryption;
    this.macBlock = null;

    KeyParameter keyParam;

    if (params instanceof AEADParameters) {
      AEADParameters param = (AEADParameters) params;

      nonce = param.getNonce();
      initialAssociatedText = param.getAssociatedText();

      int macSizeBits = param.getMacSize();
      if (macSizeBits < 32 || macSizeBits > 128 || macSizeBits % 8 != 0) {
        throw new IllegalArgumentException("Invalid value for MAC size: " + macSizeBits);
      }

      macSize = macSizeBits / 8;
      keyParam = param.getKey();
    } else if (params instanceof ParametersWithIV) {
      ParametersWithIV param = (ParametersWithIV) params;

      nonce = param.getIV();
      initialAssociatedText = null;
      macSize = 16;
      keyParam = (KeyParameter) param.getParameters();
    } else {
      throw new IllegalArgumentException("invalid parameters passed to GCM");
    }

    int bufLength = forEncryption ? BLOCK_SIZE : (BLOCK_SIZE + macSize);
    this.bufBlock = new byte[bufLength];

    if (nonce == null || nonce.length < 1) {
      throw new IllegalArgumentException("IV must be at least 1 byte");
    }

    // TODO Restrict macSize to 16 if nonce length not 12?

    // Cipher always used in forward mode
    // if keyParam is null we're reusing the last key.
    if (keyParam != null) {
      cipher.init(true, keyParam);

      this.H = new byte[BLOCK_SIZE];
      cipher.processBlock(H, 0, H, 0);

      // GCMMultiplier tables don't change unless the key changes (and are expensive to init)
      multiplier.init(H);
      exp = null;
    } else if (this.H == null) {
      throw new IllegalArgumentException("Key must be specified in initial init");
    }

    this.J0 = new byte[BLOCK_SIZE];

    if (nonce.length == 12) {
      System.arraycopy(nonce, 0, J0, 0, nonce.length);
      this.J0[BLOCK_SIZE - 1] = 0x01;
    } else {
      gHASH(J0, nonce, nonce.length);
      byte[] X = new byte[BLOCK_SIZE];
      Pack.longToBigEndian((long) nonce.length * 8, X, 8);
      gHASHBlock(J0, X);
    }

    this.S = new byte[BLOCK_SIZE];
    this.S_at = new byte[BLOCK_SIZE];
    this.S_atPre = new byte[BLOCK_SIZE];
    this.atBlock = new byte[BLOCK_SIZE];
    this.atBlockPos = 0;
    this.atLength = 0;
    this.atLengthPre = 0;
    this.counter = Arrays.clone(J0);
    this.bufOff = 0;
    this.totalLength = 0;

    if (initialAssociatedText != null) {
      processAADBytes(initialAssociatedText, 0, initialAssociatedText.length);
    }
  }
示例#3
0
 private void gHASHBlock(byte[] Y, byte[] b) {
   GCMUtil.xor(Y, b);
   multiplier.multiplyH(Y);
 }