1 // Licensed to the Apache Software Foundation (ASF) under one 2 // or more contributor license agreements. See the NOTICE file 3 // distributed with this work for additional information 4 // regarding copyright ownership. The ASF licenses this file 5 // to you under the Apache License, Version 2.0 (the 6 // "License"); you may not use this file except in compliance 7 // with the License. You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, 12 // software distributed under the License is distributed on an 13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 // KIND, either express or implied. See the License for the 15 // specific language governing permissions and limitations 16 // under the License. 17 18 #pragma once 19 20 #include <memory> 21 #include <string> 22 #include <vector> 23 24 #include "parquet/properties.h" 25 #include "parquet/types.h" 26 27 using parquet::ParquetCipher; 28 29 namespace parquet { 30 namespace encryption { 31 32 constexpr int kGcmTagLength = 16; 33 constexpr int kNonceLength = 12; 34 35 // Module types 36 constexpr int8_t kFooter = 0; 37 constexpr int8_t kColumnMetaData = 1; 38 constexpr int8_t kDataPage = 2; 39 constexpr int8_t kDictionaryPage = 3; 40 constexpr int8_t kDataPageHeader = 4; 41 constexpr int8_t kDictionaryPageHeader = 5; 42 constexpr int8_t kColumnIndex = 6; 43 constexpr int8_t kOffsetIndex = 7; 44 45 /// Performs AES encryption operations with GCM or CTR ciphers. 46 class AesEncryptor { 47 public: 48 static AesEncryptor* Make(ParquetCipher::type alg_id, int key_len, bool metadata, 49 std::vector<AesEncryptor*>* all_encryptors); 50 51 ~AesEncryptor(); 52 53 /// Size difference between plaintext and ciphertext, for this cipher. 54 int CiphertextSizeDelta(); 55 56 /// Encrypts plaintext with the key and aad. Key length is passed only for validation. 57 /// If different from value in constructor, exception will be thrown. 58 int Encrypt(const uint8_t* plaintext, int plaintext_len, const uint8_t* key, 59 int key_len, const uint8_t* aad, int aad_len, uint8_t* ciphertext); 60 61 /// Encrypts plaintext footer, in order to compute footer signature (tag). 62 int SignedFooterEncrypt(const uint8_t* footer, int footer_len, const uint8_t* key, 63 int key_len, const uint8_t* aad, int aad_len, 64 const uint8_t* nonce, uint8_t* encrypted_footer); 65 66 void WipeOut(); 67 68 private: 69 /// Can serve one key length only. Possible values: 16, 24, 32 bytes. 70 explicit AesEncryptor(ParquetCipher::type alg_id, int key_len, bool metadata); 71 // PIMPL Idiom 72 class AesEncryptorImpl; 73 std::unique_ptr<AesEncryptorImpl> impl_; 74 }; 75 76 /// Performs AES decryption operations with GCM or CTR ciphers. 77 class AesDecryptor { 78 public: 79 static AesDecryptor* Make(ParquetCipher::type alg_id, int key_len, bool metadata, 80 std::vector<AesDecryptor*>* all_decryptors); 81 82 ~AesDecryptor(); 83 void WipeOut(); 84 85 /// Size difference between plaintext and ciphertext, for this cipher. 86 int CiphertextSizeDelta(); 87 88 /// Decrypts ciphertext with the key and aad. Key length is passed only for 89 /// validation. If different from value in constructor, exception will be thrown. 90 int Decrypt(const uint8_t* ciphertext, int ciphertext_len, const uint8_t* key, 91 int key_len, const uint8_t* aad, int aad_len, uint8_t* plaintext); 92 93 private: 94 /// Can serve one key length only. Possible values: 16, 24, 32 bytes. 95 explicit AesDecryptor(ParquetCipher::type alg_id, int key_len, bool metadata); 96 // PIMPL Idiom 97 class AesDecryptorImpl; 98 std::unique_ptr<AesDecryptorImpl> impl_; 99 }; 100 101 std::string CreateModuleAad(const std::string& file_aad, int8_t module_type, 102 int16_t row_group_ordinal, int16_t column_ordinal, 103 int16_t page_ordinal); 104 105 std::string CreateFooterAad(const std::string& aad_prefix_bytes); 106 107 // Update last two bytes of page (or page header) module AAD 108 void QuickUpdatePageAad(const std::string& AAD, int16_t new_page_ordinal); 109 110 // Wraps OpenSSL RAND_bytes function 111 void RandBytes(unsigned char* buf, int num); 112 113 } // namespace encryption 114 } // namespace parquet 115