/** * Process the <em>Clear</em> part of the message. * * @param in a byte array containing the <em>Clear</em> part of the message. * @param offset the starting index in <code>in</code> where the <em>Clear</em> message bytes * should be considered. * @param length the count of bytes in <code>in</code>, starting from <code>offset</code> to * consider. * @throws IllegalStateException if no start-of-message method has been invoked earlier or the * Integrity Protection service has not been activated. */ public void doClear(byte[] in, int offset, int length) { if (!ready) { throw new IllegalStateException(); } if (!wantIntegrity) { throw new IllegalStateException(); } mac.update(in, offset, length); }
/** * Signals the end of the message transformation. * * @return the authentication tag bytes, if and when the Integrity Protection service was * specified; otherwise a 0-long byte array is returned. * @throws IllegalStateException if no start-of-message method has been invoked earlier. */ public byte[] endMessage() { if (!ready) { throw new IllegalStateException(); } if (!wantIntegrity) { return new byte[0]; } byte[] result = mac.digest(); reset(); return result; }
/** * Signals the start of a new message to process with this <code>UST</code> with a designated * <emIndex</em> value. * * @param ndx the <em>Index</em> to use with the new message. * @throws LimitReachedException if the value of the <em>Index</em> has reached its allowed upper * bound. To use this <code>UST</code> instance a new initialisation (with a new user-supplied * key material) should occur. * @throws InvalidKeyException if the underlying cipher, used in either or both the Integrity * Protection and Confidentiality Protection functions has detected an exception. */ public void beginMessageWithIndex(BigInteger ndx) throws LimitReachedException, InvalidKeyException { if (ndx.compareTo(maxIndex) > 0) { throw new LimitReachedException(); } index = ndx; // depending on the desired services, get keying material from the // internal keystream generator and complete the relevant attributes. // the key size shall be the same size as the user-supplied key material. // remember we need the 1st generator if integrity is required even when // confidentiality is not if (wantConfidentiality || wantIntegrity) { byte[] cpKey = new byte[keysize]; keystream.nextBytes(cpKey, 0, keysize); cpAttributes.put(IBlockCipher.KEY_MATERIAL, cpKey); if (cpStream instanceof ICMGenerator) { cpAttributes.put(ICMGenerator.SEGMENT_INDEX, index); } else { cpAttributes.put(UMacGenerator.INDEX, new Integer(index.intValue())); } cpStream.init(cpAttributes); } if (wantIntegrity) { byte[] ipKey = new byte[keysize]; keystream.nextBytes(ipKey, 0, keysize); ipAttributes.put(IBlockCipher.KEY_MATERIAL, ipKey); if (ipStream instanceof ICMGenerator) { ipAttributes.put(ICMGenerator.SEGMENT_INDEX, index); } else { ipAttributes.put(UMacGenerator.INDEX, new Integer(index.intValue())); } ipStream.init(ipAttributes); // get prefix bytes byte[] prefix = new byte[macLength]; cpStream.nextBytes(prefix, 0, macLength); macAttributes.put(TMMH16.PREFIX, prefix); mac = new TMMH16(); macAttributes.put(TMMH16.KEYSTREAM, ipStream); mac.init(macAttributes); } ready = true; }
/** * Process the <em>Opaque</em> part of the message. * * @param in a byte array containing the <em>Clear</em> part of the message. * @param inOffset the starting index in <code>in</code> where the <em>Opaque</em> message bytes * should be considered. * @param length the count of bytes in <code>in</code>, starting from <code>inOffset</code> to * consider. * @param out the byte array where the enciphered opaque message should be stored. * @param outOffset the starting offset in <code>out</code> where the enciphered bytes should be * stored. * @throws IllegalStateException if no start-of-message method has been invoked earlier. * @throws LimitReachedException if one or both of the underlying keystream generators have * reached their limit. */ public void doOpaque(byte[] in, int inOffset, int length, byte[] out, int outOffset) throws LimitReachedException { if (!ready) { throw new IllegalStateException(); } if (wantIntegrity) { mac.update(in, inOffset, length); } if (wantConfidentiality) { byte[] suffix = new byte[length]; cpStream.nextBytes(suffix, 0, length); for (int i = 0; i < length; ) { out[outOffset++] = (byte) (in[inOffset++] ^ suffix[i++]); } } else { System.arraycopy(in, inOffset, out, outOffset, length); } }
/** Reset this instance and prepare for processing a new message. */ public void reset() { ready = false; if (wantIntegrity) { mac.reset(); } }