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