Skip to content

Commit da83589

Browse files
authored
Merge 068dbf7 into d2ecf39
2 parents d2ecf39 + 068dbf7 commit da83589

File tree

10 files changed

+1444
-5
lines changed

10 files changed

+1444
-5
lines changed

ydb/core/backup/common/encryption.cpp

Lines changed: 873 additions & 0 deletions
Large diffs are not rendered by default.

ydb/core/backup/common/encryption.h

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
#pragma once
2+
3+
#include <ydb/library/yverify_stream/yverify_stream.h>
4+
5+
#include <util/generic/buffer.h>
6+
#include <util/generic/maybe.h>
7+
#include <util/generic/string.h>
8+
9+
#include <vector>
10+
11+
namespace NKikimr::NBackup {
12+
13+
// Backup file type.
14+
// Must be different for all files in one backup item folder.
15+
// Must suit to one byte.
16+
enum class EBackupFileType : unsigned char {
17+
Metadata = 0,
18+
Permissions,
19+
Schema,
20+
Data,
21+
};
22+
23+
struct TEncryptionIV {
24+
TEncryptionIV() = default; // Uninitialized IV
25+
TEncryptionIV(const TEncryptionIV&) = default;
26+
TEncryptionIV(TEncryptionIV&&) = default;
27+
28+
TEncryptionIV& operator=(const TEncryptionIV&) = default;
29+
TEncryptionIV& operator=(TEncryptionIV&&) = default;
30+
31+
// Generate new random IV
32+
static TEncryptionIV Generate();
33+
34+
// Combine IV for backup item file
35+
// base: base IV for the whole backup
36+
// backupItemNumber: unique backup item number within backup
37+
// shardNumber (only for sharded backup items such as tables): datashard number
38+
static TEncryptionIV Combine(const TEncryptionIV& base, EBackupFileType fileType, uint32_t backupItemNumber, uint32_t shardNumber);
39+
40+
// Combine IV for specific chunk
41+
// fileIV: IV for backup item file got by Combine() function
42+
static TEncryptionIV CombineForChunk(const TEncryptionIV& fileIV, uint32_t chunkNumber);
43+
44+
static TEncryptionIV FromBinaryString(const TString& s);
45+
46+
operator bool() const {
47+
return !IV.empty();
48+
}
49+
50+
bool operator!() const {
51+
return IV.empty();
52+
}
53+
54+
bool operator==(const TEncryptionIV& iv) const {
55+
return IV == iv.IV;
56+
}
57+
58+
bool operator!=(const TEncryptionIV& iv) const {
59+
return IV != iv.IV;
60+
}
61+
62+
size_t Size() const {
63+
return IV.size();
64+
}
65+
66+
const unsigned char* Ptr() const {
67+
Y_VERIFY(!IV.empty());
68+
return &IV[0];
69+
}
70+
71+
TString GetHexString() const;
72+
TString GetBinaryString() const;
73+
74+
std::vector<unsigned char> IV;
75+
76+
// Proper size for ciphers used in backups
77+
static constexpr size_t SIZE = 12;
78+
79+
static constexpr size_t FILE_TYPE_OFFSET = 0;
80+
static constexpr size_t FILE_TYPE_SIZE = 1;
81+
82+
static constexpr size_t BACKUP_ITEM_OFFSET = FILE_TYPE_OFFSET + FILE_TYPE_SIZE;
83+
static constexpr size_t BACKUP_ITEM_SIZE = 3;
84+
static constexpr uint32_t MAX_BACKUP_ITEM_NUMBER = (1 << (8 * BACKUP_ITEM_SIZE));
85+
86+
static constexpr size_t SHARD_NUMBER_OFFSET = BACKUP_ITEM_OFFSET + BACKUP_ITEM_SIZE;
87+
static constexpr size_t SHARD_NUMBER_SIZE = 4;
88+
89+
static constexpr size_t CHUNK_NUMBER_OFFSET = SHARD_NUMBER_OFFSET + SHARD_NUMBER_SIZE;
90+
static constexpr size_t CHUNK_NUMBER_SIZE = 4;
91+
92+
static_assert(CHUNK_NUMBER_OFFSET + CHUNK_NUMBER_SIZE == SIZE);
93+
};
94+
95+
struct TEncryptionKey {
96+
TEncryptionKey() = default; // Uninitialized
97+
TEncryptionKey(const TEncryptionKey&) = default;
98+
TEncryptionKey(TEncryptionKey&&) = default;
99+
explicit TEncryptionKey(const TString& bytes)
100+
: Key(reinterpret_cast<const unsigned char*>(bytes.data()), reinterpret_cast<const unsigned char*>(bytes.data() + bytes.size()))
101+
{
102+
}
103+
104+
TEncryptionKey& operator=(const TEncryptionKey&) = default;
105+
TEncryptionKey& operator=(TEncryptionKey&&) = default;
106+
107+
operator bool() const {
108+
return !Key.empty();
109+
}
110+
111+
bool operator!() const {
112+
return Key.empty();
113+
}
114+
115+
size_t Size() const {
116+
return Key.size();
117+
}
118+
119+
const unsigned char* Ptr() const {
120+
Y_VERIFY(!Key.empty());
121+
return &Key[0];
122+
}
123+
124+
TString GetBinaryString() const;
125+
126+
std::vector<unsigned char> Key;
127+
};
128+
129+
// Class that writes encrypted file
130+
// Has streaming interface
131+
class TEncryptedFileSerializer {
132+
public:
133+
TEncryptedFileSerializer(TEncryptedFileSerializer&&) = default;
134+
TEncryptedFileSerializer(TString algorithm, TEncryptionKey key, TEncryptionIV iv);
135+
~TEncryptedFileSerializer();
136+
137+
// Streaming interface
138+
// File consists of blocks that contain MAC
139+
// Block size should not be too big
140+
// because whole block must be read before usage.
141+
TBuffer AddBlock(TStringBuf data, bool last);
142+
143+
// Helper that serializes the whole file at one time
144+
static TBuffer EncryptFile(TString algorithm, TEncryptionKey key, TEncryptionIV iv, TStringBuf data);
145+
146+
private:
147+
class TImpl;
148+
std::unique_ptr<TImpl> Impl;
149+
};
150+
151+
// Class that reads encrypted file
152+
// Has streaming interface
153+
class TEncryptedFileDeserializer {
154+
TEncryptedFileDeserializer();
155+
156+
public:
157+
TEncryptedFileDeserializer(TEncryptedFileDeserializer&&) = default;
158+
TEncryptedFileDeserializer(TEncryptionKey key); // Decrypt file with key. Take IV from file header.
159+
TEncryptedFileDeserializer(TEncryptionKey key, TEncryptionIV expectedIV); // Decrypt file with key. Check that IV in header is equal to expectedIV
160+
~TEncryptedFileDeserializer();
161+
162+
// Adds buffer with input data.
163+
void AddData(TBuffer data, bool last);
164+
165+
// Decrypts next block from previously added data.
166+
// Throws in case of error.
167+
// Returns Nothing if not enough data added.
168+
// Returns buffer with data in normal case.
169+
TMaybe<TBuffer> GetNextBlock();
170+
171+
// Store state
172+
TString GetState() const;
173+
174+
// Restore from state
175+
// State includes secret key
176+
static TEncryptedFileDeserializer RestoreFromState(const TString& state);
177+
178+
// Get file IV.
179+
// Must be called after data added enough for the file header.
180+
TEncryptionIV GetIV() const;
181+
182+
// Get input bytes read
183+
size_t GetProcessedInputBytes() const;
184+
185+
// Helper that deserializes the whole file at one time
186+
static std::pair<TBuffer, TEncryptionIV> DecryptFile(TEncryptionKey key, TBuffer data);
187+
static TBuffer DecryptFile(TEncryptionKey key, TEncryptionIV expectedIV, TBuffer data);
188+
189+
private:
190+
class TImpl;
191+
std::unique_ptr<TImpl> Impl;
192+
};
193+
194+
} // NKikimr::NBackup

0 commit comments

Comments
 (0)