Merge "Update language to comply with Android's inclusive language guidance"
This commit is contained in:
@@ -24,8 +24,6 @@ import static com.android.server.backup.UserBackupManagerService.BACKUP_FILE_HEA
|
||||
import static com.android.server.backup.UserBackupManagerService.BACKUP_FILE_VERSION;
|
||||
import static com.android.server.backup.UserBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
|
||||
|
||||
import android.app.backup.BackupManager;
|
||||
import android.app.backup.BackupManager.OperationType;
|
||||
import android.app.backup.IFullBackupRestoreObserver;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
@@ -143,7 +141,7 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor
|
||||
|
||||
private OutputStream emitAesBackupHeader(StringBuilder headerbuf,
|
||||
OutputStream ofstream) throws Exception {
|
||||
// User key will be used to encrypt the master key.
|
||||
// User key will be used to encrypt the encryption key.
|
||||
byte[] newUserSalt = mUserBackupManagerService
|
||||
.randomBytes(PasswordUtils.PBKDF2_SALT_SIZE);
|
||||
SecretKey userKey = PasswordUtils
|
||||
@@ -151,16 +149,16 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor
|
||||
newUserSalt,
|
||||
PasswordUtils.PBKDF2_HASH_ROUNDS);
|
||||
|
||||
// the master key is random for each backup
|
||||
byte[] masterPw = new byte[256 / 8];
|
||||
mUserBackupManagerService.getRng().nextBytes(masterPw);
|
||||
// the encryption key is random for each backup
|
||||
byte[] encryptionKey = new byte[256 / 8];
|
||||
mUserBackupManagerService.getRng().nextBytes(encryptionKey);
|
||||
byte[] checksumSalt = mUserBackupManagerService
|
||||
.randomBytes(PasswordUtils.PBKDF2_SALT_SIZE);
|
||||
|
||||
// primary encryption of the datastream with the random key
|
||||
// primary encryption of the datastream with the encryption key
|
||||
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
SecretKeySpec masterKeySpec = new SecretKeySpec(masterPw, "AES");
|
||||
c.init(Cipher.ENCRYPT_MODE, masterKeySpec);
|
||||
SecretKeySpec encryptionKeySpec = new SecretKeySpec(encryptionKey, "AES");
|
||||
c.init(Cipher.ENCRYPT_MODE, encryptionKeySpec);
|
||||
OutputStream finalOutput = new CipherOutputStream(ofstream, c);
|
||||
|
||||
// line 4: name of encryption algorithm
|
||||
@@ -169,7 +167,7 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor
|
||||
// line 5: user password salt [hex]
|
||||
headerbuf.append(PasswordUtils.byteArrayToHex(newUserSalt));
|
||||
headerbuf.append('\n');
|
||||
// line 6: master key checksum salt [hex]
|
||||
// line 6: encryption key checksum salt [hex]
|
||||
headerbuf.append(PasswordUtils.byteArrayToHex(checksumSalt));
|
||||
headerbuf.append('\n');
|
||||
// line 7: number of PBKDF2 rounds used [decimal]
|
||||
@@ -184,21 +182,21 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor
|
||||
headerbuf.append(PasswordUtils.byteArrayToHex(IV));
|
||||
headerbuf.append('\n');
|
||||
|
||||
// line 9: master IV + key blob, encrypted by the user key [hex]. Blob format:
|
||||
// line 9: encryption IV + key blob, encrypted by the user key [hex]. Blob format:
|
||||
// [byte] IV length = Niv
|
||||
// [array of Niv bytes] IV itself
|
||||
// [byte] master key length = Nmk
|
||||
// [array of Nmk bytes] master key itself
|
||||
// [byte] MK checksum hash length = Nck
|
||||
// [array of Nck bytes] master key checksum hash
|
||||
// [byte] encryption key length = Nek
|
||||
// [array of Nek bytes] encryption key itself
|
||||
// [byte] encryption key checksum hash length = Nck
|
||||
// [array of Nck bytes] encryption key checksum hash
|
||||
//
|
||||
// The checksum is the (master key + checksum salt), run through the
|
||||
// The checksum is the (encryption key + checksum salt), run through the
|
||||
// stated number of PBKDF2 rounds
|
||||
IV = c.getIV();
|
||||
byte[] mk = masterKeySpec.getEncoded();
|
||||
byte[] mk = encryptionKeySpec.getEncoded();
|
||||
byte[] checksum = PasswordUtils
|
||||
.makeKeyChecksum(PBKDF_CURRENT,
|
||||
masterKeySpec.getEncoded(),
|
||||
encryptionKeySpec.getEncoded(),
|
||||
checksumSalt, PasswordUtils.PBKDF2_HASH_ROUNDS);
|
||||
|
||||
ByteArrayOutputStream blob = new ByteArrayOutputStream(IV.length + mk.length
|
||||
@@ -347,15 +345,15 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor
|
||||
// When line 4 is not "none", then additional header data follows:
|
||||
//
|
||||
// line 5: user password salt [hex]
|
||||
// line 6: master key checksum salt [hex]
|
||||
// line 7: number of PBKDF2 rounds to use (same for user & master) [decimal]
|
||||
// line 6: encryption key checksum salt [hex]
|
||||
// line 7: number of PBKDF2 rounds to use (same for user & encryption key) [decimal]
|
||||
// line 8: IV of the user key [hex]
|
||||
// line 9: master key blob [hex]
|
||||
// IV of the master key, master key itself, master key checksum hash
|
||||
// line 9: encryption key blob [hex]
|
||||
// IV of the encryption key, encryption key itself, encryption key checksum hash
|
||||
//
|
||||
// The master key checksum is the master key plus its checksum salt, run through
|
||||
// The encryption key checksum is the encryption key plus its checksum salt, run through
|
||||
// 10k rounds of PBKDF2. This is used to verify that the user has supplied the
|
||||
// correct password for decrypting the archive: the master key decrypted from
|
||||
// correct password for decrypting the archive: the encryption key decrypted from
|
||||
// the archive using the user-supplied password is also run through PBKDF2 in
|
||||
// this way, and if the result does not match the checksum as stored in the
|
||||
// archive, then we know that the user-supplied password does not match the
|
||||
|
||||
@@ -212,10 +212,9 @@ public class PerformAdbRestoreTask implements Runnable {
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
private static InputStream attemptMasterKeyDecryption(String decryptPassword, String algorithm,
|
||||
byte[] userSalt, byte[] ckSalt,
|
||||
int rounds, String userIvHex, String masterKeyBlobHex, InputStream rawInStream,
|
||||
boolean doLog) {
|
||||
private static InputStream attemptEncryptionKeyDecryption(String decryptPassword,
|
||||
String algorithm, byte[] userSalt, byte[] ckSalt, int rounds, String userIvHex,
|
||||
String encryptionKeyBlobHex, InputStream rawInStream, boolean doLog) {
|
||||
InputStream result = null;
|
||||
|
||||
try {
|
||||
@@ -228,31 +227,31 @@ public class PerformAdbRestoreTask implements Runnable {
|
||||
c.init(Cipher.DECRYPT_MODE,
|
||||
new SecretKeySpec(userKey.getEncoded(), "AES"),
|
||||
ivSpec);
|
||||
byte[] mkCipher = PasswordUtils.hexToByteArray(masterKeyBlobHex);
|
||||
byte[] mkCipher = PasswordUtils.hexToByteArray(encryptionKeyBlobHex);
|
||||
byte[] mkBlob = c.doFinal(mkCipher);
|
||||
|
||||
// first, the master key IV
|
||||
// first, the encryption key IV
|
||||
int offset = 0;
|
||||
int len = mkBlob[offset++];
|
||||
IV = Arrays.copyOfRange(mkBlob, offset, offset + len);
|
||||
offset += len;
|
||||
// then the master key itself
|
||||
// then the encryption key itself
|
||||
len = mkBlob[offset++];
|
||||
byte[] mk = Arrays.copyOfRange(mkBlob,
|
||||
byte[] encryptionKey = Arrays.copyOfRange(mkBlob,
|
||||
offset, offset + len);
|
||||
offset += len;
|
||||
// and finally the master key checksum hash
|
||||
// and finally the encryption key checksum hash
|
||||
len = mkBlob[offset++];
|
||||
byte[] mkChecksum = Arrays.copyOfRange(mkBlob,
|
||||
offset, offset + len);
|
||||
|
||||
// now validate the decrypted master key against the checksum
|
||||
byte[] calculatedCk = PasswordUtils.makeKeyChecksum(algorithm, mk, ckSalt,
|
||||
// now validate the decrypted encryption key against the checksum
|
||||
byte[] calculatedCk = PasswordUtils.makeKeyChecksum(algorithm, encryptionKey, ckSalt,
|
||||
rounds);
|
||||
if (Arrays.equals(calculatedCk, mkChecksum)) {
|
||||
ivSpec = new IvParameterSpec(IV);
|
||||
c.init(Cipher.DECRYPT_MODE,
|
||||
new SecretKeySpec(mk, "AES"),
|
||||
new SecretKeySpec(encryptionKey, "AES"),
|
||||
ivSpec);
|
||||
// Only if all of the above worked properly will 'result' be assigned
|
||||
result = new CipherInputStream(rawInStream, c);
|
||||
@@ -265,7 +264,7 @@ public class PerformAdbRestoreTask implements Runnable {
|
||||
}
|
||||
} catch (BadPaddingException e) {
|
||||
// This case frequently occurs when the wrong password is used to decrypt
|
||||
// the master key. Use the identical "incorrect password" log text as is
|
||||
// the encryption key. Use the identical "incorrect password" log text as is
|
||||
// used in the checksum failure log in order to avoid providing additional
|
||||
// information to an attacker.
|
||||
if (doLog) {
|
||||
@@ -273,7 +272,7 @@ public class PerformAdbRestoreTask implements Runnable {
|
||||
}
|
||||
} catch (IllegalBlockSizeException e) {
|
||||
if (doLog) {
|
||||
Slog.w(TAG, "Invalid block size in master key");
|
||||
Slog.w(TAG, "Invalid block size in encryption key");
|
||||
}
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
if (doLog) {
|
||||
@@ -309,15 +308,15 @@ public class PerformAdbRestoreTask implements Runnable {
|
||||
int rounds = Integer.parseInt(readHeaderLine(rawInStream)); // 7
|
||||
String userIvHex = readHeaderLine(rawInStream); // 8
|
||||
|
||||
String masterKeyBlobHex = readHeaderLine(rawInStream); // 9
|
||||
String encryptionKeyBlobHex = readHeaderLine(rawInStream); // 9
|
||||
|
||||
// decrypt the master key blob
|
||||
result = attemptMasterKeyDecryption(decryptPassword, PBKDF_CURRENT,
|
||||
userSalt, ckSalt, rounds, userIvHex, masterKeyBlobHex, rawInStream, false);
|
||||
// decrypt the encryption key blob
|
||||
result = attemptEncryptionKeyDecryption(decryptPassword, PBKDF_CURRENT, userSalt,
|
||||
ckSalt, rounds, userIvHex, encryptionKeyBlobHex, rawInStream, false);
|
||||
if (result == null && pbkdf2Fallback) {
|
||||
result = attemptMasterKeyDecryption(
|
||||
result = attemptEncryptionKeyDecryption(
|
||||
decryptPassword, PBKDF_FALLBACK, userSalt, ckSalt,
|
||||
rounds, userIvHex, masterKeyBlobHex, rawInStream, true);
|
||||
rounds, userIvHex, encryptionKeyBlobHex, rawInStream, true);
|
||||
}
|
||||
} else {
|
||||
Slog.w(TAG, "Unsupported encryption method: " + encryptionName);
|
||||
|
||||
Reference in New Issue
Block a user