private void checkVectors( int count, CCMBlockCipher ccm, byte[] k, int macSize, byte[] n, byte[] a, byte[] p, byte[] t, byte[] c) throws InvalidCipherTextException { byte[] fa = new byte[a.length / 2]; byte[] la = new byte[a.length - (a.length / 2)]; System.arraycopy(a, 0, fa, 0, fa.length); System.arraycopy(a, fa.length, la, 0, la.length); checkVectors(count, ccm, "all initial associated data", k, macSize, n, a, null, p, t, c); checkVectors(count, ccm, "subsequent associated data", k, macSize, n, null, a, p, t, c); checkVectors(count, ccm, "split associated data", k, macSize, n, fa, la, p, t, c); checkVectors(count, ccm, "reuse key", null, macSize, n, fa, la, p, t, c); }
@Override public int getIVSize() { int ivSize = this.ivSize; if (ivSize < 0) { final BlockCipher underlyingCipher = delegate.getUnderlyingCipher(); if (underlyingCipher instanceof CFBBlockCipher) ivSize = ((CFBBlockCipher)underlyingCipher).getUnderlyingCipher().getBlockSize(); else if (underlyingCipher instanceof OFBBlockCipher) ivSize = ((OFBBlockCipher)underlyingCipher).getUnderlyingCipher().getBlockSize(); else ivSize = underlyingCipher.getBlockSize(); if (delegate instanceof CCMBlockCipher) --ivSize; this.ivSize = ivSize; } return ivSize; }
private void testModes(BlockCipher cipher1, BlockCipher cipher2, int keySize) throws Exception { final KeyParameter key = new KeyParameter(new byte[keySize]); final int blockSize = getBlockSize(cipher1); final CipherParameters withIv = new ParametersWithIV(key, new byte[blockSize]); if (blockSize > 1) { testMode(new PaddedBufferedBlockCipher(cipher1, new PKCS7Padding()), key); testMode(new PaddedBufferedBlockCipher(new CBCBlockCipher(cipher1), new PKCS7Padding()), withIv); testMode(new BufferedBlockCipher(new OFBBlockCipher(cipher1, blockSize)), withIv); testMode(new BufferedBlockCipher(new CFBBlockCipher(cipher1, blockSize)), withIv); testMode(new BufferedBlockCipher(new SICBlockCipher(cipher1)), withIv); } // CTS requires at least one block if (blockSize <= 16 && streamSize >= blockSize) { testMode(new CTSBlockCipher(cipher1), key); } if (blockSize <= 16 && streamSize >= blockSize) { testMode(new NISTCTSBlockCipher(NISTCTSBlockCipher.CS1, cipher1), key); testMode(new NISTCTSBlockCipher(NISTCTSBlockCipher.CS2, cipher1), key); testMode(new NISTCTSBlockCipher(NISTCTSBlockCipher.CS3, cipher1), key); } if (blockSize == 8 || blockSize == 16) { testMode(new EAXBlockCipher(cipher1), withIv); } if (blockSize == 16) { testMode(new CCMBlockCipher(cipher1), new ParametersWithIV(key, new byte[7])); testMode(new GCMBlockCipher(cipher1), withIv); testMode(new OCBBlockCipher(cipher1, cipher2), new ParametersWithIV(key, new byte[15])); } }
protected AEADBlockCipher createAEADBlockCipher_AES_CCM() { return new CCMBlockCipher(createAESEngine()); }
private void checkVectors( int count, CCMBlockCipher ccm, String additionalDataType, byte[] k, int macSize, byte[] n, byte[] a, byte[] sa, byte[] p, byte[] t, byte[] c) throws InvalidCipherTextException { KeyParameter keyParam = (k == null) ? null : new KeyParameter(k); ccm.init(true, new AEADParameters(keyParam, macSize, n, a)); byte[] enc = new byte[c.length]; if (sa != null) { ccm.processAADBytes(sa, 0, sa.length); } int len = ccm.processBytes(p, 0, p.length, enc, 0); len += ccm.doFinal(enc, len); if (!areEqual(c, enc)) { fail("encrypted stream fails to match in test " + count + " with " + additionalDataType); } ccm.init(false, new AEADParameters(keyParam, macSize, n, a)); byte[] tmp = new byte[enc.length]; if (sa != null) { ccm.processAADBytes(sa, 0, sa.length); } len = ccm.processBytes(enc, 0, enc.length, tmp, 0); len += ccm.doFinal(tmp, len); byte[] dec = new byte[len]; System.arraycopy(tmp, 0, dec, 0, len); if (!areEqual(p, dec)) { fail("decrypted stream fails to match in test " + count + " with " + additionalDataType, new String(Hex.encode(p)), new String(Hex.encode(dec))); } if (!areEqual(t, ccm.getMac())) { fail("MAC fails to match in test " + count + " with " + additionalDataType); } }
public CCM() { super(new CCMBlockCipher(new AESFastEngine()), false, 16); }
private void AES_CCM_Encrypt(AlgorithmID alg, byte[] rgbKey) throws CoseException, IllegalStateException, InvalidCipherTextException { CCMBlockCipher cipher = new CCMBlockCipher(new AESFastEngine()); KeyParameter ContentKey; int cbIV; switch (alg) { case AES_CCM_16_64_128: case AES_CCM_16_64_256: case AES_CCM_16_128_128: case AES_CCM_16_128_256: cbIV = 15 - 2; break; case AES_CCM_64_64_128: case AES_CCM_64_64_256: case AES_CCM_64_128_256: case AES_CCM_64_128_128: cbIV = 15 - 8; break; default: throw new CoseException("Unsupported algorithm: " + alg); } // The requirements from JWA byte[] IV = new byte[cbIV]; CBORObject cbor = findAttribute(HeaderKeys.IV); if (cbor != null) { if (cbor.getType() != CBORType.ByteString) throw new CoseException("IV is incorreclty formed."); if (cbor.GetByteString().length > cbIV) throw new CoseException("IV is too long."); IV = cbor.GetByteString(); } else { random.nextBytes(IV); addAttribute(HeaderKeys.IV, CBORObject.FromObject(IV), Attribute.UNPROTECTED); } if (rgbKey.length != alg.getKeySize()/8) throw new CoseException("Key Size is incorrect"); ContentKey = new KeyParameter(rgbKey); // Build the object to be hashed AEADParameters parameters = new AEADParameters(ContentKey, alg.getTagSize(), IV, getAADBytes()); cipher.init(true, parameters); byte[] C = new byte[cipher.getOutputSize(rgbContent.length)]; int len = cipher.processBytes(rgbContent, 0, rgbContent.length, C, 0); len += cipher.doFinal(C, len); rgbEncrypt = C; }
@Override public BlockCipher initChainingMode(BlockCipher baseCipher) { return new AEADBlockCipherAdapter(new CCMBlockCipher(baseCipher)); }
protected AEADBlockCipher createAEADBlockCipher_AES_CCM() { return new CCMBlockCipher(new AESFastEngine()); }
private void ivParamTest( int count, CCMBlockCipher ccm, byte[] k, byte[] n) throws InvalidCipherTextException { byte[] p = Strings.toByteArray("hello world!!"); ccm.init(true, new ParametersWithIV(new KeyParameter(k), n)); byte[] enc = new byte[p.length + 8]; int len = ccm.processBytes(p, 0, p.length, enc, 0); len += ccm.doFinal(enc, len); ccm.init(false, new ParametersWithIV(new KeyParameter(k), n)); byte[] tmp = new byte[enc.length]; len = ccm.processBytes(enc, 0, enc.length, tmp, 0); len += ccm.doFinal(tmp, len); byte[] dec = new byte[len]; System.arraycopy(tmp, 0, dec, 0, len); if (!areEqual(p, dec)) { fail("decrypted stream fails to match in test " + count); } }