1/* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17syntax = "proto2"; 18 19package android_backup_crypto; 20 21option java_package = "com.android.server.backup.encryption.protos"; 22option java_outer_classname = "ChunksMetadataProto"; 23 24// Cipher type with which the chunks are encrypted. For now we only support AES/GCM/NoPadding, but 25// this is for backwards-compatibility in case we need to change the default Cipher in the future. 26enum CipherType { 27 UNKNOWN_CIPHER_TYPE = 0; 28 // Chunk is prefixed with a 12-byte nonce. The tag length is 16 bytes. 29 AES_256_GCM = 1; 30} 31 32// Checksum type with which the plaintext is verified. 33enum ChecksumType { 34 UNKNOWN_CHECKSUM_TYPE = 0; 35 SHA_256 = 1; 36} 37 38enum ChunkOrderingType { 39 CHUNK_ORDERING_TYPE_UNSPECIFIED = 0; 40 // The chunk ordering contains a list of the start position of each chunk in the encrypted file, 41 // ordered as in the plaintext file. This allows us to recreate the original plaintext file 42 // during decryption. We use this mode for full backups where the order of the data in the file 43 // is important. 44 EXPLICIT_STARTS = 1; 45 // The chunk ordering does not contain any start positions, and instead each encrypted chunk in 46 // the backup file is prefixed with its length. This allows us to decrypt each chunk but does 47 // not give any information about the order. However, we use this mode for key value backups 48 // where the order does not matter. 49 INLINE_LENGTHS = 2; 50} 51 52// Chunk entry (for local state) 53message Chunk { 54 // SHA-256 MAC of the plaintext of the chunk 55 optional bytes hash = 1; 56 // Number of bytes in encrypted chunk 57 optional int32 length = 2; 58} 59 60// List of the chunks in the blob, along with the length of each chunk. From this is it possible to 61// extract individual chunks. (i.e., start position is equal to the sum of the lengths of all 62// preceding chunks.) 63// 64// This is local state stored on the device. It is never sent to the backup server. See 65// ChunkOrdering for how the device restores the chunks in the correct order. 66// Next tag : 6 67message ChunkListing { 68 repeated Chunk chunks = 1; 69 70 // Cipher algorithm with which the chunks are encrypted. 71 optional CipherType cipher_type = 2; 72 73 // Defines the type of chunk order used to encode the backup file on the server, so that we can 74 // consistently use the same type between backups. If unspecified this backup file was created 75 // before INLINE_LENGTHS was supported, thus assume it is EXPLICIT_STARTS. 76 optional ChunkOrderingType chunk_ordering_type = 5; 77 78 // The document ID returned from Scotty server after uploading the blob associated with this 79 // listing. This needs to be sent when uploading new diff scripts. 80 optional string document_id = 3; 81 82 // Fingerprint mixer salt used for content defined chunking. This is randomly generated for each 83 // package during the initial non-incremental backup and reused for incremental backups. 84 optional bytes fingerprint_mixer_salt = 4; 85} 86 87// Ordering information about plaintext and checksum. This is used on restore to reconstruct the 88// blob in its correct order. (The chunk order is randomized so as to give the server less 89// information about which parts of the backup are changing over time.) This proto is encrypted 90// before being uploaded to the server, with a key unknown to the server. 91message ChunkOrdering { 92 // For backups where ChunksMetadata#chunk_ordering_type = EXPLICIT STARTS: 93 // Ordered start positions of chunks. i.e., the file is the chunk starting at this position, 94 // followed by the chunk starting at this position, followed by ... etc. You can compute the 95 // lengths of the chunks by sorting this list then looking at the start position of the next 96 // chunk after the chunk you care about. This is guaranteed to work as all chunks are 97 // represented in this list. 98 // 99 // For backups where ChunksMetadata#chunk_ordering_type = INLINE_LENGTHS: 100 // This field is unused. See ChunkOrderingType#INLINE_LENGTHS. 101 repeated int32 starts = 1 [packed = true]; 102 103 // Checksum of plaintext content. (i.e., in correct order.) 104 // 105 // Each chunk also has a MAC, as generated by GCM, so this is NOT Mac-then-Encrypt, which has 106 // security implications. This is an additional checksum to verify that once the chunks have 107 // been reordered, that the file matches the expected plaintext. This prevents the device 108 // restoring garbage data in case of a mismatch between the ChunkOrdering and the backup blob. 109 optional bytes checksum = 2; 110} 111 112// Additional metadata about a backup blob that needs to be synced to the server. This is used on 113// restore to reconstruct the blob in its correct order. (The chunk order is randomized so as to 114// give the server less information about which parts of the backup are changing over time.) This 115// data structure is only ever uploaded to the server encrypted with a key unknown to the server. 116// Next tag : 6 117message ChunksMetadata { 118 // Cipher algorithm with which the chunk listing and chunks are encrypted. 119 optional CipherType cipher_type = 1; 120 121 // Defines the type of chunk order this metadata contains. If unspecified this backup file was 122 // created before INLINE_LENGTHS was supported, thus assume it is EXPLICIT_STARTS. 123 optional ChunkOrderingType chunk_ordering_type = 5 124 [default = CHUNK_ORDERING_TYPE_UNSPECIFIED]; 125 126 // Encrypted bytes of ChunkOrdering 127 optional bytes chunk_ordering = 2; 128 129 // The type of algorithm used for the checksum of the plaintext. (See ChunkOrdering.) This is 130 // for forwards compatibility in case we change the algorithm in the future. For now, always 131 // SHA-256. 132 optional ChecksumType checksum_type = 3; 133 134 // This used to be the plaintext tertiary key. No longer used. 135 reserved 4; 136}