1 // Copyright 2017 Google Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 /////////////////////////////////////////////////////////////////////////////// 16 17 #ifndef TINK_SUBTLE_AES_EAX_BORINGSSL_H_ 18 #define TINK_SUBTLE_AES_EAX_BORINGSSL_H_ 19 20 #include <array> 21 #include <memory> 22 #include <string> 23 #include <utility> 24 25 #include "absl/strings/string_view.h" 26 #include "absl/types/span.h" 27 #include "openssl/aes.h" 28 #include "openssl/evp.h" 29 #include "tink/aead.h" 30 #include "tink/internal/fips_utils.h" 31 #include "tink/util/secret_data.h" 32 #include "tink/util/status.h" 33 #include "tink/util/statusor.h" 34 35 namespace crypto { 36 namespace tink { 37 namespace subtle { 38 39 class AesEaxBoringSsl : public Aead { 40 public: 41 // Constructs a new Aead cipher for Aes-EAX. 42 // Currently supported key sizes are 128 and 256 bits. 43 // Currently supported nonce sizes are 12 and 16 bytes. 44 // The tag size is fixed to 16 bytes. 45 static crypto::tink::util::StatusOr<std::unique_ptr<Aead>> New( 46 const util::SecretData& key, size_t nonce_size_in_bytes); 47 48 crypto::tink::util::StatusOr<std::string> Encrypt( 49 absl::string_view plaintext, 50 absl::string_view associated_data) const override; 51 52 crypto::tink::util::StatusOr<std::string> Decrypt( 53 absl::string_view ciphertext, 54 absl::string_view associated_data) const override; 55 56 static constexpr crypto::tink::internal::FipsCompatibility kFipsStatus = 57 crypto::tink::internal::FipsCompatibility::kNotFips; 58 59 private: 60 static constexpr int kTagSize = 16; 61 static constexpr int kBlockSize = 16; 62 63 using Block = std::array<uint8_t, kBlockSize>; 64 AesEaxBoringSsl(util::SecretUniquePtr<AES_KEY> aeskey,size_t nonce_size)65 AesEaxBoringSsl(util::SecretUniquePtr<AES_KEY> aeskey, size_t nonce_size) 66 : aeskey_(std::move(aeskey)), 67 nonce_size_(nonce_size), 68 B_(ComputeB()), 69 P_(ComputeP()) {} 70 71 // Precomputes block B. Requires aeskey_ to be initialized. 72 util::SecretData ComputeB() const; 73 // Precomputes block P. Requires aeskey_ and B_ to be initialized. 74 util::SecretData ComputeP() const; 75 76 // Returns whether key_size_in_bytes is a supported key size. 77 static bool IsValidKeySize(size_t key_size_in_bytes); 78 79 // Returns whether nonce_size_in_bytes is a supported size for the nonce. 80 static bool IsValidNonceSize(size_t nonce_size_in_bytes); 81 82 // XORs block x with block y. 83 // Result is: y = x ^ y 84 static void XorBlock(const uint8_t x[kBlockSize], Block* y); 85 86 // Multiplies in by X and stores result in out. 87 static void MultiplyByX(const uint8_t in[kBlockSize], 88 uint8_t out[kBlockSize]); 89 90 // Constant-time block equality 91 static bool EqualBlocks(const uint8_t x[kBlockSize], 92 const uint8_t y[kBlockSize]); 93 94 // Encrypts a single block with AES. 95 void EncryptBlock(Block* block) const; 96 void EncryptBlock(util::SecretData* block) const; 97 98 // Pads a partial data block of size 0 <= len <= kBlockSize. 99 Block Pad(absl::Span<const uint8_t> data) const; 100 101 // Computes a Omac over blob. 102 // tag is either 0, 1 or 2, depending over which value (nonce, aad, message) 103 // the Omac is computed. 104 Block Omac(absl::string_view blob, int tag) const; 105 106 // This is the same function as above with the difference that the blob 107 // is represented by a pointer and its length. 108 Block Omac(absl::Span<const uint8_t> data, int tag) const; 109 110 // Encrypts or decrypts some data using CTR mode. `N` is the 16 bytes result 111 // of an OMAC computation over the nonce. `in` are the bytes that are 112 // encrypted or decrypted, and the result is written to `out`. `in`.data() 113 // MUST NOT be null. 114 crypto::tink::util::Status CtrCrypt(const Block& N, absl::string_view in, 115 absl::Span<char> out) const; 116 117 const util::SecretUniquePtr<AES_KEY> aeskey_; 118 const size_t nonce_size_; 119 const util::SecretData B_; 120 const util::SecretData P_; 121 }; 122 123 } // namespace subtle 124 } // namespace tink 125 } // namespace crypto 126 127 #endif // TINK_SUBTLE_AES_EAX_BORINGSSL_H_ 128