blob: 2fdedbf70975ff08d3b5dfa11b05c1d867de4977 [file] [log] [blame]
/*
* 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
*/
syntax = "proto2";
package android_backup_crypto;
option java_package = "com.android.server.backup.encryption.protos";
option java_outer_classname = "ChunksMetadataProto";
// Cipher type with which the chunks are encrypted. For now we only support AES/GCM/NoPadding, but
// this is for backwards-compatibility in case we need to change the default Cipher in the future.
enum CipherType {
UNKNOWN_CIPHER_TYPE = 0;
// Chunk is prefixed with a 12-byte nonce. The tag length is 16 bytes.
AES_256_GCM = 1;
}
// Checksum type with which the plaintext is verified.
enum ChecksumType {
UNKNOWN_CHECKSUM_TYPE = 0;
SHA_256 = 1;
}
enum ChunkOrderingType {
CHUNK_ORDERING_TYPE_UNSPECIFIED = 0;
// The chunk ordering contains a list of the start position of each chunk in the encrypted file,
// ordered as in the plaintext file. This allows us to recreate the original plaintext file
// during decryption. We use this mode for full backups where the order of the data in the file
// is important.
EXPLICIT_STARTS = 1;
// The chunk ordering does not contain any start positions, and instead each encrypted chunk in
// the backup file is prefixed with its length. This allows us to decrypt each chunk but does
// not give any information about the order. However, we use this mode for key value backups
// where the order does not matter.
INLINE_LENGTHS = 2;
}
// Chunk entry (for local state)
message Chunk {
// SHA-256 MAC of the plaintext of the chunk
optional bytes hash = 1;
// Number of bytes in encrypted chunk
optional int32 length = 2;
}
// List of the chunks in the blob, along with the length of each chunk. From this is it possible to
// extract individual chunks. (i.e., start position is equal to the sum of the lengths of all
// preceding chunks.)
//
// This is local state stored on the device. It is never sent to the backup server. See
// ChunkOrdering for how the device restores the chunks in the correct order.
// Next tag : 6
message ChunkListing {
repeated Chunk chunks = 1;
// Cipher algorithm with which the chunks are encrypted.
optional CipherType cipher_type = 2;
// Defines the type of chunk order used to encode the backup file on the server, so that we can
// consistently use the same type between backups. If unspecified this backup file was created
// before INLINE_LENGTHS was supported, thus assume it is EXPLICIT_STARTS.
optional ChunkOrderingType chunk_ordering_type = 5;
// The document ID returned from Scotty server after uploading the blob associated with this
// listing. This needs to be sent when uploading new diff scripts.
optional string document_id = 3;
// Fingerprint mixer salt used for content defined chunking. This is randomly generated for each
// package during the initial non-incremental backup and reused for incremental backups.
optional bytes fingerprint_mixer_salt = 4;
}
// Ordering information about plaintext and checksum. This is used on restore to reconstruct the
// blob in its correct order. (The chunk order is randomized so as to give the server less
// information about which parts of the backup are changing over time.) This proto is encrypted
// before being uploaded to the server, with a key unknown to the server.
message ChunkOrdering {
// For backups where ChunksMetadata#chunk_ordering_type = EXPLICIT STARTS:
// Ordered start positions of chunks. i.e., the file is the chunk starting at this position,
// followed by the chunk starting at this position, followed by ... etc. You can compute the
// lengths of the chunks by sorting this list then looking at the start position of the next
// chunk after the chunk you care about. This is guaranteed to work as all chunks are
// represented in this list.
//
// For backups where ChunksMetadata#chunk_ordering_type = INLINE_LENGTHS:
// This field is unused. See ChunkOrderingType#INLINE_LENGTHS.
repeated int32 starts = 1 [packed = true];
// Checksum of plaintext content. (i.e., in correct order.)
//
// Each chunk also has a MAC, as generated by GCM, so this is NOT Mac-then-Encrypt, which has
// security implications. This is an additional checksum to verify that once the chunks have
// been reordered, that the file matches the expected plaintext. This prevents the device
// restoring garbage data in case of a mismatch between the ChunkOrdering and the backup blob.
optional bytes checksum = 2;
}
// Additional metadata about a backup blob that needs to be synced to the server. This is used on
// restore to reconstruct the blob in its correct order. (The chunk order is randomized so as to
// give the server less information about which parts of the backup are changing over time.) This
// data structure is only ever uploaded to the server encrypted with a key unknown to the server.
// Next tag : 6
message ChunksMetadata {
// Cipher algorithm with which the chunk listing and chunks are encrypted.
optional CipherType cipher_type = 1;
// Defines the type of chunk order this metadata contains. If unspecified this backup file was
// created before INLINE_LENGTHS was supported, thus assume it is EXPLICIT_STARTS.
optional ChunkOrderingType chunk_ordering_type = 5
[default = CHUNK_ORDERING_TYPE_UNSPECIFIED];
// Encrypted bytes of ChunkOrdering
optional bytes chunk_ordering = 2;
// The type of algorithm used for the checksum of the plaintext. (See ChunkOrdering.) This is
// for forwards compatibility in case we change the algorithm in the future. For now, always
// SHA-256.
optional ChecksumType checksum_type = 3;
// This used to be the plaintext tertiary key. No longer used.
reserved 4;
}