@@ -142,19 +142,19 @@ int gcm_encrypt(const uint8_t* plaintext, int plaintext_len, uint8_t* key, int k
142
142
143
143
uint8_t tag[gcmTagLen];
144
144
memset (tag, 0 , gcmTagLen);
145
- uint8_t iv [nonceLen];
146
- memset (iv , 0 , nonceLen);
145
+ uint8_t nonce [nonceLen];
146
+ memset (nonce , 0 , nonceLen);
147
147
148
- // Random IV
148
+ // Random nonce
149
149
RAND_load_file (" /dev/urandom" , rndMaxBytes);
150
- RAND_bytes (iv , sizeof (iv ));
150
+ RAND_bytes (nonce , sizeof (nonce ));
151
151
152
152
// Init cipher context
153
153
EvpCipher cipher (aesGcm, key_len, encryptType);
154
154
155
- // Setting key and IV
156
- if (1 != EVP_EncryptInit_ex (cipher.get (), nullptr , nullptr , key, iv )) {
157
- throw ParquetException (" Couldn't set key and IV " );
155
+ // Setting key and IV (nonce)
156
+ if (1 != EVP_EncryptInit_ex (cipher.get (), nullptr , nullptr , key, nonce )) {
157
+ throw ParquetException (" Couldn't set key and nonce " );
158
158
}
159
159
160
160
// Setting additional authenticated data
@@ -183,37 +183,38 @@ int gcm_encrypt(const uint8_t* plaintext, int plaintext_len, uint8_t* key, int k
183
183
throw ParquetException (" Couldn't get AES-GCM tag" );
184
184
}
185
185
186
- // Copying the buffer size, IV and tag to ciphertext
186
+ // Copying the buffer size, nonce and tag to ciphertext
187
187
int bufferSize = nonceLen + ciphertext_len + gcmTagLen;
188
188
uint8_t bufferSizeArray [bufferSizeLen];
189
189
bufferSizeArray[3 ] = 0xff & (bufferSize >> 24 );
190
190
bufferSizeArray[2 ] = 0xff & (bufferSize >> 16 );
191
191
bufferSizeArray[1 ] = 0xff & (bufferSize >> 8 );
192
192
bufferSizeArray[0 ] = 0xff & (bufferSize);
193
193
std::copy (bufferSizeArray, bufferSizeArray + bufferSizeLen, ciphertext);
194
- std::copy (iv, iv + nonceLen, ciphertext + bufferSizeLen);
194
+ std::copy (nonce, nonce + nonceLen, ciphertext + bufferSizeLen);
195
195
std::copy (tag, tag + gcmTagLen, ciphertext + bufferSizeLen + nonceLen + ciphertext_len);
196
196
197
- return bufferSize;
197
+ return bufferSizeLen + bufferSize;
198
198
}
199
199
200
200
int ctr_encrypt (const uint8_t * plaintext, int plaintext_len, uint8_t * key, int key_len,
201
201
uint8_t * ciphertext) {
202
202
int len;
203
203
int ciphertext_len;
204
-
205
- uint8_t iv[ctrIvLen];
206
- memset (iv, 0 , ctrIvLen);
207
- iv[ctrIvLen - 1 ] = 1 ;
208
204
209
205
uint8_t nonce[nonceLen];
210
- memset (iv , 0 , nonceLen);
206
+ memset (nonce , 0 , nonceLen);
211
207
212
208
// Random nonce
213
209
RAND_load_file (" /dev/urandom" , rndMaxBytes);
214
210
RAND_bytes (nonce, sizeof (nonce));
215
-
211
+
212
+ // Parquet CTR IVs are comprised of a 12-byte nonce and a 4-byte initial counter field.
213
+ // The first 31 bits of the initial counter field are set to 0, the last bit is set to 1.
214
+ uint8_t iv[ctrIvLen];
215
+ memset (iv, 0 , ctrIvLen);
216
216
std::copy (nonce, nonce + nonceLen, iv);
217
+ iv[ctrIvLen - 1 ] = 1 ;
217
218
218
219
// Init cipher context
219
220
EvpCipher cipher (aesCtr, key_len, encryptType);
@@ -248,7 +249,7 @@ int ctr_encrypt(const uint8_t* plaintext, int plaintext_len, uint8_t* key, int k
248
249
std::copy (bufferSizeArray, bufferSizeArray + bufferSizeLen, ciphertext);
249
250
std::copy (iv, iv + ctrIvLen, ciphertext + bufferSizeLen);
250
251
251
- return bufferSize;
252
+ return bufferSizeLen + bufferSize;
252
253
}
253
254
254
255
int Encrypt (Encryption::type alg_id, bool metadata, const uint8_t * plaintext,
@@ -283,30 +284,30 @@ int gcm_decrypt(const uint8_t* ciphertext, int ciphertext_len, uint8_t* key, int
283
284
284
285
uint8_t tag[gcmTagLen];
285
286
memset (tag, 0 , gcmTagLen);
286
- uint8_t iv [nonceLen];
287
- memset (iv , 0 , nonceLen);
287
+ uint8_t nonce [nonceLen];
288
+ memset (nonce , 0 , nonceLen);
288
289
289
290
// Extract ciphertext length
290
- int ciphertext_length =
291
+ int written_ciphertext_len =
291
292
((ciphertext[3 ] & 0xff ) << 24 ) |
292
293
((ciphertext[2 ] & 0xff ) << 16 ) |
293
294
((ciphertext[1 ] & 0xff ) << 8 ) |
294
295
((ciphertext[0 ] & 0xff ));
295
296
296
- if (ciphertext_len > 0 && ciphertext_len != ciphertext_length ) {
297
+ if (ciphertext_len > 0 && ciphertext_len != (written_ciphertext_len + bufferSizeLen) ) {
297
298
throw ParquetException (" Wrong ciphertext length" );
298
299
}
299
- ciphertext_len = ciphertext_length ;
300
+ ciphertext_len = written_ciphertext_len + bufferSizeLen ;
300
301
301
302
// Extracting IV and tag
302
- std::copy (ciphertext + bufferSizeLen, ciphertext + bufferSizeLen + nonceLen, iv );
303
+ std::copy (ciphertext + bufferSizeLen, ciphertext + bufferSizeLen + nonceLen, nonce );
303
304
std::copy (ciphertext + ciphertext_len - gcmTagLen, ciphertext + ciphertext_len, tag);
304
305
305
306
// Init cipher context
306
307
EvpCipher cipher (aesGcm, key_len, decryptType);
307
308
308
309
// Setting key and IV
309
- if (1 != EVP_DecryptInit_ex (cipher.get (), nullptr , nullptr , key, iv )) {
310
+ if (1 != EVP_DecryptInit_ex (cipher.get (), nullptr , nullptr , key, nonce )) {
310
311
throw ParquetException (" Couldn't set key and IV" );
311
312
}
312
313
@@ -347,18 +348,18 @@ int ctr_decrypt(const uint8_t* ciphertext, int ciphertext_len, uint8_t* key, int
347
348
memset (iv, 0 , ctrIvLen);
348
349
349
350
// Extract ciphertext length
350
- int ciphertext_length =
351
+ int written_ciphertext_len =
351
352
((ciphertext[3 ] & 0xff ) << 24 ) |
352
353
((ciphertext[2 ] & 0xff ) << 16 ) |
353
354
((ciphertext[1 ] & 0xff ) << 8 ) |
354
355
((ciphertext[0 ] & 0xff ));
355
356
356
- if (ciphertext_len > 0 && ciphertext_len != ciphertext_length ) {
357
+ if (ciphertext_len > 0 && ciphertext_len != (written_ciphertext_len + bufferSizeLen) ) {
357
358
throw ParquetException (" Wrong ciphertext length" );
358
359
}
359
- ciphertext_len = ciphertext_length ;
360
+ ciphertext_len = written_ciphertext_len ;
360
361
361
- // Extracting IV and tag
362
+ // Extracting IV
362
363
std::copy (ciphertext + bufferSizeLen, ciphertext + bufferSizeLen + ctrIvLen, iv);
363
364
364
365
// Init cipher context
@@ -371,7 +372,7 @@ int ctr_decrypt(const uint8_t* ciphertext, int ciphertext_len, uint8_t* key, int
371
372
372
373
// Decryption
373
374
if (!EVP_DecryptUpdate (cipher.get (), plaintext, &len, ciphertext + bufferSizeLen + ctrIvLen,
374
- ciphertext_len - bufferSizeLen - ctrIvLen)) {
375
+ ciphertext_len - ctrIvLen)) {
375
376
throw ParquetException (" Failed decryption update" );
376
377
}
377
378
0 commit comments