Search in sources :

Example 21 with GCMParameterSpec

use of javax.crypto.spec.GCMParameterSpec in project tink by google.

the class AndroidKeystoreAesGcm method decrypt.

@Override
public byte[] decrypt(final byte[] ciphertext, final byte[] aad) throws GeneralSecurityException {
    if (ciphertext.length < IV_SIZE_IN_BYTES + TAG_SIZE_IN_BYTES) {
        throw new GeneralSecurityException("ciphertext too short");
    }
    GCMParameterSpec params = new GCMParameterSpec(8 * TAG_SIZE_IN_BYTES, ciphertext, 0, IV_SIZE_IN_BYTES);
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
    cipher.init(Cipher.DECRYPT_MODE, key, params);
    cipher.updateAAD(aad);
    return cipher.doFinal(ciphertext, IV_SIZE_IN_BYTES, ciphertext.length - IV_SIZE_IN_BYTES);
}
Also used : GeneralSecurityException(java.security.GeneralSecurityException) GCMParameterSpec(javax.crypto.spec.GCMParameterSpec) Cipher(javax.crypto.Cipher)

Example 22 with GCMParameterSpec

use of javax.crypto.spec.GCMParameterSpec in project tink by google.

the class AesGcmHkdfStreaming method paramsForSegment.

private GCMParameterSpec paramsForSegment(byte[] prefix, int segmentNr, boolean last) {
    ByteBuffer nonce = ByteBuffer.allocate(NONCE_SIZE_IN_BYTES);
    nonce.order(ByteOrder.BIG_ENDIAN);
    nonce.put(prefix);
    nonce.putInt(segmentNr);
    nonce.put((byte) (last ? 1 : 0));
    return new GCMParameterSpec(8 * TAG_SIZE_IN_BYTES, nonce.array());
}
Also used : GCMParameterSpec(javax.crypto.spec.GCMParameterSpec) ByteBuffer(java.nio.ByteBuffer)

Example 23 with GCMParameterSpec

use of javax.crypto.spec.GCMParameterSpec in project tink by google.

the class AesGcmJce method decrypt.

@Override
public byte[] decrypt(final byte[] ciphertext, final byte[] associatedData) throws GeneralSecurityException {
    if (ciphertext.length < IV_SIZE_IN_BYTES + TAG_SIZE_IN_BYTES) {
        throw new GeneralSecurityException("ciphertext too short");
    }
    GCMParameterSpec params = new GCMParameterSpec(8 * TAG_SIZE_IN_BYTES, ciphertext, 0, IV_SIZE_IN_BYTES);
    Cipher cipher = instance();
    cipher.init(Cipher.DECRYPT_MODE, keySpec, params);
    if (associatedData != null && associatedData.length != 0) {
        cipher.updateAAD(associatedData);
    }
    return cipher.doFinal(ciphertext, IV_SIZE_IN_BYTES, ciphertext.length - IV_SIZE_IN_BYTES);
}
Also used : GeneralSecurityException(java.security.GeneralSecurityException) GCMParameterSpec(javax.crypto.spec.GCMParameterSpec) Cipher(javax.crypto.Cipher)

Example 24 with GCMParameterSpec

use of javax.crypto.spec.GCMParameterSpec in project wycheproof by google.

the class AesGcmTest method testByteBufferShiftedAlias.

/**
 * Encryption with ByteBuffers should be copy-safe even if the buffers have different starting
 * offsets and/or do not make the backing array visible.
 *
 * <p>Note that bugs in this often require a sizeable input to reproduce; the default
 * implementation of engineUpdate(ByteBuffer, ByteBuffer) copies through 4KB bounce buffers, so we
 * need to use something larger to see any problems - 8KB is what we use here.
 *
 * @see https://bugs.openjdk.java.net/browse/JDK-8181386
 */
@NoPresubmitTest(providers = { ProviderType.BOUNCY_CASTLE, ProviderType.OPENJDK }, bugs = { "b/64378943" })
@Test
public void testByteBufferShiftedAlias() throws Exception {
    byte[] ptVector = new byte[8192];
    for (int i = 0; i < 3; i++) {
        // outputOffset = offset relative to start of input.
        for (int outputOffset = -1; outputOffset <= 1; outputOffset++) {
            SecretKeySpec key = new SecretKeySpec(new byte[16], "AES");
            GCMParameterSpec parameters = new GCMParameterSpec(128, new byte[12]);
            Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
            cipher.init(Cipher.ENCRYPT_MODE, key, parameters);
            ByteBuffer output, input, inputRO;
            // We'll try three scenarios: Ordinary array backed buffers, array backed buffers where one
            // is read-only, and direct byte buffers.
            String mode;
            // offsets relative to start of buffer
            int inputOffsetInBuffer = 1;
            int outputOffsetInBuffer = inputOffsetInBuffer + outputOffset;
            int sliceLength = cipher.getOutputSize(ptVector.length);
            int bufferSize = sliceLength + Math.max(inputOffsetInBuffer, outputOffsetInBuffer);
            switch(i) {
                case 0:
                case 1:
                    {
                        byte[] buffer = new byte[bufferSize];
                        // It's important to slice() here as otherwise later when we flip() position will be
                        // reset to 0.
                        output = ByteBuffer.wrap(buffer, outputOffsetInBuffer, sliceLength).slice();
                        input = ByteBuffer.wrap(buffer, inputOffsetInBuffer, sliceLength).slice();
                        if (i == 1) {
                            mode = "array backed buffers with RO buffer";
                            inputRO = input.asReadOnlyBuffer();
                        } else {
                            mode = "array backed buffers";
                            inputRO = input.duplicate();
                        }
                        break;
                    }
                case 2:
                    {
                        mode = "direct buffers";
                        ByteBuffer buf = ByteBuffer.allocateDirect(bufferSize);
                        output = buf.duplicate();
                        output.position(outputOffsetInBuffer);
                        output.limit(sliceLength + outputOffsetInBuffer);
                        output = output.slice();
                        input = buf.duplicate();
                        input.position(inputOffsetInBuffer);
                        input.limit(sliceLength + inputOffsetInBuffer);
                        input = input.slice();
                        inputRO = input.duplicate();
                        break;
                    }
                default:
                    {
                        throw new AssertionError("Unknown test index " + i);
                    }
            }
            // Now that we have our overlapping 'input' and 'output' buffers, we can write our plaintext
            // into the input buffer.
            input.put(ptVector);
            input.flip();
            // Make sure the RO input buffer has the same limit in case the plaintext is shorter than
            // sliceLength (which it generally will be for anything other than ECB or CTR mode)
            inputRO.limit(input.limit());
            try {
                int ctSize = cipher.doFinal(inputRO, output);
                // Now flip the buffers around and undo everything
                byte[] tmp = new byte[ctSize];
                output.flip();
                output.get(tmp);
                output.clear();
                input.clear();
                inputRO.clear();
                input.put(tmp);
                input.flip();
                inputRO.limit(input.limit());
                cipher.init(Cipher.DECRYPT_MODE, key, parameters);
                cipher.doFinal(inputRO, output);
                output.flip();
                assertEquals(ByteBuffer.wrap(ptVector), output);
            } catch (Throwable t) {
                throw new AssertionError("Overlapping buffers test failed with buffer type: " + mode + " and output offset " + outputOffset, t);
            }
        }
    }
}
Also used : SecretKeySpec(javax.crypto.spec.SecretKeySpec) GCMParameterSpec(javax.crypto.spec.GCMParameterSpec) Cipher(javax.crypto.Cipher) ByteBuffer(java.nio.ByteBuffer) SlowTest(com.google.security.wycheproof.WycheproofRunner.SlowTest) Test(org.junit.Test) ExcludedTest(com.google.security.wycheproof.WycheproofRunner.ExcludedTest) NoPresubmitTest(com.google.security.wycheproof.WycheproofRunner.NoPresubmitTest) NoPresubmitTest(com.google.security.wycheproof.WycheproofRunner.NoPresubmitTest)

Example 25 with GCMParameterSpec

use of javax.crypto.spec.GCMParameterSpec in project wycheproof by google.

the class AesGcmTest method testEncryptEmptyPlaintextWithEmptyIv.

/**
 * AES-GCM allows IVs of bit length 1 .. 2^64-1. See NIST SP 800 38d, Section 5.2.1.1
 * http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
 *
 * <p>Disallowing IVs of length 0 is necessary for the following reason: if an empty IV is used
 * then the tag is an evaluation of a polynomial with the hash subkey as the value. Since the
 * polynomial can be derived from the ciphertext it is known to an attacker. Therefore, any
 * message encrypted with an empty IV leaks the hash subkey. In particular, encrypting an empty
 * plaintext with an empty IV results in a ciphertext having a tag that is equal to the hash
 * subkey used in AES-GCM. I.e. both are the same as encrypting an all zero block.
 *
 * <p>OpenJDK fails this test.
 */
@NoPresubmitTest(providers = { ProviderType.OPENJDK }, bugs = { "b/35746778" })
@Test
public void testEncryptEmptyPlaintextWithEmptyIv() throws Exception {
    byte[] emptyIv = new byte[0];
    byte[] input = new byte[0];
    byte[] key = TestUtil.hexToBytes("56aae7bd5cbefc71d31c4338e6ddd6c5");
    SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
    Cipher block = Cipher.getInstance("AES/ECB/NoPadding");
    block.init(Cipher.ENCRYPT_MODE, keySpec);
    byte[] hashkey = block.doFinal(new byte[16]);
    try {
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, new GCMParameterSpec(16 * 8, emptyIv));
        byte[] ct = cipher.doFinal(input);
        // If the encryption above is not rejected then the hash key and the ciphertext are the same.
        // Both are d1bdd948ddc5a7f7a9250cf78229b84d.
        System.out.println("testEncryptEmptyPlaintextWithEmptyIv:");
        System.out.println("Encrypt with empty IV:" + TestUtil.bytesToHex(ct));
        System.out.println("Hash subkey          :" + TestUtil.bytesToHex(hashkey));
        fail("Encrypting with an empty IV leaks the hash subkey.");
    } catch (GeneralSecurityException expected) {
        System.out.println("testEncryptWithEmptyIv:" + expected.toString());
    // expected behavior
    }
}
Also used : SecretKeySpec(javax.crypto.spec.SecretKeySpec) GeneralSecurityException(java.security.GeneralSecurityException) Cipher(javax.crypto.Cipher) GCMParameterSpec(javax.crypto.spec.GCMParameterSpec) SlowTest(com.google.security.wycheproof.WycheproofRunner.SlowTest) Test(org.junit.Test) ExcludedTest(com.google.security.wycheproof.WycheproofRunner.ExcludedTest) NoPresubmitTest(com.google.security.wycheproof.WycheproofRunner.NoPresubmitTest) NoPresubmitTest(com.google.security.wycheproof.WycheproofRunner.NoPresubmitTest)

Aggregations

GCMParameterSpec (javax.crypto.spec.GCMParameterSpec)109 Cipher (javax.crypto.Cipher)79 SecretKeySpec (javax.crypto.spec.SecretKeySpec)47 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)35 InvalidAlgorithmParameterException (java.security.InvalidAlgorithmParameterException)32 NoSuchPaddingException (javax.crypto.NoSuchPaddingException)31 InvalidKeyException (java.security.InvalidKeyException)30 BadPaddingException (javax.crypto.BadPaddingException)29 IllegalBlockSizeException (javax.crypto.IllegalBlockSizeException)29 SecretKey (javax.crypto.SecretKey)21 GeneralSecurityException (java.security.GeneralSecurityException)12 AEADBadTagException (javax.crypto.AEADBadTagException)12 Key (java.security.Key)11 ByteBuffer (java.nio.ByteBuffer)7 RequiresApi (androidx.annotation.RequiresApi)6 IOException (java.io.IOException)6 Test (org.junit.Test)6 ExcludedTest (com.google.security.wycheproof.WycheproofRunner.ExcludedTest)5 NoPresubmitTest (com.google.security.wycheproof.WycheproofRunner.NoPresubmitTest)5 SlowTest (com.google.security.wycheproof.WycheproofRunner.SlowTest)5