| /* |
| * 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; |
| } |