Skip to content

Commit 03ede65

Browse files
Gidon Gershinskyggershinsky
authored andcommitted
iv changes and buffer length
1 parent 2d7838e commit 03ede65

File tree

1 file changed

+48
-27
lines changed

1 file changed

+48
-27
lines changed

cpp/src/parquet/util/crypto.cc

Lines changed: 48 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ constexpr int aesCtr = 1;
3535
constexpr int encryptType = 0;
3636
constexpr int decryptType = 1;
3737
constexpr int gcmTagLen = 16;
38-
constexpr int gcmIvLen = 12;
38+
constexpr int nonceLen = 12;
3939
constexpr int ctrIvLen = 16;
40+
constexpr int bufferSizeLen = 4;
4041
constexpr int rndMaxBytes = 32;
4142

4243
#define ENCRYPT_INIT(CTX, ALG) \
@@ -141,8 +142,8 @@ int gcm_encrypt(const uint8_t* plaintext, int plaintext_len, uint8_t* key, int k
141142

142143
uint8_t tag[gcmTagLen];
143144
memset(tag, 0, gcmTagLen);
144-
uint8_t iv[gcmIvLen];
145-
memset(iv, 0, gcmIvLen);
145+
uint8_t iv[nonceLen];
146+
memset(iv, 0, nonceLen);
146147

147148
// Random IV
148149
RAND_load_file("/dev/urandom", rndMaxBytes);
@@ -163,15 +164,15 @@ int gcm_encrypt(const uint8_t* plaintext, int plaintext_len, uint8_t* key, int k
163164
}
164165

165166
// Encryption
166-
if (1 != EVP_EncryptUpdate(cipher.get(), ciphertext + gcmIvLen, &len, plaintext,
167-
plaintext_len)) {
167+
if (1 != EVP_EncryptUpdate(cipher.get(), ciphertext + bufferSizeLen + nonceLen,
168+
&len, plaintext, plaintext_len)) {
168169
throw ParquetException("Failed encryption update");
169170
}
170171

171172
ciphertext_len = len;
172173

173174
// Finalization
174-
if (1 != EVP_EncryptFinal_ex(cipher.get(), ciphertext + gcmIvLen + len, &len)) {
175+
if (1 != EVP_EncryptFinal_ex(cipher.get(), ciphertext + bufferSizeLen + nonceLen + len, &len)) {
175176
throw ParquetException("Failed encryption finalization");
176177
}
177178

@@ -182,11 +183,18 @@ int gcm_encrypt(const uint8_t* plaintext, int plaintext_len, uint8_t* key, int k
182183
throw ParquetException("Couldn't get AES-GCM tag");
183184
}
184185

185-
// Copying the IV and tag to ciphertext
186-
std::copy(iv, iv + gcmIvLen, ciphertext);
187-
std::copy(tag, tag + gcmTagLen, ciphertext + gcmIvLen + ciphertext_len);
188-
189-
return gcmIvLen + ciphertext_len + gcmTagLen;
186+
// Copying the buffer size, IV and tag to ciphertext
187+
int bufferSize = nonceLen + ciphertext_len + gcmTagLen;
188+
uint8_t bufferSizeArray [bufferSizeLen];
189+
bufferSizeArray[3] = 0xff & (bufferSize >> 24);
190+
bufferSizeArray[2] = 0xff & (bufferSize >> 16);
191+
bufferSizeArray[1] = 0xff & (bufferSize >> 8);
192+
bufferSizeArray[0] = 0xff & (bufferSize);
193+
std::copy(bufferSizeArray, bufferSizeArray + bufferSizeLen, ciphertext);
194+
std::copy(iv, iv + nonceLen, ciphertext + bufferSizeLen);
195+
std::copy(tag, tag + gcmTagLen, ciphertext + bufferSizeLen + nonceLen + ciphertext_len);
196+
197+
return bufferSize;
190198
}
191199

192200
int ctr_encrypt(const uint8_t* plaintext, int plaintext_len, uint8_t* key, int key_len,
@@ -196,10 +204,16 @@ int ctr_encrypt(const uint8_t* plaintext, int plaintext_len, uint8_t* key, int k
196204

197205
uint8_t iv[ctrIvLen];
198206
memset(iv, 0, ctrIvLen);
207+
iv[ctrIvLen - 1] = 1;
208+
209+
uint8_t nonce[nonceLen];
210+
memset(iv, 0, nonceLen);
199211

200-
// Random IV
212+
// Random nonce
201213
RAND_load_file("/dev/urandom", rndMaxBytes);
202-
RAND_bytes(iv, sizeof(iv));
214+
RAND_bytes(nonce, sizeof(nonce));
215+
216+
std::copy(nonce, nonce + nonceLen, iv);
203217

204218
// Init cipher context
205219
EvpCipher cipher(aesCtr, key_len, encryptType);
@@ -210,24 +224,31 @@ int ctr_encrypt(const uint8_t* plaintext, int plaintext_len, uint8_t* key, int k
210224
}
211225

212226
// Encryption
213-
if (1 != EVP_EncryptUpdate(cipher.get(), ciphertext + ctrIvLen, &len, plaintext,
227+
if (1 != EVP_EncryptUpdate(cipher.get(), ciphertext + bufferSizeLen + ctrIvLen, &len, plaintext,
214228
plaintext_len)) {
215229
throw ParquetException("Failed encryption update");
216230
}
217231

218232
ciphertext_len = len;
219233

220234
// Finalization
221-
if (1 != EVP_EncryptFinal_ex(cipher.get(), ciphertext + ctrIvLen + len, &len)) {
235+
if (1 != EVP_EncryptFinal_ex(cipher.get(), ciphertext + bufferSizeLen + ctrIvLen + len, &len)) {
222236
throw ParquetException("Failed encryption finalization");
223237
}
224238

225239
ciphertext_len += len;
226240

227-
// Copying the IV ciphertext
228-
std::copy(iv, iv + ctrIvLen, ciphertext);
229-
230-
return ctrIvLen + ciphertext_len;
241+
// Copying the buffer size and IV to ciphertext
242+
int bufferSize = ctrIvLen + ciphertext_len;
243+
uint8_t bufferSizeArray [bufferSizeLen];
244+
bufferSizeArray[3] = 0xff & (bufferSize >> 24);
245+
bufferSizeArray[2] = 0xff & (bufferSize >> 16);
246+
bufferSizeArray[1] = 0xff & (bufferSize >> 8);
247+
bufferSizeArray[0] = 0xff & (bufferSize);
248+
std::copy(bufferSizeArray, bufferSizeArray + bufferSizeLen, ciphertext);
249+
std::copy(iv, iv + ctrIvLen, ciphertext + bufferSizeLen);
250+
251+
return bufferSize;
231252
}
232253

233254
int Encrypt(Encryption::type alg_id, bool metadata, const uint8_t* plaintext,
@@ -262,11 +283,11 @@ int gcm_decrypt(const uint8_t* ciphertext, int ciphertext_len, uint8_t* key, int
262283

263284
uint8_t tag[gcmTagLen];
264285
memset(tag, 0, gcmTagLen);
265-
uint8_t iv[gcmIvLen];
266-
memset(iv, 0, gcmIvLen);
286+
uint8_t iv[nonceLen];
287+
memset(iv, 0, nonceLen);
267288

268289
// Extracting IV and tag
269-
std::copy(ciphertext, ciphertext + gcmIvLen, iv);
290+
std::copy(ciphertext + bufferSizeLen, ciphertext + bufferSizeLen + nonceLen, iv);
270291
std::copy(ciphertext + ciphertext_len - gcmTagLen, ciphertext + ciphertext_len, tag);
271292

272293
// Init cipher context
@@ -284,8 +305,8 @@ int gcm_decrypt(const uint8_t* ciphertext, int ciphertext_len, uint8_t* key, int
284305
}
285306

286307
// Decryption
287-
if (!EVP_DecryptUpdate(cipher.get(), plaintext, &len, ciphertext + gcmIvLen,
288-
ciphertext_len - gcmIvLen - gcmTagLen)) {
308+
if (!EVP_DecryptUpdate(cipher.get(), plaintext, &len, ciphertext + bufferSizeLen + nonceLen,
309+
ciphertext_len - bufferSizeLen - nonceLen - gcmTagLen)) {
289310
throw ParquetException("Failed decryption update");
290311
}
291312

@@ -314,7 +335,7 @@ int ctr_decrypt(const uint8_t* ciphertext, int ciphertext_len, uint8_t* key, int
314335
memset(iv, 0, ctrIvLen);
315336

316337
// Extracting IV and tag
317-
std::copy(ciphertext, ciphertext + ctrIvLen, iv);
338+
std::copy(ciphertext + bufferSizeLen, ciphertext + bufferSizeLen + ctrIvLen, iv);
318339

319340
// Init cipher context
320341
EvpCipher cipher(aesCtr, key_len, decryptType);
@@ -325,8 +346,8 @@ int ctr_decrypt(const uint8_t* ciphertext, int ciphertext_len, uint8_t* key, int
325346
}
326347

327348
// Decryption
328-
if (!EVP_DecryptUpdate(cipher.get(), plaintext, &len, ciphertext + ctrIvLen,
329-
ciphertext_len - ctrIvLen)) {
349+
if (!EVP_DecryptUpdate(cipher.get(), plaintext, &len, ciphertext + bufferSizeLen + ctrIvLen,
350+
ciphertext_len - bufferSizeLen - ctrIvLen)) {
330351
throw ParquetException("Failed decryption update");
331352
}
332353

0 commit comments

Comments
 (0)