|
||||
File indexing completed on 2025-01-18 09:55:08
0001 // seckey.h - originally written and placed in the public domain by Wei Dai 0002 0003 /// \file seckey.h 0004 /// \brief Classes and functions for implementing secret key algorithms. 0005 0006 #ifndef CRYPTOPP_SECKEY_H 0007 #define CRYPTOPP_SECKEY_H 0008 0009 #include "config.h" 0010 #include "cryptlib.h" 0011 #include "misc.h" 0012 #include "simple.h" 0013 #include "stdcpp.h" 0014 0015 #if CRYPTOPP_MSC_VERSION 0016 # pragma warning(push) 0017 # pragma warning(disable: 4189 4296) 0018 #endif 0019 0020 // Issue 340 0021 #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE 0022 # pragma GCC diagnostic push 0023 # pragma GCC diagnostic ignored "-Wconversion" 0024 # pragma GCC diagnostic ignored "-Wsign-conversion" 0025 #endif 0026 0027 NAMESPACE_BEGIN(CryptoPP) 0028 0029 /// \brief Inverts the cipher's direction 0030 /// \param dir the cipher's direction 0031 /// \return DECRYPTION if \ref CipherDir "dir" is ENCRYPTION, DECRYPTION otherwise 0032 inline CipherDir ReverseCipherDir(CipherDir dir) 0033 { 0034 return (dir == ENCRYPTION) ? DECRYPTION : ENCRYPTION; 0035 } 0036 0037 /// \brief Inherited by algorithms with fixed block size 0038 /// \tparam N the blocksize of the algorithm 0039 template <unsigned int N> 0040 class FixedBlockSize 0041 { 0042 public: 0043 /// \brief The block size of the algorithm provided as a constant. 0044 CRYPTOPP_CONSTANT(BLOCKSIZE = N); 0045 }; 0046 0047 // ************** rounds *************** 0048 0049 /// \brief Inherited by algorithms with fixed number of rounds 0050 /// \tparam R the number of rounds used by the algorithm 0051 template <unsigned int R> 0052 class FixedRounds 0053 { 0054 public: 0055 /// \brief The number of rounds for the algorithm provided as a constant. 0056 CRYPTOPP_CONSTANT(ROUNDS = R); 0057 }; 0058 0059 /// \brief Inherited by algorithms with variable number of rounds 0060 /// \tparam D Default number of rounds 0061 /// \tparam N Minimum number of rounds 0062 /// \tparam M Maximum number of rounds 0063 template <unsigned int D, unsigned int N=1, unsigned int M=INT_MAX> // use INT_MAX here because enums are treated as signed ints 0064 class VariableRounds 0065 { 0066 public: 0067 /// \brief The default number of rounds for the algorithm provided as a constant. 0068 CRYPTOPP_CONSTANT(DEFAULT_ROUNDS = D); 0069 /// \brief The minimum number of rounds for the algorithm provided as a constant. 0070 CRYPTOPP_CONSTANT(MIN_ROUNDS = N); 0071 /// \brief The maximum number of rounds for the algorithm provided as a constant. 0072 CRYPTOPP_CONSTANT(MAX_ROUNDS = M); 0073 /// \brief The default number of rounds for the algorithm based on key length 0074 /// provided by a static function. 0075 /// \param keylength the size of the key, in bytes 0076 /// \details keylength is unused in the default implementation. 0077 CRYPTOPP_STATIC_CONSTEXPR unsigned int StaticGetDefaultRounds(size_t keylength) 0078 { 0079 return CRYPTOPP_UNUSED(keylength), static_cast<unsigned int>(DEFAULT_ROUNDS); 0080 } 0081 0082 protected: 0083 /// \brief Validates the number of rounds for an algorithm. 0084 /// \param rounds the candidate number of rounds 0085 /// \param alg an Algorithm object used if the number of rounds are invalid 0086 /// \throw InvalidRounds if the number of rounds are invalid 0087 /// \details ThrowIfInvalidRounds() validates the number of rounds and throws if invalid. 0088 inline void ThrowIfInvalidRounds(int rounds, const Algorithm *alg) 0089 { 0090 if (M == INT_MAX) // Coverity and result_independent_of_operands 0091 { 0092 if (rounds < MIN_ROUNDS) 0093 throw InvalidRounds(alg ? alg->AlgorithmName() : std::string("VariableRounds"), rounds); 0094 } 0095 else 0096 { 0097 if (rounds < MIN_ROUNDS || rounds > MAX_ROUNDS) 0098 throw InvalidRounds(alg ? alg->AlgorithmName() : std::string("VariableRounds"), rounds); 0099 } 0100 } 0101 0102 /// \brief Validates the number of rounds for an algorithm 0103 /// \param param the candidate number of rounds 0104 /// \param alg an Algorithm object used if the number of rounds are invalid 0105 /// \return the number of rounds for the algorithm 0106 /// \throw InvalidRounds if the number of rounds are invalid 0107 /// \details GetRoundsAndThrowIfInvalid() validates the number of rounds and throws if invalid. 0108 inline unsigned int GetRoundsAndThrowIfInvalid(const NameValuePairs ¶m, const Algorithm *alg) 0109 { 0110 int rounds = param.GetIntValueWithDefault("Rounds", DEFAULT_ROUNDS); 0111 ThrowIfInvalidRounds(rounds, alg); 0112 return static_cast<unsigned int>(rounds); 0113 } 0114 }; 0115 0116 // ************** key length *************** 0117 0118 /// \brief Inherited by keyed algorithms with fixed key length 0119 /// \tparam N Default key length, in bytes 0120 /// \tparam IV_REQ the \ref SimpleKeyingInterface::IV_Requirement "IV requirements" 0121 /// \tparam IV_L default IV length, in bytes 0122 /// \sa SimpleKeyingInterface 0123 template <unsigned int N, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE, unsigned int IV_L = 0> 0124 class FixedKeyLength 0125 { 0126 public: 0127 /// \brief The default key length used by the algorithm provided as a constant 0128 /// \details KEYLENGTH is provided in bytes, not bits 0129 CRYPTOPP_CONSTANT(KEYLENGTH=N); 0130 /// \brief The minimum key length used by the algorithm provided as a constant 0131 /// \details MIN_KEYLENGTH is provided in bytes, not bits 0132 CRYPTOPP_CONSTANT(MIN_KEYLENGTH=N); 0133 /// \brief The maximum key length used by the algorithm provided as a constant 0134 /// \details MAX_KEYLENGTH is provided in bytes, not bits 0135 CRYPTOPP_CONSTANT(MAX_KEYLENGTH=N); 0136 /// \brief The default key length used by the algorithm provided as a constant 0137 /// \details DEFAULT_KEYLENGTH is provided in bytes, not bits 0138 CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=N); 0139 /// \brief The default IV requirements for the algorithm provided as a constant 0140 /// \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement 0141 /// in cryptlib.h for allowed values. 0142 CRYPTOPP_CONSTANT(IV_REQUIREMENT = IV_REQ); 0143 /// \brief The default IV length used by the algorithm provided as a constant 0144 /// \details IV_LENGTH is provided in bytes, not bits. The default implementation uses 0. 0145 CRYPTOPP_CONSTANT(IV_LENGTH = IV_L); 0146 /// \brief The default key length for the algorithm provided by a static function. 0147 /// \param keylength the size of the key, in bytes 0148 /// \details The default implementation returns KEYLENGTH. keylength is unused 0149 /// in the default implementation. 0150 CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength) 0151 { 0152 return CRYPTOPP_UNUSED(keylength), static_cast<size_t>(KEYLENGTH); 0153 } 0154 }; 0155 0156 /// \brief Inherited by keyed algorithms with variable key length 0157 /// \tparam D Default key length, in bytes 0158 /// \tparam N Minimum key length, in bytes 0159 /// \tparam M Maximum key length, in bytes 0160 /// \tparam Q Default key length multiple, in bytes. The default multiple is 1. 0161 /// \tparam IV_REQ the \ref SimpleKeyingInterface::IV_Requirement "IV requirements" 0162 /// \tparam IV_L default IV length, in bytes. The default length is 0. 0163 /// \sa SimpleKeyingInterface 0164 template <unsigned int D, unsigned int N, unsigned int M, unsigned int Q = 1, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE, unsigned int IV_L = 0> 0165 class VariableKeyLength 0166 { 0167 // Make these private to avoid Doxygen documenting them in all derived classes 0168 CRYPTOPP_COMPILE_ASSERT(Q > 0); 0169 CRYPTOPP_COMPILE_ASSERT(N % Q == 0); 0170 CRYPTOPP_COMPILE_ASSERT(M % Q == 0); 0171 CRYPTOPP_COMPILE_ASSERT(N < M); 0172 CRYPTOPP_COMPILE_ASSERT(D >= N); 0173 CRYPTOPP_COMPILE_ASSERT(M >= D); 0174 0175 public: 0176 /// \brief The minimum key length used by the algorithm provided as a constant 0177 /// \details MIN_KEYLENGTH is provided in bytes, not bits 0178 CRYPTOPP_CONSTANT(MIN_KEYLENGTH=N); 0179 /// \brief The maximum key length used by the algorithm provided as a constant 0180 /// \details MAX_KEYLENGTH is provided in bytes, not bits 0181 CRYPTOPP_CONSTANT(MAX_KEYLENGTH=M); 0182 /// \brief The default key length used by the algorithm provided as a constant 0183 /// \details DEFAULT_KEYLENGTH is provided in bytes, not bits 0184 CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=D); 0185 /// \brief The key length multiple used by the algorithm provided as a constant 0186 /// \details MAX_KEYLENGTH is provided in bytes, not bits 0187 CRYPTOPP_CONSTANT(KEYLENGTH_MULTIPLE=Q); 0188 /// \brief The default IV requirements for the algorithm provided as a constant 0189 /// \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement 0190 /// in cryptlib.h for allowed values. 0191 CRYPTOPP_CONSTANT(IV_REQUIREMENT=IV_REQ); 0192 /// \brief The default initialization vector length for the algorithm provided as a constant 0193 /// \details IV_LENGTH is provided in bytes, not bits. The default implementation uses 0. 0194 CRYPTOPP_CONSTANT(IV_LENGTH=IV_L); 0195 /// \brief Provides a valid key length for the algorithm provided by a static function. 0196 /// \param keylength the size of the key, in bytes 0197 /// \details If keylength is less than MIN_KEYLENGTH, then the function returns 0198 /// MIN_KEYLENGTH. If keylength is greater than MAX_KEYLENGTH, then the function 0199 /// returns MAX_KEYLENGTH. If keylength is a multiple of KEYLENGTH_MULTIPLE, 0200 /// then keylength is returned. Otherwise, the function returns keylength rounded 0201 /// \a down to the next smaller multiple of KEYLENGTH_MULTIPLE. 0202 /// \details keylength is provided in bytes, not bits. 0203 CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength) 0204 { 0205 return (keylength <= N) ? N : 0206 (keylength >= M) ? M : 0207 (keylength+Q-1) - (keylength+Q-1)%Q; 0208 } 0209 }; 0210 0211 /// \brief Provides key lengths based on another class's key length 0212 /// \tparam T another FixedKeyLength or VariableKeyLength class 0213 /// \tparam IV_REQ the \ref SimpleKeyingInterface::IV_Requirement "IV requirements" 0214 /// \tparam IV_L default IV length, in bytes 0215 /// \sa SimpleKeyingInterface 0216 template <class T, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE, unsigned int IV_L = 0> 0217 class SameKeyLengthAs 0218 { 0219 public: 0220 /// \brief The minimum key length used by the algorithm provided as a constant 0221 /// \details MIN_KEYLENGTH is provided in bytes, not bits 0222 CRYPTOPP_CONSTANT(MIN_KEYLENGTH=T::MIN_KEYLENGTH); 0223 /// \brief The maximum key length used by the algorithm provided as a constant 0224 /// \details MIN_KEYLENGTH is provided in bytes, not bits 0225 CRYPTOPP_CONSTANT(MAX_KEYLENGTH=T::MAX_KEYLENGTH); 0226 /// \brief The default key length used by the algorithm provided as a constant 0227 /// \details MIN_KEYLENGTH is provided in bytes, not bits 0228 CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=T::DEFAULT_KEYLENGTH); 0229 /// \brief The default IV requirements for the algorithm provided as a constant 0230 /// \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement 0231 /// in cryptlib.h for allowed values. 0232 CRYPTOPP_CONSTANT(IV_REQUIREMENT=IV_REQ); 0233 /// \brief The default initialization vector length for the algorithm provided as a constant 0234 /// \details IV_LENGTH is provided in bytes, not bits. The default implementation uses 0. 0235 CRYPTOPP_CONSTANT(IV_LENGTH=IV_L); 0236 /// \brief Provides a valid key length for the algorithm provided by a static function. 0237 /// \param keylength the size of the key, in bytes 0238 /// \details If keylength is less than MIN_KEYLENGTH, then the function returns 0239 /// MIN_KEYLENGTH. If keylength is greater than MAX_KEYLENGTH, then the function 0240 /// returns MAX_KEYLENGTH. If keylength is a multiple of KEYLENGTH_MULTIPLE, 0241 /// then keylength is returned. Otherwise, the function returns keylength rounded 0242 /// \a down to the next smaller multiple of KEYLENGTH_MULTIPLE. 0243 /// \details keylength is provided in bytes, not bits. 0244 CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength) 0245 {return T::StaticGetValidKeyLength(keylength);} 0246 }; 0247 0248 // ************** implementation helper for SimpleKeyingInterface *************** 0249 0250 /// \brief Provides a base implementation of SimpleKeyingInterface 0251 /// \tparam BASE a SimpleKeyingInterface derived class 0252 /// \tparam INFO a SimpleKeyingInterface derived class 0253 /// \details SimpleKeyingInterfaceImpl() provides a default implementation for ciphers providing a keying interface. 0254 /// Functions are virtual and not eligible for C++11 <tt>constexpr</tt>-ness. 0255 /// \sa Algorithm(), SimpleKeyingInterface() 0256 template <class BASE, class INFO = BASE> 0257 class CRYPTOPP_NO_VTABLE SimpleKeyingInterfaceImpl : public BASE 0258 { 0259 public: 0260 /// \brief The minimum key length used by the algorithm 0261 /// \return minimum key length used by the algorithm, in bytes 0262 size_t MinKeyLength() const 0263 {return INFO::MIN_KEYLENGTH;} 0264 0265 /// \brief The maximum key length used by the algorithm 0266 /// \return maximum key length used by the algorithm, in bytes 0267 size_t MaxKeyLength() const 0268 {return static_cast<size_t>(INFO::MAX_KEYLENGTH);} 0269 0270 /// \brief The default key length used by the algorithm 0271 /// \return default key length used by the algorithm, in bytes 0272 size_t DefaultKeyLength() const 0273 {return INFO::DEFAULT_KEYLENGTH;} 0274 0275 /// \brief Provides a valid key length for the algorithm 0276 /// \param keylength the size of the key, in bytes 0277 /// \return the valid key length, in bytes 0278 /// \details keylength is provided in bytes, not bits. If keylength is less than MIN_KEYLENGTH, 0279 /// then the function returns MIN_KEYLENGTH. If keylength is greater than MAX_KEYLENGTH, 0280 /// then the function returns MAX_KEYLENGTH. if If keylength is a multiple of KEYLENGTH_MULTIPLE, 0281 /// then keylength is returned. Otherwise, the function returns a \a lower multiple of 0282 /// KEYLENGTH_MULTIPLE. 0283 size_t GetValidKeyLength(size_t keylength) const {return INFO::StaticGetValidKeyLength(keylength);} 0284 0285 /// \brief The default IV requirements for the algorithm 0286 /// \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement 0287 /// in cryptlib.h for allowed values. 0288 SimpleKeyingInterface::IV_Requirement IVRequirement() const 0289 {return static_cast<SimpleKeyingInterface::IV_Requirement>(INFO::IV_REQUIREMENT);} 0290 0291 /// \brief The initialization vector length for the algorithm 0292 /// \details IVSize is provided in bytes, not bits. The default implementation uses 0293 /// IV_LENGTH, which is 0. 0294 unsigned int IVSize() const 0295 {return INFO::IV_LENGTH;} 0296 }; 0297 0298 /// \brief Provides a base implementation of Algorithm and SimpleKeyingInterface for block ciphers 0299 /// \tparam INFO a SimpleKeyingInterface derived class 0300 /// \tparam BASE a SimpleKeyingInterface derived class 0301 /// \details BlockCipherImpl() provides a default implementation for block ciphers using AlgorithmImpl() 0302 /// and SimpleKeyingInterfaceImpl(). Functions are virtual and not eligible for C++11 <tt>constexpr</tt>-ness. 0303 /// \sa Algorithm(), SimpleKeyingInterface(), AlgorithmImpl(), SimpleKeyingInterfaceImpl() 0304 template <class INFO, class BASE = BlockCipher> 0305 class CRYPTOPP_NO_VTABLE BlockCipherImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<TwoBases<BASE, INFO> > > 0306 { 0307 public: 0308 /// Provides the block size of the algorithm 0309 /// \return the block size of the algorithm, in bytes 0310 unsigned int BlockSize() const {return this->BLOCKSIZE;} 0311 }; 0312 0313 /// \brief Provides class member functions to key a block cipher 0314 /// \tparam DIR a CipherDir 0315 /// \tparam BASE a BlockCipherImpl derived class 0316 template <CipherDir DIR, class BASE> 0317 class BlockCipherFinal : public ClonableImpl<BlockCipherFinal<DIR, BASE>, BASE> 0318 { 0319 public: 0320 /// \brief Construct a default BlockCipherFinal 0321 /// \details The cipher is not keyed. 0322 BlockCipherFinal() {} 0323 0324 /// \brief Construct a BlockCipherFinal 0325 /// \param key a byte array used to key the cipher 0326 /// \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls 0327 /// SimpleKeyingInterface::SetKey. 0328 BlockCipherFinal(const byte *key) 0329 {this->SetKey(key, this->DEFAULT_KEYLENGTH);} 0330 0331 /// \brief Construct a BlockCipherFinal 0332 /// \param key a byte array used to key the cipher 0333 /// \param length the length of the byte array 0334 /// \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls 0335 /// SimpleKeyingInterface::SetKey. 0336 BlockCipherFinal(const byte *key, size_t length) 0337 {this->SetKey(key, length);} 0338 0339 /// \brief Construct a BlockCipherFinal 0340 /// \param key a byte array used to key the cipher 0341 /// \param length the length of the byte array 0342 /// \param rounds the number of rounds 0343 /// \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls 0344 /// SimpleKeyingInterface::SetKeyWithRounds. 0345 BlockCipherFinal(const byte *key, size_t length, unsigned int rounds) 0346 {this->SetKeyWithRounds(key, length, rounds);} 0347 0348 /// \brief Provides the direction of the cipher 0349 /// \return true if DIR is ENCRYPTION, false otherwise 0350 /// \sa GetCipherDirection(), IsPermutation() 0351 bool IsForwardTransformation() const {return DIR == ENCRYPTION;} 0352 }; 0353 0354 /// \brief Provides a base implementation of Algorithm and SimpleKeyingInterface for message authentication codes 0355 /// \tparam INFO a SimpleKeyingInterface derived class 0356 /// \tparam BASE a SimpleKeyingInterface derived class 0357 /// \details MessageAuthenticationCodeImpl() provides a default implementation for message authentication codes 0358 /// using AlgorithmImpl() and SimpleKeyingInterfaceImpl(). Functions are virtual and not subject to C++11 0359 /// <tt>constexpr</tt>. 0360 /// \sa Algorithm(), SimpleKeyingInterface(), AlgorithmImpl(), SimpleKeyingInterfaceImpl() 0361 template <class BASE, class INFO = BASE> 0362 class MessageAuthenticationCodeImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<BASE, INFO>, INFO> 0363 { 0364 }; 0365 0366 /// \brief Provides class member functions to key a message authentication code 0367 /// \tparam BASE a BlockCipherImpl derived class 0368 /// \details A default implementation for MessageAuthenticationCode 0369 template <class BASE> 0370 class MessageAuthenticationCodeFinal : public ClonableImpl<MessageAuthenticationCodeFinal<BASE>, MessageAuthenticationCodeImpl<BASE> > 0371 { 0372 public: 0373 /// \brief Construct a default MessageAuthenticationCodeFinal 0374 /// \details The message authentication code is not keyed. 0375 MessageAuthenticationCodeFinal() {} 0376 /// \brief Construct a BlockCipherFinal 0377 /// \param key a byte array used to key the algorithm 0378 /// \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls 0379 /// SimpleKeyingInterface::SetKey. 0380 MessageAuthenticationCodeFinal(const byte *key) 0381 {this->SetKey(key, this->DEFAULT_KEYLENGTH);} 0382 /// \brief Construct a BlockCipherFinal 0383 /// \param key a byte array used to key the algorithm 0384 /// \param length the length of the byte array 0385 /// \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls 0386 /// SimpleKeyingInterface::SetKey. 0387 MessageAuthenticationCodeFinal(const byte *key, size_t length) 0388 {this->SetKey(key, length);} 0389 }; 0390 0391 // ************** documentation *************** 0392 0393 /// \brief Provides Encryption and Decryption typedefs used by derived classes to 0394 /// implement a block cipher 0395 /// \details These objects usually should not be used directly. See CipherModeDocumentation 0396 /// instead. Each class derived from this one defines two types, Encryption and Decryption, 0397 /// both of which implement the BlockCipher interface. 0398 struct BlockCipherDocumentation 0399 { 0400 /// implements the BlockCipher interface 0401 typedef BlockCipher Encryption; 0402 /// implements the BlockCipher interface 0403 typedef BlockCipher Decryption; 0404 }; 0405 0406 /// \brief Provides Encryption and Decryption typedefs used by derived classes to 0407 /// implement a symmetric cipher 0408 /// \details Each class derived from this one defines two types, Encryption and Decryption, 0409 /// both of which implement the SymmetricCipher interface. Two types of classes derive 0410 /// from this class: stream ciphers and block cipher modes. Stream ciphers can be used 0411 /// alone, cipher mode classes need to be used with a block cipher. See CipherModeDocumentation 0412 /// for more for information about using cipher modes and block ciphers. 0413 struct SymmetricCipherDocumentation 0414 { 0415 /// implements the SymmetricCipher interface 0416 typedef SymmetricCipher Encryption; 0417 /// implements the SymmetricCipher interface 0418 typedef SymmetricCipher Decryption; 0419 }; 0420 0421 /// \brief Provides Encryption and Decryption typedefs used by derived classes to 0422 /// implement an authenticated encryption cipher 0423 /// \details Each class derived from this one defines two types, Encryption and Decryption, 0424 /// both of which implement the AuthenticatedSymmetricCipher interface. 0425 struct AuthenticatedSymmetricCipherDocumentation 0426 { 0427 /// implements the AuthenticatedSymmetricCipher interface 0428 typedef AuthenticatedSymmetricCipher Encryption; 0429 /// implements the AuthenticatedSymmetricCipher interface 0430 typedef AuthenticatedSymmetricCipher Decryption; 0431 }; 0432 0433 NAMESPACE_END 0434 0435 #if CRYPTOPP_MSC_VERSION 0436 # pragma warning(pop) 0437 #endif 0438 0439 // Issue 340 0440 #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE 0441 # pragma GCC diagnostic pop 0442 #endif 0443 0444 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |