1 // Copyright 2022 Google LLC 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_MAC_AES_CMAC_PARAMETERS_H_ 18 #define TINK_MAC_AES_CMAC_PARAMETERS_H_ 19 20 #include <memory> 21 22 #include "tink/mac/mac_parameters.h" 23 #include "tink/util/statusor.h" 24 25 namespace crypto { 26 namespace tink { 27 28 // Describes the parameters of an `AesCmacKey`. 29 class AesCmacParameters : public MacParameters { 30 public: 31 // Describes the details of a MAC computation. 32 // 33 // The usual AES-CMAC key is used for variant `NO_PREFIX`. Other variants 34 // slightly change how the MAC is computed, or add a prefix to every 35 // computation depending on the key id. 36 enum class Variant : int { 37 // Prepends '0x01<big endian key id>' to tag. 38 kTink = 1, 39 // Prepends '0x00<big endian key id>' to tag. 40 kCrunchy = 2, 41 // Appends a 0-byte to input message BEFORE computing the tag, then 42 // prepends '0x00<big endian key id>' to tag. 43 kLegacy = 3, 44 // Does not prepend any prefix (i.e., keys must have no ID requirement). 45 kNoPrefix = 4, 46 // Added to guard from failures that may be caused by future expansions. 47 kDoNotUseInsteadUseDefaultWhenWritingSwitchStatements = 20, 48 }; 49 50 // Copyable and movable. 51 AesCmacParameters(const AesCmacParameters& other) = default; 52 AesCmacParameters& operator=(const AesCmacParameters& other) = default; 53 AesCmacParameters(AesCmacParameters&& other) = default; 54 AesCmacParameters& operator=(AesCmacParameters&& other) = default; 55 56 // Creates a new AES-CMAC parameters object unless an error occurs. An error 57 // occurs under one of the following conditions: 58 // 1. `key_size_in_bytes` is a value other than 16 or 32 59 // 2. `cryptographic_tag_size_in_bytes` falls outside [10,...,16] 60 static util::StatusOr<AesCmacParameters> Create( 61 int key_size_in_bytes, int cryptographic_tag_size_in_bytes, 62 Variant variant); 63 GetVariant()64 Variant GetVariant() const { return variant_; } 65 KeySizeInBytes()66 int KeySizeInBytes() const { return key_size_in_bytes_; } 67 68 // Returns the size of the tag, which is computed cryptographically from the 69 // message. Note that this may differ from the total size of the tag, as for 70 // some keys, Tink prefixes the tag with a key dependent output prefix. CryptographicTagSizeInBytes()71 int CryptographicTagSizeInBytes() const { 72 return cryptographic_tag_size_in_bytes_; 73 } 74 75 // Returns the size of the cryptographic tag plus the size of the prefix with 76 // which this key prefixes every cryptographic tag. 77 int TotalTagSizeInBytes() const; 78 HasIdRequirement()79 bool HasIdRequirement() const override { 80 return variant_ != Variant::kNoPrefix; 81 } 82 83 bool operator==(const Parameters& other) const override; 84 85 private: AesCmacParameters(int key_size_in_bytes,int cryptographic_tag_size_in_bytes,Variant variant)86 AesCmacParameters(int key_size_in_bytes, int cryptographic_tag_size_in_bytes, 87 Variant variant) 88 : key_size_in_bytes_(key_size_in_bytes), 89 cryptographic_tag_size_in_bytes_(cryptographic_tag_size_in_bytes), 90 variant_(variant) {} 91 92 int key_size_in_bytes_; 93 int cryptographic_tag_size_in_bytes_; 94 Variant variant_; 95 }; 96 97 } // namespace tink 98 } // namespace crypto 99 100 #endif // TINK_MAC_AES_CMAC_PARAMETERS_H_ 101