| /* |
| * Copyright (C) 2018 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.server.backup.encryption.chunking; |
| |
| import com.android.internal.util.Preconditions; |
| import com.android.server.backup.encryption.chunk.ChunkHash; |
| |
| import java.util.Arrays; |
| import java.util.Objects; |
| |
| /** |
| * A chunk of a file encrypted using AES/GCM. |
| * |
| * <p>TODO(b/116575321): After all code is ported, remove the factory method and rename |
| * encryptedBytes(), key() and nonce(). |
| */ |
| public class EncryptedChunk { |
| public static final int KEY_LENGTH_BYTES = ChunkHash.HASH_LENGTH_BYTES; |
| public static final int NONCE_LENGTH_BYTES = 12; |
| |
| /** |
| * Constructs a new instance with the given key, nonce, and encrypted bytes. |
| * |
| * @param key SHA-256 Hmac of the chunk plaintext. |
| * @param nonce Nonce with which the bytes of the chunk were encrypted. |
| * @param encryptedBytes Encrypted bytes of the chunk. |
| */ |
| public static EncryptedChunk create(ChunkHash key, byte[] nonce, byte[] encryptedBytes) { |
| Preconditions.checkArgument( |
| nonce.length == NONCE_LENGTH_BYTES, "Nonce does not have the correct length."); |
| return new EncryptedChunk(key, nonce, encryptedBytes); |
| } |
| |
| private ChunkHash mKey; |
| private byte[] mNonce; |
| private byte[] mEncryptedBytes; |
| |
| private EncryptedChunk(ChunkHash key, byte[] nonce, byte[] encryptedBytes) { |
| mKey = key; |
| mNonce = nonce; |
| mEncryptedBytes = encryptedBytes; |
| } |
| |
| /** The SHA-256 Hmac of the plaintext bytes of the chunk. */ |
| public ChunkHash key() { |
| return mKey; |
| } |
| |
| /** The nonce with which the chunk was encrypted. */ |
| public byte[] nonce() { |
| return mNonce; |
| } |
| |
| /** The encrypted bytes of the chunk. */ |
| public byte[] encryptedBytes() { |
| return mEncryptedBytes; |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if (this == o) { |
| return true; |
| } |
| if (!(o instanceof EncryptedChunk)) { |
| return false; |
| } |
| |
| EncryptedChunk encryptedChunkOrdering = (EncryptedChunk) o; |
| return Arrays.equals(mEncryptedBytes, encryptedChunkOrdering.mEncryptedBytes) |
| && Arrays.equals(mNonce, encryptedChunkOrdering.mNonce) |
| && mKey.equals(encryptedChunkOrdering.mKey); |
| } |
| |
| @Override |
| public int hashCode() { |
| return Objects.hash(mKey, Arrays.hashCode(mNonce), Arrays.hashCode(mEncryptedBytes)); |
| } |
| } |