Search in sources :

Example 26 with GCMParameterSpec

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

the class JsonAeadTest method getInitializedCipher.

/**
 * Returns an initialized instance of Cipher. Typically it is somewhat
 * time consuming to generate a new instance of Cipher for each encryption.
 * However, some implementations of ciphers (e.g. AES-GCM in jdk) check that
 * the same key and nonce are not reused twice in a row to catch simple
 * programming errors. This precaution can interfere with the tests, since
 * the test vectors do sometimes repeat nonces. To avoid such problems cipher
 * instances are not reused.
 * @param algorithm the cipher algorithm including encryption mode and padding.
 * @param opmode one of Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODE
 * @param key the key bytes
 * @param iv the bytes of the initialization vector
 * @param tagSize the expected size of the tag
 * @return an initialized instance of Cipher
 * @throws Exception if the initialization failed.
 */
protected static Cipher getInitializedCipher(String algorithm, int opmode, byte[] key, byte[] iv, int tagSize) throws Exception {
    Cipher cipher = Cipher.getInstance(algorithm);
    if (algorithm.equalsIgnoreCase("AES/GCM/NoPadding")) {
        SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
        GCMParameterSpec parameters = new GCMParameterSpec(tagSize, iv);
        cipher.init(opmode, keySpec, parameters);
    } else if (algorithm.equalsIgnoreCase("AES/EAX/NoPadding") || algorithm.equalsIgnoreCase("AES/CCM/NoPadding")) {
        SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
        // TODO(bleichen): This works for BouncyCastle but looks non-standard.
        // org.bouncycastle.crypto.params.AEADParameters works too, but would add a dependency that
        // we want to avoid.
        GCMParameterSpec parameters = new GCMParameterSpec(tagSize, iv);
        cipher.init(opmode, keySpec, parameters);
    } else if (algorithm.toUpperCase().startsWith("CHACHA")) {
        SecretKeySpec keySpec = new SecretKeySpec(key, "ChaCha20");
        IvParameterSpec parameters = new IvParameterSpec(iv);
        cipher.init(opmode, keySpec, parameters);
    } else {
        fail("Algorithm not supported:" + algorithm);
    }
    return cipher;
}
Also used : SecretKeySpec(javax.crypto.spec.SecretKeySpec) IvParameterSpec(javax.crypto.spec.IvParameterSpec) Cipher(javax.crypto.Cipher) GCMParameterSpec(javax.crypto.spec.GCMParameterSpec)

Example 27 with GCMParameterSpec

use of javax.crypto.spec.GCMParameterSpec in project secure-quick-reliable-login by kalaspuffar.

the class SQRLStorage method encryptRescueKey.

/**
 * Encrypt the identity key, this has the master key used to login to sites and also the lock
 * key that we supply to the sites in order to lock at a later date if the master key ever
 * gets compromised.
 *
 * @param entropyHarvester  Class to give us new random bits for encryption
 */
public boolean encryptRescueKey(EntropyHarvester entropyHarvester) {
    this.progressionUpdater.clear();
    this.rescueRandomSalt = new byte[16];
    this.rescueLogNFactor = 9;
    this.rescueIdentityUnlockKey = new byte[32];
    this.rescueIdentityUnlockKeyEncrypted = new byte[32];
    this.rescueVerificationTag = new byte[16];
    this.hasRescueBlock = true;
    // 2 min 30 seconds.
    byte rescueCodeEncryptionTime = (byte) 150;
    try {
        entropyHarvester.fetchRandom(this.rescueRandomSalt);
        entropyHarvester.fetchRandom(this.rescueIdentityUnlockKey);
        byte[] encResult = EncryptionUtils.enSCryptTime(getTempRescueCode(), rescueRandomSalt, rescueLogNFactor, 32, rescueCodeEncryptionTime, this.progressionUpdater);
        this.rescueIterationCount = getIntFromFourBytes(encResult, 0);
        byte[] key = Arrays.copyOfRange(encResult, 4, 36);
        byte[] nullBytes = new byte[12];
        Arrays.fill(nullBytes, (byte) 0);
        this.updateRescuePlaintext();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            Key keySpec = new SecretKeySpec(key, "AES");
            Cipher cipher = Cipher.getInstance("AES_256/GCM/NoPadding");
            GCMParameterSpec params = new GCMParameterSpec(128, nullBytes);
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, params);
            cipher.updateAAD(rescuePlaintext);
            cipher.update(rescueIdentityUnlockKey);
            byte[] encryptionResult = cipher.doFinal();
            this.rescueIdentityUnlockKeyEncrypted = Arrays.copyOfRange(encryptionResult, 0, 32);
            this.rescueVerificationTag = Arrays.copyOfRange(encryptionResult, 32, 48);
        } else {
            byte[] resultVerificationTag = new byte[16];
            byte[] encryptionResult = new byte[rescueIdentityUnlockKey.length];
            Grc_aesgcm.gcm_setkey(key, key.length);
            int res = Grc_aesgcm.gcm_encrypt_and_tag(nullBytes, nullBytes.length, rescuePlaintext, rescuePlaintext.length, rescueIdentityUnlockKey, encryptionResult, rescueIdentityUnlockKey.length, resultVerificationTag, resultVerificationTag.length);
            Grc_aesgcm.gcm_zero_ctx();
            if (res == 0x55555555)
                return false;
            this.rescueIdentityUnlockKeyEncrypted = encryptionResult;
            this.rescueVerificationTag = resultVerificationTag;
        }
    } catch (Exception e) {
        Log.e(TAG, e.getMessage(), e);
        return false;
    }
    return true;
}
Also used : SecretKeySpec(javax.crypto.spec.SecretKeySpec) Cipher(javax.crypto.Cipher) GCMParameterSpec(javax.crypto.spec.GCMParameterSpec) Key(java.security.Key) AEADBadTagException(javax.crypto.AEADBadTagException)

Example 28 with GCMParameterSpec

use of javax.crypto.spec.GCMParameterSpec in project secure-quick-reliable-login by kalaspuffar.

the class SQRLStorage method encryptIdentityKeyQuickPass.

/**
 * Encrypt the identity key, this has the master key used to login to sites and also the lock
 * key that we supply to the sites in order to lock at a later date if the master key ever
 * gets compromised.
 *
 * @param password          Password used to encrypt the master key.
 * @param entropyHarvester  Class to give us new random bits for encryption
 */
public boolean encryptIdentityKeyQuickPass(String password, EntropyHarvester entropyHarvester) {
    if (!this.hasKeys() || !this.hasEncryptedKeys())
        return false;
    this.progressionUpdater.clear();
    password = password.substring(0, this.getHintLength());
    this.quickPassRandomSalt = new byte[16];
    this.quickPassInitializationVector = new byte[12];
    this.quickPassKeyEncrypted = new byte[32];
    this.quickPassVerificationTag = new byte[16];
    try {
        entropyHarvester.fetchRandom(this.quickPassRandomSalt);
        byte[] encResult = EncryptionUtils.enSCryptTime(password, this.quickPassRandomSalt, logNFactor, 32, timeInSecondsToRunPWEnScryptOnPassword, this.progressionUpdater);
        this.quickPassIterationCount = getIntFromFourBytes(encResult, 0);
        byte[] key = Arrays.copyOfRange(encResult, 4, 36);
        entropyHarvester.fetchRandom(this.quickPassInitializationVector);
        this.updateIdentityPlaintext();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            Key keySpec = new SecretKeySpec(key, "AES");
            Cipher cipher = Cipher.getInstance("AES_256/GCM/NoPadding");
            GCMParameterSpec params = new GCMParameterSpec(128, this.quickPassInitializationVector);
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, params);
            cipher.update(identityMasterKey);
            byte[] encryptionResult = cipher.doFinal();
            this.quickPassKeyEncrypted = Arrays.copyOfRange(encryptionResult, 0, 32);
            this.quickPassVerificationTag = Arrays.copyOfRange(encryptionResult, 32, 48);
        } else {
            byte[] emptyPlainText = new byte[0];
            Grc_aesgcm.gcm_setkey(key, key.length);
            int res = Grc_aesgcm.gcm_encrypt_and_tag(this.quickPassInitializationVector, this.quickPassInitializationVector.length, emptyPlainText, emptyPlainText.length, identityMasterKey, this.quickPassKeyEncrypted, identityMasterKey.length, this.quickPassVerificationTag, this.quickPassVerificationTag.length);
            Grc_aesgcm.gcm_zero_ctx();
            if (res == 0x55555555)
                return false;
        }
    } catch (Exception e) {
        Log.e(TAG, e.getMessage(), e);
        return false;
    }
    return true;
}
Also used : SecretKeySpec(javax.crypto.spec.SecretKeySpec) Cipher(javax.crypto.Cipher) GCMParameterSpec(javax.crypto.spec.GCMParameterSpec) Key(java.security.Key) AEADBadTagException(javax.crypto.AEADBadTagException)

Example 29 with GCMParameterSpec

use of javax.crypto.spec.GCMParameterSpec in project secure-quick-reliable-login by kalaspuffar.

the class SQRLStorage method decryptUnlockKey.

/**
 * This unlocks the unlock key used to recover your identity if your master key gets comprimised
 * this key should NEVER be saved in the device. It's just used to create a new identity.
 *
 * @param rescueCode    Special rescueCode printed on paper in the format of 0000-0000-0000-0000-0000-0000
 */
public boolean decryptUnlockKey(String rescueCode) {
    this.progressionUpdater.setMax(rescueIterationCount);
    rescueCode = rescueCode.replaceAll("-", "");
    try {
        byte[] key = EncryptionUtils.enSCryptIterations(rescueCode, rescueRandomSalt, rescueLogNFactor, 32, rescueIterationCount, this.progressionUpdater);
        byte[] nullBytes = new byte[12];
        Arrays.fill(nullBytes, (byte) 0);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            Key keySpec = new SecretKeySpec(key, "AES");
            Cipher cipher = Cipher.getInstance("AES_256/GCM/NoPadding");
            GCMParameterSpec params = new GCMParameterSpec(128, nullBytes);
            cipher.init(Cipher.DECRYPT_MODE, keySpec, params);
            cipher.updateAAD(rescuePlaintext);
            cipher.update(rescueIdentityUnlockKeyEncrypted);
            try {
                rescueIdentityUnlockKey = cipher.doFinal(rescueVerificationTag);
            } catch (AEADBadTagException badTag) {
                return false;
            }
        } else {
            rescueIdentityUnlockKey = new byte[rescueIdentityUnlockKeyEncrypted.length];
            Grc_aesgcm.gcm_setkey(key, key.length);
            int res = Grc_aesgcm.gcm_auth_decrypt(nullBytes, nullBytes.length, rescuePlaintext, rescuePlaintext.length, rescueIdentityUnlockKeyEncrypted, rescueIdentityUnlockKey, rescueIdentityUnlockKeyEncrypted.length, rescueVerificationTag, rescueVerificationTag.length);
            Grc_aesgcm.gcm_zero_ctx();
            if (res == 0x55555555)
                return false;
        }
    } catch (Exception e) {
        Log.e(SQRLStorage.TAG, e.getMessage(), e);
        return false;
    }
    return true;
}
Also used : SecretKeySpec(javax.crypto.spec.SecretKeySpec) Cipher(javax.crypto.Cipher) GCMParameterSpec(javax.crypto.spec.GCMParameterSpec) AEADBadTagException(javax.crypto.AEADBadTagException) Key(java.security.Key) AEADBadTagException(javax.crypto.AEADBadTagException)

Example 30 with GCMParameterSpec

use of javax.crypto.spec.GCMParameterSpec in project secure-quick-reliable-login by kalaspuffar.

the class SQRLStorage method decryptPreviousBlock.

private boolean decryptPreviousBlock() {
    try {
        byte[] identityKeys = previousKey1Encrypted;
        if (previousCountOfKeys > 1) {
            identityKeys = EncryptionUtils.combine(identityKeys, previousKey2Encrypted);
        }
        if (previousCountOfKeys > 2) {
            identityKeys = EncryptionUtils.combine(identityKeys, previousKey3Encrypted);
        }
        if (previousCountOfKeys > 3) {
            identityKeys = EncryptionUtils.combine(identityKeys, previousKey4Encrypted);
        }
        byte[] decryptionResult = new byte[identityKeys.length];
        byte[] nullBytes = new byte[12];
        Arrays.fill(nullBytes, (byte) 0);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            Key keySpec = new SecretKeySpec(this.identityMasterKey, "AES");
            Cipher cipher = Cipher.getInstance("AES_256/GCM/NoPadding");
            GCMParameterSpec params = new GCMParameterSpec(128, nullBytes);
            cipher.init(Cipher.DECRYPT_MODE, keySpec, params);
            cipher.updateAAD(previousPlaintext);
            cipher.update(identityKeys);
            try {
                decryptionResult = cipher.doFinal(previousVerificationTag);
            } catch (AEADBadTagException badTag) {
                return false;
            }
        } else {
            Grc_aesgcm.gcm_setkey(this.identityMasterKey, identityMasterKey.length);
            int res = Grc_aesgcm.gcm_auth_decrypt(nullBytes, nullBytes.length, previousPlaintext, previousPlaintext.length, identityKeys, decryptionResult, identityKeys.length, previousVerificationTag, previousVerificationTag.length);
            Grc_aesgcm.gcm_zero_ctx();
            if (res == 0x55555555)
                return false;
        }
        previousKey1 = Arrays.copyOfRange(decryptionResult, 0, 32);
        if (previousCountOfKeys > 1) {
            previousKey2 = Arrays.copyOfRange(decryptionResult, 32, 64);
        }
        if (previousCountOfKeys > 2) {
            previousKey3 = Arrays.copyOfRange(decryptionResult, 64, 96);
        }
        if (previousCountOfKeys > 3) {
            previousKey4 = Arrays.copyOfRange(decryptionResult, 96, 128);
        }
    } catch (Exception e) {
        Log.e(TAG, e.getMessage(), e);
        return false;
    }
    return true;
}
Also used : SecretKeySpec(javax.crypto.spec.SecretKeySpec) Cipher(javax.crypto.Cipher) GCMParameterSpec(javax.crypto.spec.GCMParameterSpec) AEADBadTagException(javax.crypto.AEADBadTagException) Key(java.security.Key) AEADBadTagException(javax.crypto.AEADBadTagException)

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